Isis 3 Programmer Reference
RingCylindrical.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "RingCylindrical.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 #include "SpecialPixel.h"
19 
20 using namespace std;
21 namespace Isis {
22 
39  RingCylindrical::RingCylindrical(Pvl &label, bool allowDefaults) :
41  try {
42  // Try to read the mapping group
43  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
44 
45  // Compute the default value if allowed and needed
46  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingLongitude"))) {
47  double az = (m_minimumRingLongitude + m_maximumRingLongitude) / 2.0;
48  mapGroup += PvlKeyword("CenterRingLongitude", toString(az));
49  }
50 
51  // Compute and write the default center radius if allowed and
52  // necessary
53  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingRadius"))) {
54  double radius = (m_minimumRingRadius + m_maximumRingRadius) / 2.0;
55  mapGroup += PvlKeyword("CenterRingRadius", toString(radius));
56  }
57 
58  // Get the center ring radius and center ring longitude.
59  m_centerRingLongitude = mapGroup["CenterRingLongitude"];
60  m_centerRingRadius = mapGroup["CenterRingRadius"];
61 
62  // Because the center radius is used to scale the y values of the projection, it cannot be 0.
63  // For now, we will reset the center to the radius of Saturn.
64  // Perhaps we should fail and issue an error message??? TODO
65  if (m_centerRingRadius == 0.0) {
66  m_centerRingRadius = 18000.;
67  }
68 
69  // Convert to radians, adjust for azimuth direction
72  }
73  catch (IException &e) {
74  string message = "Invalid label group [Mapping]";
75  throw IException(e, IException::Io, message, _FILEINFO_);
76  }
77  }
78 
81  }
82 
92  if (!Projection::operator==(proj)) return false;
93  // dont do the below it is a recusive plunge
94  // if (Projection::operator!=(proj)) return false;
95  RingCylindrical *ringCyl = (RingCylindrical *) &proj;
96  if ((ringCyl->m_centerRingLongitude != m_centerRingLongitude) ||
97  (ringCyl->m_centerRingRadius != m_centerRingRadius)) return false;
98  return true;
99  }
100 
106  QString RingCylindrical::Name() const {
107  return "RingCylindrical";
108  }
109 
115  QString RingCylindrical::Version() const {
116  return "1.0";
117  }
118 
119 
131  return true;
132  }
133 
134 
149  return m_centerRingRadius;
150  }
151 
152 
159  double dir = 1.0;
160  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
161  return m_centerRingLongitude * RAD2DEG * dir;
162  }
163 
164 
171  return m_centerRingRadius;
172  }
173 
174 
188  bool RingCylindrical::SetGround(const double ringRadius, const double ringLongitude) {
189  //TODO Add scalar to make azimuth distance equivalent to radius distance at center rad
190  // Convert to azimuth to radians and adjust
191  m_ringLongitude = ringLongitude;
192  double ringLongitudeRadians = ringLongitude * DEG2RAD;
193  if (m_ringLongitudeDirection == Clockwise) ringLongitudeRadians *= -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  // Compute helper variable
209  double deltaAz = (ringLongitudeRadians - m_centerRingLongitude);
210 
211  // Compute the coordinates
212  if (ringRadius ==0) {
213  // TODO How should we handle this case? We should use epsilon probably instead of 0 too
214  m_good = false;
215  return m_good;
216  }
217  double x = deltaAz * m_centerRingRadius;
218  double y = m_centerRingRadius - ringRadius;
219  SetComputedXY(x, y);
220  m_good = true;
221  return m_good;
222  }
223 
239  bool RingCylindrical::SetCoordinate(const double x, const double y) {
240  // Save the coordinate
241  SetXY(x, y);
242 
243  // Compute radius and make sure it is valid
244  // m_ringRadius = GetY() + m_centerRingRadius;
246  if (m_ringRadius < m_minimumRingRadius || m_ringRadius > m_maximumRingRadius) {
247  m_good = false;
248  return m_good;
249  }
250 
251  // Compute azimuth
253 
254  // Convert to degrees
256 
257  // Cleanup the azimuth
259  // Do these if the projection is circular
260  // m_ringLongitude = To360Domain (m_ringLongitude);
261  // if (m_ringLongitudeDomain == 180) m_ringLongitude = To180Domain(m_ringLongitude);
262 
263  m_good = true;
264  return m_good;
265  }
266 
267 
276 
277  mapping += PvlKeyword("CenterRingRadius", toString(m_centerRingRadius));
278  double dir = 1.0;
279  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
280  double lonDegrees = m_centerRingLongitude*RAD2DEG*dir;
281  mapping += PvlKeyword("CenterRingLongitude", toString(lonDegrees));
282 
283  return mapping;
284  }
285 
294 
295  if (HasGroundRange())
296  mapping += m_mappingGrp["CenterRingRadius"];
297 
298  return mapping;
299  }
300 
301 
310 
311  if (HasGroundRange())
312  mapping += m_mappingGrp["CenterRingLongitude"];
313 
314  return mapping;
315  }
316 
317 
355  bool RingCylindrical::XYRange(double &minX, double &maxX,
356  double &minY, double &maxY) {
357 
358  double rad, az;
359 
360  // Check the corners of the rad/az range
365 
366  // Walk top and bottom edges in half pixel increments
367  double radiusInc = 2. * (m_maximumRingRadius - m_minimumRingRadius) / PixelResolution();
368 
369  for (rad = m_minimumRingRadius; rad <= m_maximumRingRadius; rad += radiusInc) {
371  XYRangeCheck(rad, az);
372 
374  XYRangeCheck(rad, az);
375  }
376 
377  // Walk left and right edges
378  for (az = m_minimumRingLongitude; az <= m_maximumRingLongitude; az += 0.01) {
379  rad = m_minimumRingRadius;
380  XYRangeCheck(rad, az);
381 
382  rad = m_maximumRingRadius;
383  XYRangeCheck(rad, az);
384  }
385 
386  // Make sure everything is ordered
387  if (m_minimumX >= m_maximumX) return false;
388  if (m_minimumY >= m_maximumY) return false;
389 
390  // Return X/Y min/maxs
391  // m_maximumX = m_maximumRingRadius*cos(m_maximumRingLongitude);
392  // m_minimumX = -m_maximumX;
393  // m_maximumY = m_maximumRingRadius*sin(m_maximumRingLongitude);
394  // m_minimumY = -m_maximumY;
395 
396  minX = m_minimumX;
397  maxX = m_maximumX;
398  minY = m_minimumY;
399  maxY = m_maximumY;
400 
401  return true;
402  }
403 } // end namespace isis
404 
417 extern "C" Isis::Projection *RingCylindricalPlugin(Isis::Pvl &lab,
418  bool allowDefaults) {
419  return new Isis::RingCylindrical(lab, allowDefaults);
420 }
Isis::RingCylindrical::TrueScaleRingRadius
double TrueScaleRingRadius() const
Returns the center radius, in meters.
Definition: RingCylindrical.cpp:148
Isis::RingCylindrical::Name
QString Name() const
Returns the name of the map projection, "RingCylindrical".
Definition: RingCylindrical.cpp:106
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::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::RingCylindrical::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: RingCylindrical.cpp:355
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::Projection::m_minimumY
double m_minimumY
See minimumX description.
Definition: Projection.h:327
Isis::Projection::GetX
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:818
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::RingCylindrical::SetGround
bool SetGround(const double ringRadius, const double ringLongitude)
This method is used to set the radius/longitude (assumed to be of the correct RingLongitudeDirection,...
Definition: RingCylindrical.cpp:188
Isis::RingPlaneProjection::m_ringRadius
double m_ringRadius
This contain a ring radius value in m.
Definition: RingPlaneProjection.h:261
Isis::Projection::m_mappingGrp
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:329
Isis::Projection::GetY
double GetY() const
Calculates the unrotated form of the current y value.
Definition: Projection.cpp:829
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::RingCylindrical::CenterRingRadius
double CenterRingRadius() const
Returns the center radius, in meters.
Definition: RingCylindrical.cpp:170
Isis::RingCylindrical::operator==
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition: RingCylindrical.cpp:91
Isis::RingCylindrical::Version
QString Version() const
Returns the version of the map projection.
Definition: RingCylindrical.cpp:115
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::RingCylindrical::SetCoordinate
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition: RingCylindrical.cpp:239
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::RingCylindrical::~RingCylindrical
~RingCylindrical()
Destroys the RingCylindrical object.
Definition: RingCylindrical.cpp:80
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::RingCylindrical
Ring Cylindrical Map Projection.
Definition: RingCylindrical.h:37
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::IException
Isis exception class.
Definition: IException.h:91
Isis::RingCylindrical::m_centerRingRadius
double m_centerRingRadius
The center ring radius for the map projection.
Definition: RingCylindrical.h:64
Isis::RingCylindrical::MappingRingRadii
PvlGroup MappingRingRadii()
This function returns the radii keywords that this projection uses.
Definition: RingCylindrical.cpp:292
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::RingCylindrical::MappingRingLongitudes
PvlGroup MappingRingLongitudes()
This function returns the longitude keywords that this projection uses.
Definition: RingCylindrical.cpp:308
Isis::RingPlaneProjection::m_minimumRingRadius
double m_minimumRingRadius
Contains the minimum ring radius for the entire ground range.
Definition: RingPlaneProjection.h:281
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::Projection::m_maximumY
double m_maximumY
See minimumX description.
Definition: Projection.h:328
Isis::RingCylindrical::Mapping
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition: RingCylindrical.cpp:274
Isis::RingPlaneProjection::m_minimumRingLongitude
double m_minimumRingLongitude
Contains the minimum longitude for the entire ground range.
Definition: RingPlaneProjection.h:287
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::RingCylindrical::CenterRingLongitude
double CenterRingLongitude() const
Returns the center longitude, in degrees.
Definition: RingCylindrical.cpp:158
Isis::RingCylindrical::IsEquatorialCylindrical
bool IsEquatorialCylindrical()
This method returns true if the projection is equatorial cylindrical.
Definition: RingCylindrical.cpp:130
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::RingCylindrical::m_centerRingLongitude
double m_centerRingLongitude
The center ring longitude (azimuth) for the map projection, in radians.
Definition: RingCylindrical.h:62