home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Examples / MiscGISMapCoord / Controller.m < prev    next >
Encoding:
Text File  |  1995-07-08  |  10.1 KB  |  336 lines

  1. /*============================= Controller.m ================================*/
  2. /* Class controls a demo panel. The panel shows one geographic coordinate
  3.    in World Coordinates and various local UTM grid systems. It allows up to
  4.    10 such points to be selected and edited.
  5.  
  6. HISTORY
  7. 7-Feb-93  Dale Amon at GPL
  8.       Created
  9. */
  10.  
  11. #import "Controller.h"
  12. #import <misckit/miscgiskit.h>
  13.  
  14. #define MAXPOINTS    10
  15.  
  16. @implementation Controller
  17.  
  18. /*===========================================================================*/
  19. /* Internal methods */
  20. /*===========================================================================*/
  21.  
  22. - initTheInputMatrix: aTextMatrix
  23.   {    id    east, north;
  24.     east =  [aTextMatrix findCellWithTag: EASTING];
  25.     north = [aTextMatrix findCellWithTag: NORTHING];
  26.  
  27.     [east setEntryType:NX_DOUBLETYPE];
  28.     [east setFloatingPointFormat: NO
  29.                 left: METERS_DIGITS
  30.                    right: METER_FRACTION_DIGITS];
  31.  
  32.     [north setEntryType:NX_DOUBLETYPE];
  33.     [north setFloatingPointFormat: NO
  34.                  left: METERS_DIGITS
  35.                 right: METER_FRACTION_DIGITS];
  36.     return self;
  37.   }
  38.  
  39.  
  40. - outputWorldCoord: aWorldCoord inMatrix: aTextMatrix
  41.   {    double    deg1,min1,sec1;
  42.     double    deg2,min2,sec2;
  43.  
  44.     /* Load latitude as deg:min:sec. If value is negative, ie South,
  45.        display negative only on degrees field. */
  46.     [MiscCoord fromDegreesOnly: [aWorldCoord latitudeDegrees]
  47.                degrees: °1 minutes: &min1 seconds: &sec1];
  48.     if (sec1 < 0.0)    sec1 = -sec1;
  49.     if (min1 < 0.0)    min1 = -min1;
  50.     if (sec1 < .00001) sec1 = 0.0;
  51.  
  52.     [[aTextMatrix findCellWithTag:LATITUDE_DEGREES] setDoubleValue: deg1]; 
  53.     [[aTextMatrix findCellWithTag:LATITUDE_MINUTES] setDoubleValue: min1]; 
  54.     [[aTextMatrix findCellWithTag:LATITUDE_SECONDS] setDoubleValue: sec1]; 
  55.  
  56.     /* Load longitude as deg:min:sec If value is negative, ie East,
  57.        display negative only on degrees field. */
  58.     [MiscCoord fromDegreesOnly: [aWorldCoord longitudeDegrees]
  59.                degrees: °2 minutes: &min2 seconds: &sec2];
  60.     if (sec2 < 0.0)    sec2 = -sec2;
  61.     if (min2 < 0.0)    min2 = -min2;
  62.     if (sec2 < .00001) sec2 = 0.0;
  63.  
  64.     [[aTextMatrix findCellWithTag:LONGITUDE_DEGREES] setDoubleValue: deg2]; 
  65.     [[aTextMatrix findCellWithTag:LONGITUDE_MINUTES] setDoubleValue: min2]; 
  66.     [[aTextMatrix findCellWithTag:LONGITUDE_SECONDS] setDoubleValue: sec2]; 
  67.     return self;
  68.    }
  69.  
  70.  
  71. - inputWorldCoord: aWorldCoord inMatrix: aTextMatrix
  72.  {    double    deg,min,sec;
  73.     double latitude,longitude;
  74.  
  75.     /* Only allow a minus sign in the degree field. A minus there makes
  76.        this an South Latitude */
  77.     deg = [[aTextMatrix findCellWithTag:LATITUDE_DEGREES] doubleValue];
  78.     min = [[aTextMatrix findCellWithTag:LATITUDE_MINUTES] doubleValue];
  79.     sec = [[aTextMatrix findCellWithTag:LATITUDE_SECONDS] doubleValue];
  80.     if (sec <0.0)  sec = -sec;
  81.     if (min <0.0)  min = -min;
  82.     if (deg <0.0) {min = -min; sec = -sec;}
  83.  
  84.     latitude = [MiscCoord toDegreesOnlyDegrees: deg
  85.                        minutes: min
  86.                        seconds: sec];
  87.  
  88.     /* Only allow a minus sign in the degree field. A minus there makes
  89.        this a West Longitude */
  90.     deg = [[aTextMatrix findCellWithTag:LONGITUDE_DEGREES] doubleValue];
  91.     min = [[aTextMatrix findCellWithTag:LONGITUDE_MINUTES] doubleValue];
  92.     sec = [[aTextMatrix findCellWithTag:LONGITUDE_SECONDS] doubleValue];
  93.     if (sec <0.0)  sec = -sec;
  94.     if (min <0.0)  min = -min;
  95.     if (deg <0.0) {min = -min; sec = -sec;}
  96.  
  97.     longitude = [MiscCoord toDegreesOnlyDegrees: deg
  98.                         minutes: min
  99.                         seconds: sec];
  100.  
  101.     [aWorldCoord setCoordLatitudeDegrees: latitude
  102.                    longitudeDegrees: longitude
  103.                    altitude: 0.0];
  104.     return self;
  105.   }
  106.  
  107.  
  108. - outputGridCoord: aGridCoord inMatrix: aTextMatrix
  109.   {
  110.     [[aTextMatrix findCellWithTag:EASTING]
  111.         setDoubleValue: [aGridCoord easting]];
  112.     [[aTextMatrix findCellWithTag:NORTHING]
  113.         setDoubleValue: [aGridCoord northing]];
  114.  
  115.     return self;
  116.    }
  117.  
  118. - inputGridCoord: aUTMCoord inMatrix: aTextMatrix
  119.   {    double    easting, northing;
  120.  
  121.     easting =  [[aTextMatrix findCellWithTag:EASTING ] doubleValue];
  122.     northing = [[aTextMatrix findCellWithTag:NORTHING] doubleValue];
  123.  
  124.     [aUTMCoord setCoordEastingMeters: easting
  125.               northingMeters: northing
  126.              elevationMeters: 0.0];
  127.     return self;
  128.   }
  129.  
  130.  
  131. - recalcGridCoord: aCoord toMatrix: aMatrix
  132.   {
  133.     [worldCoord convert: aCoord];
  134.     [self outputGridCoord: aCoord inMatrix: aMatrix];
  135.     return self;
  136.   }
  137.  
  138. - selectGridPnt: (unsigned int) n coord: aCoord toMatrix: aMatrix
  139.   {
  140.     [aCoord selectExistingPoints: n blockSize:1];
  141.     [self outputGridCoord: aCoord inMatrix: aMatrix];
  142.     return self;
  143.   }
  144.  
  145.  
  146. /*===========================================================================*/
  147. /* When the Application starts, we are notified and carry out the required
  148.    initialization. 
  149. */
  150.  
  151. - appDidInit:sender
  152. {
  153.     autoLaunch    = NXGetDefaultValue([NXApp appName], "NXAutoLaunch");
  154.  
  155.     [self initTheInputMatrix: ukngInput];
  156.     [self initTheInputMatrix: ukz30Input];
  157.     [self initTheInputMatrix: ukz31Input];
  158.     [self initTheInputMatrix: igInput];
  159.     [self initTheInputMatrix: igOldInput];
  160.  
  161.     [index setEntryType: NX_POSINTTYPE];
  162.     [index setIntValue: 1];
  163.  
  164.     /* UK Grid origin */
  165.     ukngCoord = [[MiscUKUTMCoord alloc] initDescription: "A UK point"];
  166.     [ukngCoord selectAndSetMinPoints: 0 blockSize: MAXPOINTS];
  167.  
  168.     /* UK Zone 30 Grid origin */
  169.     ukz30Coord = [[MiscZoneUTMCoord alloc]
  170.             initDescription: "A UK Zone 30 point" zone: 30];
  171.     [ukz30Coord selectAndSetMinPoints: 0 blockSize: MAXPOINTS];
  172.  
  173.     /* UK Zone 31 Grid origin */
  174.     ukz31Coord = [[MiscZoneUTMCoord alloc]
  175.             initDescription: "A UK Zone 31 point" zone: 31];
  176.     [ukz31Coord selectAndSetMinPoints: 0 blockSize: MAXPOINTS];
  177.  
  178.     /* Irish Grid origin */
  179.     igCoord = [[MiscIrelandUTMCoord alloc]
  180.                  initDescription: "An Irish Grid point"];
  181.     [igCoord selectAndSetMinPoints: 0 blockSize: MAXPOINTS];
  182.  
  183.     /* Old Irish Grid */
  184.     igOldCoord = [[MiscIrelandOldUTMCoord alloc] initDescription:
  185.                             "An Old Irish Grid point"];
  186.     [igOldCoord selectAndSetMinPoints: 0 blockSize: MAXPOINTS];
  187.  
  188.     /* init test point to Greenwich */
  189.     worldCoord = [[MiscWorldCoord alloc] initDescription: "A World Coord Point"
  190.                                   constants: nil];
  191.     [worldCoord selectAndSetMinPoints: 0 blockSize: MAXPOINTS];
  192.  
  193.     /* Set the world coord and then make all the grid cells update
  194.        to match the initial value */
  195.     [worldCoord setCoordLatitudeDegrees: 49.0
  196.                longitudeDegrees: -2.0
  197.                    altitude: 0.0];
  198.  
  199.     /* Set all the points to the same block size so the
  200.        convert method will succeed. */
  201.     [self indexChanged: self];
  202.  
  203.     /* Then update them */
  204.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  205.     [self worldChanged: self];
  206.  
  207.     return self;
  208. }
  209.  
  210.  
  211. - indexChanged: sender
  212.   {    unsigned int n;
  213.  
  214.     n = (unsigned int) [index intValue] - 1;
  215.     if (![worldCoord selectExistingPoints: n blockSize:1])
  216.         {[index setIntValue: (int) [worldCoord curIndex] + 1];
  217.          return self;
  218.         }
  219.  
  220.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  221.  
  222.     [self selectGridPnt: n coord: ukngCoord  toMatrix: ukngInput];
  223.     [self selectGridPnt: n coord: ukz30Coord toMatrix: ukz30Input];
  224.     [self selectGridPnt: n coord: ukz31Coord toMatrix: ukz31Input];
  225.     [self selectGridPnt: n coord: igCoord    toMatrix: igInput];
  226.     [self selectGridPnt: n coord: igOldCoord toMatrix: igOldInput];
  227.     return self;
  228.   }
  229.  
  230. - worldChanged:sender
  231. {
  232.     /* read the new value */
  233.     [self inputWorldCoord: worldCoord inMatrix: worldInput];
  234.  
  235.     /* Make sure the input fields are always in a standard format */
  236.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  237.  
  238.     /* update all the grid displays to match the new world Coord */
  239.     [self recalcGridCoord: ukngCoord  toMatrix: ukngInput];
  240.     [self recalcGridCoord: ukz30Coord toMatrix: ukz30Input];
  241.     [self recalcGridCoord: ukz31Coord toMatrix: ukz31Input];
  242.     [self recalcGridCoord: igCoord    toMatrix: igInput];
  243.     [self recalcGridCoord: igOldCoord toMatrix: igOldInput];
  244.  
  245.     return self;
  246. }
  247.  
  248.  
  249. - ukngChanged:sender
  250. {
  251.     /* read the new value */
  252.     [self inputGridCoord: ukngCoord inMatrix: ukngInput];
  253.  
  254.     [ukngCoord convert: worldCoord];
  255.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  256.  
  257.     /* update all the grid displays to match the new world Coord */
  258.     [self recalcGridCoord: ukz30Coord toMatrix: ukz30Input];
  259.     [self recalcGridCoord: ukz31Coord toMatrix: ukz31Input];
  260.     [self recalcGridCoord: igCoord    toMatrix: igInput];
  261.     [self recalcGridCoord: igOldCoord toMatrix: igOldInput];
  262.  
  263.     return self;
  264.    }
  265.  
  266. - ukz30Changed:sender
  267. {
  268.     /* read the new value */
  269.     [self inputGridCoord: ukz30Coord inMatrix: ukz30Input];
  270.  
  271.     [ukz30Coord convert: worldCoord];
  272.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  273.  
  274.     /* update all the grid displays to match the new world Coord */
  275.     [self recalcGridCoord: ukngCoord  toMatrix: ukngInput];
  276.     [self recalcGridCoord: ukz31Coord toMatrix: ukz31Input];
  277.     [self recalcGridCoord: igCoord    toMatrix: igInput];
  278.     [self recalcGridCoord: igOldCoord toMatrix: igOldInput];
  279.  
  280.     return self;
  281.    }
  282.  
  283.  
  284. - ukz31Changed:sender
  285. {
  286.     /* read the new value */
  287.     [self inputGridCoord: ukz31Coord inMatrix: ukz31Input];
  288.  
  289.     [ukz31Coord  convert: worldCoord];
  290.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  291.  
  292.     /* update all the grid displays to match the new world Coord */
  293.     [self recalcGridCoord: ukngCoord  toMatrix: ukngInput];
  294.     [self recalcGridCoord: ukz30Coord toMatrix: ukz30Input];
  295.     [self recalcGridCoord: igCoord    toMatrix: igInput];
  296.     [self recalcGridCoord: igOldCoord toMatrix: igOldInput];
  297.  
  298.     return self;
  299.    }
  300.  
  301. - igChanged:sender
  302. {
  303.     /* read the new value */
  304.     [self inputGridCoord: igCoord inMatrix: igInput];
  305.  
  306.     [igCoord  convert: worldCoord];
  307.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  308.  
  309.     /* update all the grid displays to match the new world Coord */
  310.     [self recalcGridCoord: ukngCoord  toMatrix: ukngInput];
  311.     [self recalcGridCoord: ukz30Coord toMatrix: ukz30Input];
  312.     [self recalcGridCoord: ukz31Coord toMatrix: ukz31Input];
  313.     [self recalcGridCoord: igOldCoord toMatrix: igOldInput];
  314.  
  315.     return self;
  316.    }
  317.  
  318. - igOldChanged:sender
  319. {
  320.     /* read the new value */
  321.     [self inputGridCoord: igOldCoord inMatrix: igOldInput];
  322.  
  323.     [igOldCoord  convert: worldCoord];
  324.     [self outputWorldCoord: worldCoord inMatrix: worldInput];
  325.  
  326.     /* update all the grid displays to match the new world Coord */
  327.     [self recalcGridCoord: ukngCoord  toMatrix: ukngInput];
  328.     [self recalcGridCoord: ukz30Coord toMatrix: ukz30Input];
  329.     [self recalcGridCoord: ukz31Coord toMatrix: ukz31Input];
  330.     [self recalcGridCoord: igCoord    toMatrix: igInput];
  331.  
  332.     return self;
  333.    }
  334.  
  335. @end
  336.