USGS

Isis 3.0 Object Programmers' Reference

Home

RingPlaneProjection.cpp
Go to the documentation of this file.
1 
22 #include "RingPlaneProjection.h"
23 
24 #include <QObject>
25 
26 #include <cfloat>
27 #include <cmath>
28 #include <iomanip>
29 #include <sstream>
30 #include <vector>
31 
32 #include <SpiceUsr.h>
33 
34 #include "Constants.h"
35 #include "Displacement.h"
36 #include "FileName.h"
37 #include "IException.h"
38 #include "IString.h"
39 #include "Longitude.h"
40 #include "NaifStatus.h"
41 #include "Pvl.h"
42 #include "PvlGroup.h"
43 #include "PvlKeyword.h"
44 #include "SpecialPixel.h"
45 #include "WorldMapper.h"
46 
47 using namespace std;
48 namespace Isis {
84  RingPlaneProjection::RingPlaneProjection(Pvl &label) : Projection::Projection(label) {
85  try {
86  // Mapping group is read by the parent (Projection)
87  // Get the RingLongitude Direction
88  if ((QString) m_mappingGrp["RingLongitudeDirection"] == "Clockwise") {
90  }
91  else if ((QString) m_mappingGrp["RingLongitudeDirection"] == "CounterClockwise") {
93  }
94  else {
95  QString msg = "Projection failed. Invalid value for keyword "
96  "[RingLongitudeDirection] must be "
97  "[Clockwise or CounterClockwise]";
99  }
100 
101  // Get the RingLongitudeDomain
102  if ((QString) m_mappingGrp["RingLongitudeDomain"] == "360") {
103  m_ringLongitudeDomain = 360;
104  }
105  else if ((QString) m_mappingGrp["RingLongitudeDomain"] == "180") {
106  m_ringLongitudeDomain = 180;
107  }
108  else {
109  QString msg = "Projection failed. Invalid value for keyword "
110  "[RingLongitudeDomain] must be [180 or 360]";
112  }
113 
114  // Get the ground range if it exists
115  m_groundRangeGood = false;
116 
117  if ((m_mappingGrp.hasKeyword("MinimumRingLongitude")) &&
118  (m_mappingGrp.hasKeyword("MaximumRingLongitude")) &&
119  (m_mappingGrp.hasKeyword("MaximumRingRadius")) &&
120  (m_mappingGrp.hasKeyword("MinimumRingRadius"))) {
121  m_minimumRingLongitude = m_mappingGrp["MinimumRingLongitude"];
122  m_maximumRingLongitude = m_mappingGrp["MaximumRingLongitude"];
123  m_minimumRingRadius = m_mappingGrp["MinimumRingRadius"];
124  m_maximumRingRadius = m_mappingGrp["MaximumRingRadius"];
125 
126  if (m_minimumRingRadius < 0) {
127  IString msg = "Projection failed. "
128  "[MinimumRingRadius] of ["+ IString(m_minimumRingRadius) + "] is not "
129  + "valid";
131  }
132 
133  if (m_maximumRingRadius < 0) {
134  IString msg = "Projection failed. "
135  "[MaximumRingRadius] of ["+ IString(m_maximumRingRadius) + "] is not "
136  + "valid";
138  }
139 
141  IString msg = "Projection failed. "
142  "[MinimumRingRadius,MaximumRingRadius] of ["
144  + IString(m_maximumRingRadius) + "] are not "
145  + "properly ordered";
147  }
148 
150  IString msg = "Projection failed. "
151  "[MinimumRingLongitude,MaximumRingLongitude] of ["
153  + IString(m_maximumRingLongitude) + "] are not "
154  + "properly ordered";
156  }
157 
158  m_groundRangeGood = true;
159  }
160  else {
161  // if no ground range is given, initialize the min/max ring rad/lon to 0
162  m_minimumRingRadius = 0.0;
163  m_maximumRingRadius = 0.0;
166  }
167 
168  // Initialize miscellaneous protected data elements
169  // initialize the rest of the x,y,ring rad,ring lon
170  // member variables
171  m_ringRadius = Null;
173 
174  // If we made it to this point, we have what we need for a ring plane projection
176  }
177  catch(IException &e) {
178  IString msg = "Projection failed. Invalid label group [Mapping]";
179  throw IException(e, IException::Unknown, msg, _FILEINFO_);
180  }
181  }
182 
185  }
186 
197  if (!Projection::operator==(proj)) return false;
198  RingPlaneProjection *rproj = (RingPlaneProjection *) &proj;
199  if (IsClockwise() != rproj->IsClockwise()) return false;
200  if (Has180Domain() != rproj->Has180Domain()) return false;
201  return true;
202  }
203 
204 
215  return 0.0;
216  }
217 
218 
228  }
229 
239  }
240 
255  double RingPlaneProjection::ToClockwise(const double ringLongitude, const int domain) {
256  if (ringLongitude == Null) {
258  "Unable to convert to Clockwise. The given ring longitude value ["
259  + IString(ringLongitude) + "] is invalid.",
260  _FILEINFO_);
261  }
262  double myRingLongitude = ringLongitude;
263 
264  myRingLongitude *= -1;
265 
266  if (domain == 360) {
267  myRingLongitude = To360Domain(myRingLongitude);
268  }
269  else if (domain == 180) {
270  myRingLongitude = To180Domain(myRingLongitude);
271  }
272  else {
273  IString msg = "Unable to convert ring longitude. Domain [" + IString(domain)
274  + "] is not 180 or 360.";
276  }
277 
278  return myRingLongitude;
279  }
280 
295  double RingPlaneProjection::ToCounterClockwise(const double ringLongitude, const int domain) {
296  if (ringLongitude == Null) {
298  "Unable to convert to CounterClockwise. The given ring longitude value ["
299  + IString(ringLongitude) + "] is invalid.",
300  _FILEINFO_);
301  }
302  double myRingLongitude = ringLongitude;
303 
304  myRingLongitude *= -1;
305 
306  if (domain == 360) {
307  myRingLongitude = To360Domain(myRingLongitude);
308  }
309  else if (domain == 180) {
310  myRingLongitude = To180Domain(myRingLongitude);
311  }
312  else {
313  IString msg = "Unable to convert ring longitude. Domain [" + IString(domain)
314  + "] is not 180 or 360.";
316  }
317 
318  return myRingLongitude;
319  }
320 
321 
330  if (m_ringLongitudeDirection == Clockwise) return "Clockwise";
331  return "CounterClockwise";
332  }
333 
342  return m_ringLongitudeDomain == 180;
343  }
344 
353  return m_ringLongitudeDomain == 360;
354  }
355 
367  double RingPlaneProjection::To180Domain(const double ringLongitude) {
368  if (ringLongitude == Null) {
370  "Unable to convert to 180 degree domain. The given ring longitude value ["
371  + IString(ringLongitude) + "] is invalid.",
372  _FILEINFO_);
373  }
374  return Isis::Longitude(ringLongitude, Angle::Degrees).force180Domain().degrees();
375  }
376 
385  double RingPlaneProjection::To360Domain(const double ringLongitude) {
386  if (ringLongitude == Null) {
388  "Unable to convert to 360 degree domain. The given ring longitude value ["
389  + IString(ringLongitude) + "] is invalid.",
390  _FILEINFO_);
391  }
392  double result = ringLongitude;
393 
394  if ( (ringLongitude < 0.0 || ringLongitude > 360.0) &&
395  !qFuzzyCompare(ringLongitude, 0.0) && !qFuzzyCompare(ringLongitude, 360.0)) {
396  result = Isis::Longitude(ringLongitude, Angle::Degrees).force360Domain().degrees();
397  }
398 
399  return result;
400  }
401 
409  if (m_ringLongitudeDomain == 360) return "360";
410  return "180";
411  }
412 
421  return m_minimumRingRadius;
422  }
423 
432  return m_maximumRingRadius;
433  }
434 
443  return m_minimumRingLongitude;
444  }
445 
454  return m_maximumRingLongitude;
455  }
456 
471  bool RingPlaneProjection::SetGround(const double ringRadius, const double ringLongitude) {
472  if (ringRadius == Null || ringLongitude == Null) {
473  m_good = false;
474  return m_good;
475  }
476  else {
477  m_ringRadius = ringRadius;
478  m_ringLongitude = ringLongitude;
479  m_good = true;
480  SetComputedXY(ringLongitude, ringRadius);
481  }
482  return m_good;
483  }
484 
500  bool RingPlaneProjection::SetCoordinate(const double x, const double y) {
501  if (x == Null || y == Null) {
502  m_good = false;
503  }
504  else {
505  m_good = true;
506  SetXY(x, y);
507  m_ringRadius = XCoord();
509  }
510  return m_good;
511  }
512 
513 
522  return m_ringRadius;
523  }
524 
525 
534  return m_ringRadius;
535  }
536 
546  return m_ringLongitude;
547  }
548 
561  bool RingPlaneProjection::SetUniversalGround(const double ringRadius, const double ringLongitude) {
562  if (ringRadius == Null || ringLongitude == Null) {
563  m_good = false;
564  return m_good;
565  }
566  // Deal with the ring longitude first
567  m_ringLongitude = ringLongitude;
568  if (m_ringLongitudeDirection == Clockwise) m_ringLongitude = -ringLongitude;
569  if (m_ringLongitudeDomain == 180) {
571  }
572  else {
573  // Do this because RingLongitudeDirection could cause (-360,0)
575  }
576 
577  // Nothing to do with radius
578 
579  m_ringRadius = ringRadius;
580 
581  // Now the rad/ring longitude are in user defined coordinates so set them
583  }
584 
591  double ringRadius = m_ringRadius;
592  return ringRadius;
593  }
594 
595 
605  double ringLongitude = m_ringLongitude;
606  if (m_ringLongitudeDirection == Clockwise) ringLongitude = -ringLongitude;
607  ringLongitude = To360Domain(ringLongitude);
608  return ringLongitude;
609  }
610 
611 
622  double RingPlaneProjection::Scale() const {
623  if (m_mapper != NULL) {
624  double localRadius = TrueScaleRingRadius();
625  return localRadius / m_mapper->Resolution() * DEG2RAD;
626  // return localRadius / m_mapper->Resolution();
627  }
628  else {
629  return 1.0;
630  }
631  }
632 
633 
671  bool RingPlaneProjection::XYRange(double &minX, double &maxX,
672  double &minY, double &maxY) {
673  if (minX == Null || maxX == Null || minY == Null || maxY == Null) {
674  return false;
675  }
676  if (m_groundRangeGood) {
677  minX = m_minimumRingLongitude;
678  maxX = m_maximumRingLongitude;
679  minY = m_minimumRingRadius;
680  maxY = m_maximumRingRadius;
681  return true;
682  }
683  return false;
684  }
685 
724  void RingPlaneProjection::XYRangeCheck(const double ringRadius, const double ringLongitude) {
725  if (ringRadius == Null || ringLongitude == Null) {
726  m_good = false;
727  return;
728  }
729  SetGround(ringRadius, ringLongitude);
730  if (!IsGood()) return;
731 
732  if (XCoord() < m_minimumX) m_minimumX = XCoord();
733  if (XCoord() > m_maximumX) m_maximumX = XCoord();
734  if (YCoord() < m_minimumY) m_minimumY = YCoord();
735  if (YCoord() > m_maximumY) m_maximumY = YCoord();
736  return;
737  }
738 
760  // bool Projection::xyRangeOblique(double &minX, double &maxX,
761  // double &minY, double &maxY) {
762  // if (minX == Null || maxX == Null || minY == Null || maxY == Null) {
763  // return false;
764  // }
765  // //For oblique, we'll have to walk all 4 sides to find out min/max x/y values
766  // if (!HasGroundRange()) return false; // Don't have min/max ring rad/lon,
767  // //can't continue
768 
769  // m_specialLatCases.clear();
770  // m_specialLonCases.clear();
771 
772  // // First, search ring longitude for
773  // min X/Y double minFoundX1, minFoundX2;
774  // double minFoundY1, minFoundY2;
775 
776  // // Search for minX between minlat and maxlat along minlon
777  // doSearch(MinimumLatitude(), MaximumLatitude(),
778  // minFoundX1, MinimumLongitude(), true, true, true);
779  // // Search for minX between minlat and maxlat along maxlon
780  // doSearch(MinimumLatitude(), MaximumLatitude(),
781  // minFoundX2, MaximumLongitude(), true, true, true);
782  // // Search for minY between minlat and maxlat along minlon
783  // doSearch(MinimumLatitude(), MaximumLatitude(),
784  // minFoundY1, MinimumLongitude(), false, true, true);
785  // // Search for minY between minlat and maxlat along maxlon
786  // doSearch(MinimumLatitude(), MaximumLatitude(),
787  // minFoundY2, MaximumLongitude(), false, true, true);
788 
789  // // Second, search latitude for min X/Y
790  // double minFoundX3, minFoundX4;
791  // double minFoundY3, minFoundY4;
792 
793  // // Search for minX between minlon and maxlon along minlat
794  // doSearch(MinimumLongitude(), MaximumLongitude(),
795  // minFoundX3, MinimumLatitude(), true, false, true);
796  // // Search for minX between minlon and maxlon along maxlat
797  // doSearch(MinimumLongitude(), MaximumLongitude(),
798  // minFoundX4, MaximumLatitude(), true, false, true);
799  // // Search for minY between minlon and maxlon along minlat
800  // doSearch(MinimumLongitude(), MaximumLongitude(),
801  // minFoundY3, MinimumLatitude(), false, false, true);
802  // // Search for minY between minlon and maxlon along maxlat
803  // doSearch(MinimumLongitude(), MaximumLongitude(),
804  // minFoundY4, MaximumLatitude(), false, false, true);
805 
806  // // We've searched all possible minimums, go ahead and store the lowest
807  // double minFoundX5 = min(minFoundX1, minFoundX2);
808  // double minFoundX6 = min(minFoundX3, minFoundX4);
809  // m_minimumX = min(minFoundX5, minFoundX6);
810 
811  // double minFoundY5 = min(minFoundY1, minFoundY2);
812  // double minFoundY6 = min(minFoundY3, minFoundY4);
813  // m_minimumY = min(minFoundY5, minFoundY6);
814 
815  // // Search ring longitude for
816  // max X/Y double maxFoundX1,
817  // maxFoundX2; double maxFoundY1,
818  // maxFoundY2;
819 
820  // // Search for maxX between minlat and maxlat along minlon
821  // doSearch(MinimumLatitude(), MaximumLatitude(),
822  // maxFoundX1, MinimumLongitude(), true, true, false);
823  // // Search for maxX between minlat and maxlat along maxlon
824  // doSearch(MinimumLatitude(), MaximumLatitude(),
825  // maxFoundX2, MaximumLongitude(), true, true, false);
826  // // Search for maxY between minlat and maxlat along minlon
827  // doSearch(MinimumLatitude(), MaximumLatitude(),
828  // maxFoundY1, MinimumLongitude(), false, true, false);
829  // // Search for maxY between minlat and maxlat along maxlon
830  // doSearch(MinimumLatitude(), MaximumLatitude(),
831  // maxFoundY2, MaximumLongitude(), false, true, false);
832 
833  // // Search latitude for max X/Y
834  // double maxFoundX3, maxFoundX4;
835  // double maxFoundY3, maxFoundY4;
836 
837  // // Search for maxX between minlon and maxlon along minlat
838  // doSearch(MinimumLongitude(), MaximumLongitude(),
839  // maxFoundX3, MinimumLatitude(), true, false, false);
840  // // Search for maxX between minlon and maxlon along maxlat
841  // doSearch(MinimumLongitude(), MaximumLongitude(),
842  // maxFoundX4, MaximumLatitude(), true, false, false);
843  // // Search for maxY between minlon and maxlon along minlat
844  // doSearch(MinimumLongitude(), MaximumLongitude(),
845  // maxFoundY3, MinimumLatitude(), false, false, false);
846  // // Search for maxY between minlon and maxlon along maxlat
847  // doSearch(MinimumLongitude(), MaximumLongitude(),
848  // maxFoundY4, MaximumLatitude(), false, false, false);
849 
850  // // We've searched all possible maximums, go ahead and store the highest
851  // double maxFoundX5 = max(maxFoundX1, maxFoundX2);
852  // double maxFoundX6 = max(maxFoundX3, maxFoundX4);
853  // m_maximumX = max(maxFoundX5, maxFoundX6);
854 
855  // double maxFoundY5 = max(maxFoundY1, maxFoundY2);
856  // double maxFoundY6 = max(maxFoundY3, maxFoundY4);
857  // m_maximumY = max(maxFoundY5, maxFoundY6);
858 
859  // // Look along discontinuities for more extremes
860  // vector<double> specialLatCases = m_specialLatCases;
861  // for (unsigned int specialLatCase = 0;
862  // specialLatCase < specialLatCases.size();
863  // specialLatCase ++) {
864  // double minX, maxX, minY, maxY;
865 
866  // // Search for minX between minlon and maxlon along latitude discontinuities
867  // doSearch(MinimumLongitude(), MaximumLongitude(),
868  // minX, specialLatCases[specialLatCase], true, false, true);
869  // // Search for minY between minlon and maxlon along latitude discontinuities
870  // doSearch(MinimumLongitude(), MaximumLongitude(),
871  // minY, specialLatCases[specialLatCase], false, false, true);
872  // // Search for maxX between minlon and maxlon along latitude discontinuities
873  // doSearch(MinimumLongitude(), MaximumLongitude(),
874  // maxX, specialLatCases[specialLatCase], true, false, false);
875  // // Search for maxX between minlon and maxlon along latitude discontinuities
876  // doSearch(MinimumLongitude(), MaximumLongitude(),
877  // maxY, specialLatCases[specialLatCase], false, false, false);
878 
879  // m_minimumX = min(minX, m_minimumX);
880  // m_maximumX = max(maxX, m_maximumX);
881  // m_minimumY = min(minY, m_minimumY);
882  // m_maximumY = max(maxY, m_maximumY);
883  // }
884 
885  // vector<double> specialLonCases = m_specialLonCases;
886  // for (unsigned int specialLonCase = 0;
887  // specialLonCase < specialLonCases.size();
888  // specialLonCase ++) {
889  // double minX, maxX, minY, maxY;
890 
891  // // Search for minX between minlat and maxlat along longitude discontinuities
892  // doSearch(MinimumLatitude(), MaximumLatitude(),
893  // minX, specialLonCases[specialLonCase], true, true, true);
894  // // Search for minY between minlat and maxlat along longitude discontinuities
895  // doSearch(MinimumLatitude(), MaximumLatitude(),
896  // minY, specialLonCases[specialLonCase], false, true, true);
897  // // Search for maxX between minlat and maxlat along longitude discontinuities
898  // doSearch(MinimumLatitude(), MaximumLatitude(),
899  // maxX, specialLonCases[specialLonCase], true, true, false);
900  // // Search for maxY between minlat and maxlat along longitude discontinuities
901  // doSearch(MinimumLatitude(), MaximumLatitude(),
902  // maxY, specialLonCases[specialLonCase], false, true, false);
903 
904  // m_minimumX = min(minX, m_minimumX);
905  // m_maximumX = max(maxX, m_maximumX);
906  // m_minimumY = min(minY, m_minimumY);
907  // m_maximumY = max(maxY, m_maximumY);
908  // }
909 
910  // m_specialLatCases.clear();
911  // m_specialLonCases.clear();
912 
913  // // Make sure everything is ordered
914  // if (m_minimumX >= m_maximumX) return false;
915  // if (m_minimumY >= m_maximumY) return false;
916 
917  // // Return X/Y min/maxs
918  // minX = m_minimumX;
919  // maxX = m_maximumX;
920  // minY = m_minimumY;
921  // maxY = m_maximumY;
922 
923  // return true;
924  // }
925 
963  // void Projection::doSearch(double minBorder, double maxBorder,
964  // double &extremeVal, const double constBorder,
965  // bool searchX, bool searchRingLongitude, bool findMin) {
966  // if (minBorder == Null || maxBorder == Null || constBorder == Null) {
967  // return;
968  // }
969  // const double TOLERANCE = m_pixelResolution/2;
970  // const int NUM_ATTEMPTS = (unsigned int)DBL_DIG; // It's unsafe to go past
971  // // this precision
972 
973  // double minBorderX, minBorderY, maxBorderX, maxBorderY;
974  // int attempts = 0;
975 
976  // do {
977  // findExtreme(minBorder, maxBorder, minBorderX, minBorderY, maxBorderX,
978  // maxBorderY, constBorder, searchX, searchLongitude, findMin);
979  // if (minBorderX == Null && maxBorderX == Null
980  // && minBorderY == Null && maxBorderY == Null ) {
981  // attempts = NUM_ATTEMPTS;
982  // continue;
983  // }
984  // attempts ++;
985  // }
986  // while ((fabs(minBorderX - maxBorderX) > TOLERANCE
987  // || fabs(minBorderY - maxBorderY) > TOLERANCE)
988  // && (attempts < NUM_ATTEMPTS));
989  // // check both x and y distance in case symmetry of map
990  // // For example, if minBorderX = maxBorderX but minBorderY = -maxBorderY,
991  // // these points may not be close enough.
992 
993  // if (attempts >= NUM_ATTEMPTS) {
994  // // We zoomed in on a discontinuity because our range never shrank, this
995  // // will need to be rechecked later.
996  // // *min and max border should be nearly identical, so it doesn't matter
997  // // which is used here
998  // if (searchLongitude) {
999  // m_specialLatCases.push_back(minBorder);
1000  // }
1001  // else {
1002  // m_specialLonCases.push_back(minBorder);
1003  // }
1004  // }
1005 
1006  // // These values will always be accurate, even over a discontinuity
1007  // if (findMin) {
1008  // if (searchX) extremeVal = min(minBorderX, maxBorderX);
1009  // else extremeVal = min(minBorderY, maxBorderY);
1010  // }
1011  // else {
1012  // if (searchX) extremeVal = max(minBorderX, maxBorderX);
1013  // else extremeVal = max(minBorderY, maxBorderY);
1014  // }
1015  // return;
1016  // }
1017 
1077  // void Projection::findExtreme(double &minBorder, double &maxBorder,
1078  // double &minBorderX, double &minBorderY,
1079  // double &maxBorderX, double &maxBorderY,
1080  // const double constBorder, bool searchX,
1081  // bool searchRingLongitude, bool findMin) {
1082  // if (minBorder == Null || maxBorder == Null || constBorder == Null) {
1083  // minBorderX = Null;
1084  // minBorderY = minBorderX;
1085  // minBorderX = minBorderX;
1086  // minBorderY = minBorderX;
1087  // return;
1088  // }
1089  // if (!searchRingLongitude && (fabs(fabs(constBorder) - 90.0) < DBL_EPSILON)) {
1090  // // it is impossible to search "along" a pole
1091  // setSearchGround(minBorder, constBorder, searchRingLongitude);
1092  // minBorderX = XCoord();
1093  // minBorderY = YCoord();
1094  // maxBorderX = minBorderX;
1095  // maxBorderY = minBorderY;
1096  // return;
1097  // }
1098  // // Always do 10 steps
1099  // const double STEP_SIZE = (maxBorder - minBorder) / 10.0;
1100  // const double LOOP_END = maxBorder + (STEP_SIZE / 2.0); // This ensures we do
1101  // // all of the steps
1102  // // properly
1103  // double currBorderVal = minBorder;
1104  // setSearchGround(minBorder, constBorder, searchRingLongitude);
1105 
1106  // // this makes sure that the initial currBorderVal is valid before entering
1107  // // the loop below
1108  // if (!m_good){
1109  // // minBorder = currBorderVal+STEP_SIZE < LOOP_END until setGround is good?
1110  // // then, if still not good return?
1111  // while (!m_good && currBorderVal <= LOOP_END) {
1112  // currBorderVal+=STEP_SIZE;
1113  // if (searchRingLongitude && (currBorderVal - 90.0 > DBL_EPSILON)) {
1114  // currBorderVal = 90.0;
1115  // }
1116  // setSearchGround(currBorderVal, constBorder, searchRingLongitude);
1117  // }
1118  // if (!m_good) {
1119  // minBorderX = Null;
1120  // minBorderY = minBorderX;
1121  // minBorderX = minBorderX;
1122  // minBorderY = minBorderX;
1123  // return;
1124  // }
1125  // }
1126 
1127  // // save the values of three consecutive steps from the minBorder towards
1128  // // the maxBorder along the constBorder. initialize these three border
1129  // // values (the non-constant lat or lon)
1130  // double border1 = currBorderVal;
1131  // double border2 = currBorderVal;
1132  // double border3 = currBorderVal;
1133 
1134  // // save the coordinate (x or y) values that correspond to the first
1135  // // two borders that are being saved.
1136  // // initialize these two coordinate values (x or y)
1137  // double value1 = (searchX) ? XCoord() : YCoord();
1138  // double value2 = value1;
1139 
1140  // // initialize the extreme coordinate value
1141  // // -- this is the largest coordinate value found so far
1142  // double extremeVal2 = value2;
1143 
1144  // // initialize the extreme border values
1145  // // -- these are the borders on either side of the extreme coordinate value
1146  // double extremeBorder1 = minBorder;
1147  // double extremeBorder3 = minBorder;
1148 
1149  // while (currBorderVal <= LOOP_END) {
1150 
1151  // // this conditional was added to prevent trying to SetGround with an
1152  // // invalid latitude greater than 90 degrees. There is no need check for
1153  // // latitude less than -90 since we start at the minBorder (already
1154  // // assumed to be valid) and step forward toward (and possibly past)
1155  // // maxBorder
1156  // if (searchRingLongitude && (currBorderVal - 90.0 > DBL_EPSILON)) {
1157  // currBorderVal = 90.0;
1158  // }
1159 
1160  // // update the current border value along constBorder
1161  // currBorderVal += STEP_SIZE;
1162  // setSearchGround(currBorderVal, constBorder, searchRingLongitude);
1163  // if (!m_good){
1164  // continue;
1165  // }
1166 
1167  // // update the border and coordinate values
1168  // border3 = border2;
1169  // border2 = border1;
1170  // border1 = currBorderVal;
1171  // value2 = value1;
1172  // value1 = (searchX) ? XCoord() : YCoord();
1173 
1174  // if ((findMin && value2 < extremeVal2)
1175  // || (!findMin && value2 > extremeVal2)) {
1176  // // Compare the coordinate value associated with the center border with
1177  // // the current extreme. If the updated coordinate value is more extreme
1178  // // (smaller or larger, depending on findMin), then we update the
1179  // // extremeVal and it's borders.
1180  // extremeVal2 = value2;
1181 
1182  // extremeBorder3 = border3;
1183  // extremeBorder1 = border1;
1184  // }
1185  // }
1186 
1187  // // update min/max border values to the values on either side of the most
1188  // // extreme coordinate found in this call to this method
1189 
1190  // minBorder = extremeBorder3; // Border 3 is lagging and thus smaller
1191 
1192  // // since the loop steps past the original maxBorder, we want to retain
1193  // // the original maxBorder value so we don't go outside of the original
1194  // // min/max range given
1195  // if (extremeBorder1 <= maxBorder ) {
1196  // maxBorder = extremeBorder1; // Border 1 is leading and thus larger
1197  // }
1198 
1199  // // update minBorder coordinate values
1200  // setSearchGround(minBorder, constBorder, searchRingLongitude);
1201  // // if (!m_good){
1202  // // this should not happen since minBorder has already been verified in
1203  // // the while loop above
1204  // // }
1205 
1206  // minBorderX = XCoord();
1207  // minBorderY = YCoord();
1208 
1209  // // update maxBorder coordinate values
1210  // setSearchGround(maxBorder, constBorder, searchRingLongitude);
1211  // // if (!m_good){
1212  // // this should not happen since maxBorder has already been verified in
1213  // // the while loop above
1214  // // }
1215 
1216  // maxBorderX = XCoord();
1217  // maxBorderY = YCoord();
1218  // return;
1219  // }
1220 
1243  // void Projection::setSearchGround(const double variableBorder,
1244  // const double constBorder,
1245  // bool variableIsLat) {
1246  // if (variableBorder == Null || constBorder == Null) {
1247  // return;
1248  // }
1249  // double lat, lon;
1250  // if (variableIsLat) {
1251  // lat = variableBorder;
1252  // lon = constBorder;
1253  // }
1254  // else {
1255  // lat = constBorder;
1256  // lon = variableBorder;
1257  // }
1258  // SetGround(lat, lon);
1259  // return;
1260  // }
1261 
1262 
1269  PvlGroup mapping("Mapping");
1270 
1271  if (m_mappingGrp.hasKeyword("TargetName")) {
1272  mapping += m_mappingGrp["TargetName"];
1273  }
1274 
1275  mapping += m_mappingGrp["ProjectionName"];
1276  mapping += m_mappingGrp["RingLongitudeDirection"];
1277  mapping += m_mappingGrp["RingLongitudeDomain"];
1278 
1279  if (m_mappingGrp.hasKeyword("PixelResolution")) {
1280  mapping += m_mappingGrp["PixelResolution"];
1281  }
1282  if (m_mappingGrp.hasKeyword("Scale")) {
1283  mapping += m_mappingGrp["Scale"];
1284  }
1285  if (m_mappingGrp.hasKeyword("UpperLeftCornerX")) {
1286  mapping += m_mappingGrp["UpperLeftCornerX"];
1287  }
1288  if (m_mappingGrp.hasKeyword("UpperLeftCornerY")) {
1289  mapping += m_mappingGrp["UpperLeftCornerY"];
1290  }
1291 
1292  if (HasGroundRange()) {
1293  mapping += m_mappingGrp["MinimumRingRadius"];
1294  mapping += m_mappingGrp["MaximumRingRadius"];
1295  mapping += m_mappingGrp["MinimumRingLongitude"];
1296  mapping += m_mappingGrp["MaximumRingLongitude"];
1297  }
1298 
1299  if (m_mappingGrp.hasKeyword("Rotation")) {
1300  mapping += m_mappingGrp["Rotation"];
1301  }
1302 
1303  return mapping;
1304  }
1305 
1312  PvlGroup mapping("Mapping");
1313 
1314  if (HasGroundRange()) {
1315  mapping += m_mappingGrp["MinimumRingRadius"];
1316  mapping += m_mappingGrp["MaximumRingRadius"];
1317  }
1318 
1319  return mapping;
1320  }
1321 
1322 
1329  PvlGroup mapping("Mapping");
1330 
1331  if (HasGroundRange()) {
1332  mapping += m_mappingGrp["MinimumRingLongitude"];
1333  mapping += m_mappingGrp["MaximumRingLongitude"];
1334  }
1335 
1336  return mapping;
1337  }
1338 
1339 
1340 } //end namespace isis
1341 
1342