Isis 3 Programmer Reference
Planar.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "Planar.h"
8 
9 #include <cmath>
10 #include <cfloat>
11 
12 #include "Constants.h"
13 #include "IException.h"
14 #include "Pvl.h"
15 #include "PvlGroup.h"
16 #include "PvlKeyword.h"
17 #include "RingPlaneProjection.h"
18 
19 using namespace std;
20 namespace Isis {
39  Planar::Planar(Pvl &label, bool allowDefaults) :
41 
42  // latitude in ring plane is always zero
43  m_ringRadius = 0.0;
44 
45  try {
46  // Try to read the mapping group
47  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
48 
49  // Compute and write the default center longitude if allowed and
50  // necessary
51  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingLongitude"))) {
52  double azimuth = (m_minimumRingLongitude + m_maximumRingLongitude) / 2.0;
53  mapGroup += PvlKeyword("CenterRingLongitude", toString(azimuth));
54  }
55 
56  // Compute and write the default center radius if allowed and
57  // necessary
58  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingRadius"))) {
59  double radius = (m_minimumRingRadius + m_maximumRingRadius) / 2.0;
60  mapGroup += PvlKeyword("CenterRingRadius", toString(radius));
61  }
62 
63  // Get the center longitude & radius
64  m_centerRingLongitude = mapGroup["CenterRingLongitude"];
65  m_centerRingRadius = mapGroup["CenterRingRadius"];
66 
67  // convert to radians, adjust for azimuth direction
70  }
71  catch(IException &e) {
72  string message = "Invalid label group [Mapping]";
73  throw IException(e, IException::Io, message, _FILEINFO_);
74  }
75  }
76 
79  }
80 
89  bool Planar::operator== (const Projection &proj) {
90  if (!RingPlaneProjection::operator==(proj)) return false;
91  // dont do the below it is a recursive plunge
92  // if (Projection::operator!=(proj)) return false;
93  Planar *planar = (Planar *) &proj;
95  (planar->m_centerRingRadius != m_centerRingRadius)) return false;
96  return true;
97  }
98 
104  QString Planar::Name() const {
105  return "Planar";
106  }
107 
122  return m_centerRingRadius;
123  // return 60268000.0;
124  }
125 
126 
133  double dir = 1.0;
134  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
135  return m_centerRingLongitude * RAD2DEG * dir;;
136  }
137 
138 
144  double Planar::CenterRingRadius() const {
145  return m_centerRingRadius;
146  }
147 
148 
155  QString Planar::Version() const {
156  return "1.0";
157  }
158 
159 
172  bool Planar::SetGround(const double ringRadius, const double ringLongitude) {
173 
174  // Convert azimuth to radians & adjust
175  m_ringLongitude = ringLongitude;
176  double azRadians = ringLongitude * DEG2RAD;
177  if (m_ringLongitudeDirection == Clockwise) azRadians *= -1.0;
178 
179  // Check to make sure radius is valid
180  if (ringRadius < 0) {
181  m_good = false;
182  // cout << "Unable to set radius. The given radius value ["
183  // << IString(ringRadius) << "] is invalid." << endl;
184  // throw IException(IException::Unknown,
185  // "Unable to set radius. The given radius value ["
186  // + IString(ringRadius) + "] is invalid.",
187  // _FILEINFO_);
188  return m_good;
189  }
190  m_ringRadius = ringRadius;
191 
192 
193  // Compute helper variables
194  double deltaAz = (azRadians - m_centerRingLongitude);
195 // double coslon = cos(deltaLon);
196 
197  // Lat/Lon cannot be projected
198 // double g = m_sinph0 * sinphi + m_cosph0 * cosphi * coslon;
199 // if ((g <= 0.0) && (fabs(g) > 1.0e-10)) {
200 // m_good = false;
201 // return m_good;
202 // }
203 
204  // Compute the coordinates
205  double x = ringRadius * cos(deltaAz);
206  double y = ringRadius * sin(deltaAz);
207 
208  SetComputedXY(x, y);
209  m_good = true;
210  return m_good;
211  }
212 
226  bool Planar::SetCoordinate(const double x, const double y) {
227 
228  // Save the coordinate
229  SetXY(x, y);
230 
231  // compute radius and azimuth in degrees
232  m_ringRadius = sqrt(x*x + y*y);
233 
234  if (y == 0.0)
236  else
237  m_ringLongitude = atan2(y,x) + m_centerRingLongitude;
238 
240 
241  // if ( m_ringLongitude < 0.0 )
242  // m_ringLongitude += 360.0;
243 
244  // Cleanup the azimuth
246 
247  // These need to be done for circular type projections
249 
250  if (m_ringLongitudeDomain == 180)
252 
253  m_good = true;
254  return m_good;
255  }
256 
279 /*
280  bool Planar::XYRange(double &minX, double &maxX,
281  double &minY, double &maxY) {
282  double lat, lon;
283 
284  // Check the corners of the lat/lon range
285  XYRangeCheck(m_minimumLatitude, m_minimumLongitude);
286  XYRangeCheck(m_maximumLatitude, m_minimumLongitude);
287  XYRangeCheck(m_minimumLatitude, m_maximumLongitude);
288  XYRangeCheck(m_maximumLatitude, m_maximumLongitude);
289 
290 //cout << " ************ WALK LATITUDE ******************\n";
291 //cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
292  // Walk top and bottom edges
293  for (lat = m_minimumLatitude; lat <= m_maximumLatitude; lat += 0.01) {
294 //cout << "WALKED A STEP - lat: " << lat << "\n";
295  lat = lat;
296  lon = m_minimumLongitude;
297  XYRangeCheck(lat, lon);
298 
299  lat = lat;
300  lon = m_maximumLongitude;
301  XYRangeCheck(lat, lon);
302 //cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
303  }
304 
305 //cout << " ************ WALK LONGITUDE ******************\n";
306  // Walk left and right edges
307  for (lon = m_minimumLongitude; lon <= m_maximumLongitude; lon += 0.01) {
308  lat = m_minimumLatitude;
309  lon = lon;
310  XYRangeCheck(lat, lon);
311 
312  lat = m_maximumLatitude;
313  lon = lon;
314  XYRangeCheck(lat, lon);
315  }
316 
317  // Walk the limb
318  for (double angle = 0.0; angle <= 360.0; angle += 0.01) {
319  double x = m_equatorialRadius * cos(angle * PI / 180.0);
320  double y = m_equatorialRadius * sin(angle * PI / 180.0);
321  if (SetCoordinate(x, y) == 0) {
322  if (m_latitude > m_maximumLatitude) {
323  continue;
324  }
325  if (m_longitude > m_maximumLongitude) {
326  continue;
327  }
328  if (m_latitude < m_minimumLatitude) {
329  continue;
330  }
331  if (m_longitude < m_minimumLongitude) {
332  continue;
333  }
334 
335  if (m_minimumX > x) m_minimumX = x;
336  if (m_maximumX < x) m_maximumX = x;
337  if (m_minimumY > y) m_minimumY = y;
338  if (m_maximumY < y) m_maximumY = y;
339  XYRangeCheck(m_latitude, m_longitude);
340  }
341  }
342 
343  // Make sure everything is ordered
344  if (m_minimumX >= m_maximumX) return false;
345  if (m_minimumY >= m_maximumY) return false;
346 
347  // Return X/Y min/maxs
348  minX = m_minimumX;
349  maxX = m_maximumX;
350  minY = m_minimumY;
351  maxY = m_maximumY;
352  return true;
353  }
354 */
355 
356 
379  bool Planar::XYRange(double &minX, double &maxX,
380  double &minY, double &maxY) {
381 
382  double rad, az;
383 
384  // Check the corners of the rad/az range
389 
390  // Walk top and bottom edges in half pixel increments
391  double radiusInc = 2. * (m_maximumRingRadius - m_minimumRingRadius) / PixelResolution();
392 
393  for (rad = m_minimumRingRadius; rad <= m_maximumRingRadius; rad += radiusInc) {
395  XYRangeCheck(rad, az);
396 
398  XYRangeCheck(rad, az);
399  }
400 
401  // Walk left and right edges
402  for (az = m_minimumRingLongitude; az <= m_maximumRingLongitude; az += 0.01) {
403  rad = m_minimumRingRadius;
404  XYRangeCheck(rad, az);
405 
406  rad = m_maximumRingRadius;
407  XYRangeCheck(rad, az);
408  }
409 
410  // Make sure everything is ordered
411  if (m_minimumX >= m_maximumX) return false;
412  if (m_minimumY >= m_maximumY) return false;
413 
414  // Return X/Y min/maxs
415  // m_maximumX = m_maximumRingRadius*cos(m_maximumRingLongitude);
416  // m_minimumX = -m_maximumX;
417  // m_maximumY = m_maximumRingRadius*sin(m_maximumRingLongitude);
418  // m_minimumY = -m_maximumY;
419 
420  minX = m_minimumX;
421  maxX = m_maximumX;
422  minY = m_minimumY;
423  maxY = m_maximumY;
424 
425  return true;
426  }
427 
428 
436 
437  mapping += PvlKeyword("CenterRingRadius", toString(m_centerRingRadius));
438  double dir = 1.0;
439  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
440  double lonDegrees = m_centerRingLongitude*RAD2DEG*dir;
441  mapping += PvlKeyword("CenterRingLongitude", toString(lonDegrees));
442 
443  return mapping;
444  }
445 
453 
454  if (HasGroundRange())
455  mapping += m_mappingGrp["CenterRingRadius"];
456 
457  return mapping;
458  }
459 
460 
468 
469  if (HasGroundRange())
470  mapping += m_mappingGrp["CenterRingLongitude"];
471 
472  return mapping;
473  }
474 
475 } // end namespace isis
476 
490 extern "C" Isis::Projection *PlanarPlugin(Isis::Pvl &lab,
491  bool allowDefaults) {
492  return new Isis::Planar(lab, allowDefaults);
493 }
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::IException::Io
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:155
Isis::Planar::MappingRingRadii
PvlGroup MappingRingRadii()
This function returns the radius keywords that this projection uses.
Definition: Planar.cpp:451
Isis::RingPlaneProjection::m_maximumRingLongitude
double m_maximumRingLongitude
Contains the maximum longitude for the entire ground range.
Definition: RingPlaneProjection.h:290
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::RingPlaneProjection::Mapping
virtual PvlGroup Mapping()
This method is used to find the XY range for oblique aspect projections (non-polar projections) by "w...
Definition: RingPlaneProjection.cpp:1253
Isis::RingPlaneProjection::To360Domain
static double To360Domain(const double lon)
This method converts an ring longitude into the 0 to 360 domain.
Definition: RingPlaneProjection.cpp:370
Isis::DEG2RAD
const double DEG2RAD
Multiplier for converting from degrees to radians.
Definition: Constants.h:43
Isis::Projection::PixelResolution
double PixelResolution() const
Returns the pixel resolution value from the PVL mapping group in meters/pixel.
Definition: Projection.cpp:840
Isis::Planar::Version
QString Version() const
Returns the version of the map projection.
Definition: Planar.cpp:155
Isis::Projection::m_minimumY
double m_minimumY
See minimumX description.
Definition: Projection.h:327
Isis::Planar::operator==
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition: Planar.cpp:89
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::Projection::SetXY
void SetXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:804
Isis::RingPlaneProjection::m_maximumRingRadius
double m_maximumRingRadius
Contains the maximum ring radius for the entire ground range.
Definition: RingPlaneProjection.h:284
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::RingPlaneProjection::m_ringRadius
double m_ringRadius
This contain a ring radius value in m.
Definition: RingPlaneProjection.h:261
Isis::Planar::CenterRingLongitude
double CenterRingLongitude() const
Returns the center longitude, in degrees.
Definition: Planar.cpp:132
Isis::Planar
Planar Map Projection.
Definition: Planar.h:40
Isis::Projection::m_mappingGrp
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:329
Isis::RingPlaneProjection::XYRangeCheck
void XYRangeCheck(const double ringRadius, const double ringLongitude)
This convience function is established to assist in the development of the XYRange virtual method.
Definition: RingPlaneProjection.cpp:709
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::Planar::CenterRingRadius
double CenterRingRadius() const
Returns the center radius, in meters.
Definition: Planar.cpp:144
Isis::RingPlaneProjection
Base class for Map Projections of plane shapes.
Definition: RingPlaneProjection.h:147
Isis::Projection::m_minimumX
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
Definition: Projection.h:317
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Projection::m_good
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
Definition: Projection.h:300
Isis::Planar::Name
QString Name() const
Returns the name of the map projection, "Planar".
Definition: Planar.cpp:104
Isis::Planar::MappingRingLongitudes
PvlGroup MappingRingLongitudes()
This function returns the azimuth keywords that this projection uses.
Definition: Planar.cpp:466
Isis::RingPlaneProjection::MappingRingRadii
virtual PvlGroup MappingRingRadii()
This function returns the ring radius keywords that this projection uses.
Definition: RingPlaneProjection.cpp:1296
Isis::RingPlaneProjection::m_ringLongitude
double m_ringLongitude
This contain a ring longitude value.
Definition: RingPlaneProjection.h:263
Isis::RingPlaneProjection::m_ringLongitudeDirection
RingLongitudeDirection m_ringLongitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
Definition: RingPlaneProjection.h:267
Isis::RingPlaneProjection::To180Domain
static double To180Domain(const double lon)
This method converts a ring longitude into the -180 to 180 domain.
Definition: RingPlaneProjection.cpp:352
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::Planar::m_centerRingLongitude
double m_centerRingLongitude
The center longitude for the map projection.
Definition: Planar.h:64
Isis::Planar::m_centerRingRadius
double m_centerRingRadius
The center radius for the map projection.
Definition: Planar.h:65
Isis::Projection::SetComputedXY
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:780
std
Namespace for the standard library.
Isis::Planar::~Planar
~Planar()
Destroys the Planar object.
Definition: Planar.cpp:78
Isis::Planar::SetGround
bool SetGround(const double ringRadius, const double ringLongitude)
This method is used to set the radius/azimuth (assumed to be of the correct RingLongitudeDirection,...
Definition: Planar.cpp:172
Isis::RingPlaneProjection::m_minimumRingRadius
double m_minimumRingRadius
Contains the minimum ring radius for the entire ground range.
Definition: RingPlaneProjection.h:281
Isis::Planar::Mapping
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition: Planar.cpp:434
Isis::RingPlaneProjection::MappingRingLongitudes
virtual PvlGroup MappingRingLongitudes()
This function returns the ring longitude keywords that this projection uses.
Definition: RingPlaneProjection.cpp:1313
Isis::RingPlaneProjection::Clockwise
@ Clockwise
Ring longitude values increase in the clockwise direction.
Definition: RingPlaneProjection.h:178
Isis::Planar::TrueScaleRingRadius
double TrueScaleRingRadius() const
Returns the center radius, in meters.
Definition: Planar.cpp:121
Isis::Projection::m_maximumY
double m_maximumY
See minimumX description.
Definition: Projection.h:328
Isis::RingPlaneProjection::m_minimumRingLongitude
double m_minimumRingLongitude
Contains the minimum longitude for the entire ground range.
Definition: RingPlaneProjection.h:287
Isis::RingPlaneProjection::m_ringLongitudeDomain
int m_ringLongitudeDomain
This integer is either 180 or 360 and is read from the labels.
Definition: RingPlaneProjection.h:275
Isis::Projection
Base class for Map Projections.
Definition: Projection.h:155
Isis::Projection::m_maximumX
double m_maximumX
See minimumX description.
Definition: Projection.h:326
Isis::RAD2DEG
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition: Constants.h:44
Isis::Projection::HasGroundRange
virtual bool HasGroundRange() const
This indicates if the longitude direction type is positive west (as opposed to postive east).
Definition: Projection.cpp:349
Isis::Planar::SetCoordinate
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition: Planar.cpp:226
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::Planar::XYRange
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:379