Isis 3 Programmer Reference
Planar.cpp
Go to the documentation of this file.
1 
23 #include "Planar.h"
24 
25 #include <cmath>
26 #include <cfloat>
27 
28 #include "Constants.h"
29 #include "IException.h"
30 #include "Pvl.h"
31 #include "PvlGroup.h"
32 #include "PvlKeyword.h"
33 #include "RingPlaneProjection.h"
34 
35 using namespace std;
36 namespace Isis {
55  Planar::Planar(Pvl &label, bool allowDefaults) :
57 
58  // latitude in ring plane is always zero
59  m_ringRadius = 0.0;
60 
61  try {
62  // Try to read the mapping group
63  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
64 
65  // Compute and write the default center longitude if allowed and
66  // necessary
67  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingLongitude"))) {
68  double azimuth = (m_minimumRingLongitude + m_maximumRingLongitude) / 2.0;
69  mapGroup += PvlKeyword("CenterRingLongitude", toString(azimuth));
70  }
71 
72  // Compute and write the default center radius if allowed and
73  // necessary
74  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingRadius"))) {
75  double radius = (m_minimumRingRadius + m_maximumRingRadius) / 2.0;
76  mapGroup += PvlKeyword("CenterRingRadius", toString(radius));
77  }
78 
79  // Get the center longitude & radius
80  m_centerRingLongitude = mapGroup["CenterRingLongitude"];
81  m_centerRingRadius = mapGroup["CenterRingRadius"];
82 
83  // convert to radians, adjust for azimuth direction
86  }
87  catch(IException &e) {
88  string message = "Invalid label group [Mapping]";
89  throw IException(e, IException::Io, message, _FILEINFO_);
90  }
91  }
92 
95  }
96 
105  bool Planar::operator== (const Projection &proj) {
106  if (!RingPlaneProjection::operator==(proj)) return false;
107  // dont do the below it is a recursive plunge
108  // if (Projection::operator!=(proj)) return false;
109  Planar *planar = (Planar *) &proj;
110  if ((planar->m_centerRingLongitude != m_centerRingLongitude) ||
111  (planar->m_centerRingRadius != m_centerRingRadius)) return false;
112  return true;
113  }
114 
120  QString Planar::Name() const {
121  return "Planar";
122  }
123 
138  return m_centerRingRadius;
139  // return 60268000.0;
140  }
141 
142 
149  double dir = 1.0;
150  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
151  return m_centerRingLongitude * RAD2DEG * dir;;
152  }
153 
154 
160  double Planar::CenterRingRadius() const {
161  return m_centerRingRadius;
162  }
163 
164 
171  QString Planar::Version() const {
172  return "1.0";
173  }
174 
175 
188  bool Planar::SetGround(const double ringRadius, const double ringLongitude) {
189 
190  // Convert azimuth to radians & adjust
191  m_ringLongitude = ringLongitude;
192  double azRadians = ringLongitude * DEG2RAD;
193  if (m_ringLongitudeDirection == Clockwise) azRadians *= -1.0;
194 
195  // Check to make sure radius is valid
196  if (ringRadius < 0) {
197  m_good = false;
198  // cout << "Unable to set radius. The given radius value ["
199  // << IString(ringRadius) << "] is invalid." << endl;
200  // throw IException(IException::Unknown,
201  // "Unable to set radius. The given radius value ["
202  // + IString(ringRadius) + "] is invalid.",
203  // _FILEINFO_);
204  return m_good;
205  }
206  m_ringRadius = ringRadius;
207 
208 
209  // Compute helper variables
210  double deltaAz = (azRadians - m_centerRingLongitude);
211 // double coslon = cos(deltaLon);
212 
213  // Lat/Lon cannot be projected
214 // double g = m_sinph0 * sinphi + m_cosph0 * cosphi * coslon;
215 // if ((g <= 0.0) && (fabs(g) > 1.0e-10)) {
216 // m_good = false;
217 // return m_good;
218 // }
219 
220  // Compute the coordinates
221  double x = ringRadius * cos(deltaAz);
222  double y = ringRadius * sin(deltaAz);
223 
224  SetComputedXY(x, y);
225  m_good = true;
226  return m_good;
227  }
228 
242  bool Planar::SetCoordinate(const double x, const double y) {
243 
244  // Save the coordinate
245  SetXY(x, y);
246 
247  // compute radius and azimuth in degrees
248  m_ringRadius = sqrt(x*x + y*y);
249 
250  if (y == 0.0)
252  else
253  m_ringLongitude = atan2(y,x) + m_centerRingLongitude;
254 
256 
257  // if ( m_ringLongitude < 0.0 )
258  // m_ringLongitude += 360.0;
259 
260  // Cleanup the azimuth
262 
263  // These need to be done for circular type projections
265 
266  if (m_ringLongitudeDomain == 180)
268 
269  m_good = true;
270  return m_good;
271  }
272 
295 /*
296  bool Planar::XYRange(double &minX, double &maxX,
297  double &minY, double &maxY) {
298  double lat, lon;
299 
300  // Check the corners of the lat/lon range
301  XYRangeCheck(m_minimumLatitude, m_minimumLongitude);
302  XYRangeCheck(m_maximumLatitude, m_minimumLongitude);
303  XYRangeCheck(m_minimumLatitude, m_maximumLongitude);
304  XYRangeCheck(m_maximumLatitude, m_maximumLongitude);
305 
306 //cout << " ************ WALK LATITUDE ******************\n";
307 //cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
308  // Walk top and bottom edges
309  for (lat = m_minimumLatitude; lat <= m_maximumLatitude; lat += 0.01) {
310 //cout << "WALKED A STEP - lat: " << lat << "\n";
311  lat = lat;
312  lon = m_minimumLongitude;
313  XYRangeCheck(lat, lon);
314 
315  lat = lat;
316  lon = m_maximumLongitude;
317  XYRangeCheck(lat, lon);
318 //cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
319  }
320 
321 //cout << " ************ WALK LONGITUDE ******************\n";
322  // Walk left and right edges
323  for (lon = m_minimumLongitude; lon <= m_maximumLongitude; lon += 0.01) {
324  lat = m_minimumLatitude;
325  lon = lon;
326  XYRangeCheck(lat, lon);
327 
328  lat = m_maximumLatitude;
329  lon = lon;
330  XYRangeCheck(lat, lon);
331  }
332 
333  // Walk the limb
334  for (double angle = 0.0; angle <= 360.0; angle += 0.01) {
335  double x = m_equatorialRadius * cos(angle * PI / 180.0);
336  double y = m_equatorialRadius * sin(angle * PI / 180.0);
337  if (SetCoordinate(x, y) == 0) {
338  if (m_latitude > m_maximumLatitude) {
339  continue;
340  }
341  if (m_longitude > m_maximumLongitude) {
342  continue;
343  }
344  if (m_latitude < m_minimumLatitude) {
345  continue;
346  }
347  if (m_longitude < m_minimumLongitude) {
348  continue;
349  }
350 
351  if (m_minimumX > x) m_minimumX = x;
352  if (m_maximumX < x) m_maximumX = x;
353  if (m_minimumY > y) m_minimumY = y;
354  if (m_maximumY < y) m_maximumY = y;
355  XYRangeCheck(m_latitude, m_longitude);
356  }
357  }
358 
359  // Make sure everything is ordered
360  if (m_minimumX >= m_maximumX) return false;
361  if (m_minimumY >= m_maximumY) return false;
362 
363  // Return X/Y min/maxs
364  minX = m_minimumX;
365  maxX = m_maximumX;
366  minY = m_minimumY;
367  maxY = m_maximumY;
368  return true;
369  }
370 */
371 
372 
395  bool Planar::XYRange(double &minX, double &maxX,
396  double &minY, double &maxY) {
397 
398  double rad, az;
399 
400  // Check the corners of the rad/az range
405 
406  // Walk top and bottom edges in half pixel increments
407  double radiusInc = 2. * (m_maximumRingRadius - m_minimumRingRadius) / PixelResolution();
408 
409  for (rad = m_minimumRingRadius; rad <= m_maximumRingRadius; rad += radiusInc) {
411  XYRangeCheck(rad, az);
412 
414  XYRangeCheck(rad, az);
415  }
416 
417  // Walk left and right edges
418  for (az = m_minimumRingLongitude; az <= m_maximumRingLongitude; az += 0.01) {
419  rad = m_minimumRingRadius;
420  XYRangeCheck(rad, az);
421 
422  rad = m_maximumRingRadius;
423  XYRangeCheck(rad, az);
424  }
425 
426  // Make sure everything is ordered
427  if (m_minimumX >= m_maximumX) return false;
428  if (m_minimumY >= m_maximumY) return false;
429 
430  // Return X/Y min/maxs
431  // m_maximumX = m_maximumRingRadius*cos(m_maximumRingLongitude);
432  // m_minimumX = -m_maximumX;
433  // m_maximumY = m_maximumRingRadius*sin(m_maximumRingLongitude);
434  // m_minimumY = -m_maximumY;
435 
436  minX = m_minimumX;
437  maxX = m_maximumX;
438  minY = m_minimumY;
439  maxY = m_maximumY;
440 
441  return true;
442  }
443 
444 
452 
453  mapping += PvlKeyword("CenterRingRadius", toString(m_centerRingRadius));
454  double dir = 1.0;
455  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
456  double lonDegrees = m_centerRingLongitude*RAD2DEG*dir;
457  mapping += PvlKeyword("CenterRingLongitude", toString(lonDegrees));
458 
459  return mapping;
460  }
461 
469 
470  if (HasGroundRange())
471  mapping += m_mappingGrp["CenterRingRadius"];
472 
473  return mapping;
474  }
475 
476 
484 
485  if (HasGroundRange())
486  mapping += m_mappingGrp["CenterRingLongitude"];
487 
488  return mapping;
489  }
490 
491 } // end namespace isis
492 
507  bool allowDefaults) {
508  return new Isis::Planar(lab, allowDefaults);
509 }
Planar Map Projection.
Definition: Planar.h:56
int m_ringLongitudeDomain
This integer is either 180 or 360 and is read from the labels.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
double TrueScaleRingRadius() const
Returns the center radius, in meters.
Definition: Planar.cpp:137
bool XYRange(double &minX, double &maxX, double &minY, double &maxY)
This method is used to determine the x/y range which completely covers the area of interest specified...
Definition: Planar.cpp:395
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
PvlGroup MappingRingRadii()
This function returns the radius keywords that this projection uses.
Definition: Planar.cpp:467
double m_maximumRingLongitude
Contains the maximum longitude for the entire ground range.
double CenterRingLongitude() const
Returns the center longitude, in degrees.
Definition: Planar.cpp:148
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition: Planar.cpp:105
Isis::Projection * PlanarPlugin(Isis::Pvl &lab, bool allowDefaults)
This is the function that is called in order to instantiate an Planar object.
Definition: Planar.cpp:506
double PixelResolution() const
Returns the pixel resolution value from the PVL mapping group in meters/pixel.
Definition: Projection.cpp:855
Namespace for the standard library.
QString Version() const
Returns the version of the map projection.
Definition: Planar.cpp:171
virtual PvlGroup MappingRingLongitudes()
This function returns the ring longitude keywords that this projection uses.
Search child objects.
Definition: PvlObject.h:170
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
Definition: Projection.h:333
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:795
virtual PvlGroup Mapping()
This method is used to find the XY range for oblique aspect projections (non-polar projections) by "w...
double CenterRingRadius() const
Returns the center radius, in meters.
Definition: Planar.cpp:160
double m_maximumY
See minimumX description.
Definition: Projection.h:344
Base class for Map Projections.
Definition: Projection.h:171
double m_minimumY
See minimumX description.
Definition: Projection.h:343
RingLongitudeDirection m_ringLongitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
bool HasGroundRange() const
This indicates if the longitude direction type is positive west (as opposed to postive east)...
Definition: Projection.cpp:364
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A single keyword-value pair.
Definition: PvlKeyword.h:98
QString Name() const
Returns the name of the map projection, "Planar".
Definition: Planar.cpp:120
PvlGroup MappingRingLongitudes()
This function returns the azimuth keywords that this projection uses.
Definition: Planar.cpp:482
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition: Planar.cpp:450
Container for cube-like labels.
Definition: Pvl.h:135
double m_ringLongitude
This contain a ring longitude value.
const double DEG2RAD
Multiplier for converting from degrees to radians.
Definition: Constants.h:59
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
Definition: Projection.h:316
double m_ringRadius
This contain a ring radius value in m.
void XYRangeCheck(const double ringRadius, const double ringLongitude)
This convience function is established to assist in the development of the XYRange virtual method...
Ring longitude values increase in the clockwise direction.
Base class for Map Projections of plane shapes.
double m_maximumRingRadius
Contains the maximum ring radius for the entire ground range.
static double To360Domain(const double lon)
This method converts an ring longitude into the 0 to 360 domain.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
~Planar()
Destroys the Planar object.
Definition: Planar.cpp:94
double m_centerRingLongitude
The center longitude for the map projection.
Definition: Planar.h:80
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition: Constants.h:60
bool SetGround(const double ringRadius, const double ringLongitude)
This method is used to set the radius/azimuth (assumed to be of the correct RingLongitudeDirection, a nd RingLongitudeDomain.
Definition: Planar.cpp:188
void SetXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:819
static double To180Domain(const double lon)
This method converts a ring longitude into the -180 to 180 domain.
double m_maximumX
See minimumX description.
Definition: Projection.h:342
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition: Planar.cpp:242
double m_minimumRingLongitude
Contains the minimum longitude for the entire ground range.
virtual PvlGroup MappingRingRadii()
This function returns the ring radius keywords that this projection uses.
double m_centerRingRadius
The center radius for the map projection.
Definition: Planar.h:81
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:345
double m_minimumRingRadius
Contains the minimum ring radius for the entire ground range.