Isis 3 Programmer Reference
RingCylindrical.cpp
Go to the documentation of this file.
1 
23 #include "RingCylindrical.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 #include "SpecialPixel.h"
35 
36 using namespace std;
37 namespace Isis {
38 
55  RingCylindrical::RingCylindrical(Pvl &label, bool allowDefaults) :
57  try {
58  // Try to read the mapping group
59  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
60 
61  // Compute the default value if allowed and needed
62  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingLongitude"))) {
63  double az = (m_minimumRingLongitude + m_maximumRingLongitude) / 2.0;
64  mapGroup += PvlKeyword("CenterRingLongitude", toString(az));
65  }
66 
67  // Compute and write the default center radius if allowed and
68  // necessary
69  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingRadius"))) {
70  double radius = (m_minimumRingRadius + m_maximumRingRadius) / 2.0;
71  mapGroup += PvlKeyword("CenterRingRadius", toString(radius));
72  }
73 
74  // Get the center ring radius and center ring longitude.
75  m_centerRingLongitude = mapGroup["CenterRingLongitude"];
76  m_centerRingRadius = mapGroup["CenterRingRadius"];
77 
78  // Because the center radius is used to scale the y values of the projection, it cannot be 0.
79  // For now, we will reset the center to the radius of Saturn.
80  // Perhaps we should fail and issue an error message??? TODO
81  if (m_centerRingRadius == 0.0) {
82  m_centerRingRadius = 18000.;
83  }
84 
85  // Convert to radians, adjust for azimuth direction
88  }
89  catch (IException &e) {
90  string message = "Invalid label group [Mapping]";
91  throw IException(e, IException::Io, message, _FILEINFO_);
92  }
93  }
94 
97  }
98 
108  if (!Projection::operator==(proj)) return false;
109  // dont do the below it is a recusive plunge
110  // if (Projection::operator!=(proj)) return false;
111  RingCylindrical *ringCyl = (RingCylindrical *) &proj;
112  if ((ringCyl->m_centerRingLongitude != m_centerRingLongitude) ||
113  (ringCyl->m_centerRingRadius != m_centerRingRadius)) return false;
114  return true;
115  }
116 
122  QString RingCylindrical::Name() const {
123  return "RingCylindrical";
124  }
125 
131  QString RingCylindrical::Version() const {
132  return "1.0";
133  }
134 
135 
147  return true;
148  }
149 
150 
165  return m_centerRingRadius;
166  }
167 
168 
175  double dir = 1.0;
176  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
177  return m_centerRingLongitude * RAD2DEG * dir;
178  }
179 
180 
187  return m_centerRingRadius;
188  }
189 
190 
204  bool RingCylindrical::SetGround(const double ringRadius, const double ringLongitude) {
205  //TODO Add scalar to make azimuth distance equivalent to radius distance at center rad
206  // Convert to azimuth to radians and adjust
207  m_ringLongitude = ringLongitude;
208  double ringLongitudeRadians = ringLongitude * DEG2RAD;
209  if (m_ringLongitudeDirection == Clockwise) ringLongitudeRadians *= -1.0;
210 
211  // Check to make sure radius is valid
212  if (ringRadius <= 0) {
213  m_good = false;
214  // cout << "Unable to set radius. The given radius value ["
215  // << IString(ringRadius) << "] is invalid." << endl;
216  // throw IException(IException::Unknown,
217  // "Unable to set radius. The given radius value ["
218  // + IString(ringRadius) + "] is invalid.",
219  // _FILEINFO_);
220  return m_good;
221  }
222  m_ringRadius = ringRadius;
223 
224  // Compute helper variable
225  double deltaAz = (ringLongitudeRadians - m_centerRingLongitude);
226 
227  // Compute the coordinates
228  if (ringRadius ==0) {
229  // TODO How should we handle this case? We should use epsilon probably instead of 0 too
230  m_good = false;
231  return m_good;
232  }
233  double x = deltaAz * m_centerRingRadius;
234  double y = m_centerRingRadius - ringRadius;
235  SetComputedXY(x, y);
236  m_good = true;
237  return m_good;
238  }
239 
255  bool RingCylindrical::SetCoordinate(const double x, const double y) {
256  // Save the coordinate
257  SetXY(x, y);
258 
259  // Compute radius and make sure it is valid
260  // m_ringRadius = GetY() + m_centerRingRadius;
262  if (m_ringRadius < m_minimumRingRadius || m_ringRadius > m_maximumRingRadius) {
263  m_good = false;
264  return m_good;
265  }
266 
267  // Compute azimuth
269 
270  // Convert to degrees
272 
273  // Cleanup the azimuth
275  // Do these if the projection is circular
276  // m_ringLongitude = To360Domain (m_ringLongitude);
277  // if (m_ringLongitudeDomain == 180) m_ringLongitude = To180Domain(m_ringLongitude);
278 
279  m_good = true;
280  return m_good;
281  }
282 
283 
292 
293  mapping += PvlKeyword("CenterRingRadius", toString(m_centerRingRadius));
294  double dir = 1.0;
295  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
296  double lonDegrees = m_centerRingLongitude*RAD2DEG*dir;
297  mapping += PvlKeyword("CenterRingLongitude", toString(lonDegrees));
298 
299  return mapping;
300  }
301 
310 
311  if (HasGroundRange())
312  mapping += m_mappingGrp["CenterRingRadius"];
313 
314  return mapping;
315  }
316 
317 
326 
327  if (HasGroundRange())
328  mapping += m_mappingGrp["CenterRingLongitude"];
329 
330  return mapping;
331  }
332 
333 
371  bool RingCylindrical::XYRange(double &minX, double &maxX,
372  double &minY, double &maxY) {
373 
374  double rad, az;
375 
376  // Check the corners of the rad/az range
381 
382  // Walk top and bottom edges in half pixel increments
383  double radiusInc = 2. * (m_maximumRingRadius - m_minimumRingRadius) / PixelResolution();
384 
385  for (rad = m_minimumRingRadius; rad <= m_maximumRingRadius; rad += radiusInc) {
387  XYRangeCheck(rad, az);
388 
390  XYRangeCheck(rad, az);
391  }
392 
393  // Walk left and right edges
394  for (az = m_minimumRingLongitude; az <= m_maximumRingLongitude; az += 0.01) {
395  rad = m_minimumRingRadius;
396  XYRangeCheck(rad, az);
397 
398  rad = m_maximumRingRadius;
399  XYRangeCheck(rad, az);
400  }
401 
402  // Make sure everything is ordered
403  if (m_minimumX >= m_maximumX) return false;
404  if (m_minimumY >= m_maximumY) return false;
405 
406  // Return X/Y min/maxs
407  // m_maximumX = m_maximumRingRadius*cos(m_maximumRingLongitude);
408  // m_minimumX = -m_maximumX;
409  // m_maximumY = m_maximumRingRadius*sin(m_maximumRingLongitude);
410  // m_minimumY = -m_maximumY;
411 
412  minX = m_minimumX;
413  maxX = m_maximumX;
414  minY = m_minimumY;
415  maxY = m_maximumY;
416 
417  return true;
418  }
419 } // end namespace isis
420 
434  bool allowDefaults) {
435  return new Isis::RingCylindrical(lab, allowDefaults);
436 }
double TrueScaleRingRadius() const
Returns the center radius, in meters.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
double m_maximumRingLongitude
Contains the maximum longitude for the entire ground range.
QString Name() const
Returns the name of the map projection, "RingCylindrical".
double m_centerRingLongitude
The center ring longitude (azimuth) for the map projection, in radians.
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.
virtual PvlGroup MappingRingLongitudes()
This function returns the ring longitude keywords that this projection uses.
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...
Search child objects.
Definition: PvlObject.h:170
Ring Cylindrical Map Projection.
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:833
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
Definition: Projection.h:333
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
double CenterRingRadius() const
Returns the center radius, in meters.
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 m_maximumY
See minimumX description.
Definition: Projection.h:344
bool SetGround(const double ringRadius, const double ringLongitude)
This method is used to set the radius/longitude (assumed to be of the correct RingLongitudeDirection...
QString Version() const
Returns the version of the map projection.
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
~RingCylindrical()
Destroys the RingCylindrical object.
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
Isis::Projection * RingCylindricalPlugin(Isis::Pvl &lab, bool allowDefaults)
This is the function that is called in order to instantiate a RingCylindrical object.
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A single keyword-value pair.
Definition: PvlKeyword.h:98
Container for cube-like labels.
Definition: Pvl.h:135
double m_ringLongitude
This contain a ring longitude value.
PvlGroup Mapping()
This function returns the keywords that this projection uses.
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.
bool IsEquatorialCylindrical()
This method returns true if the projection is equatorial cylindrical.
double m_maximumRingRadius
Contains the maximum ring radius for the entire ground range.
double m_centerRingRadius
The center ring radius for the map projection.
Isis exception class.
Definition: IException.h:107
PvlGroup MappingRingLongitudes()
This function returns the longitude keywords that this projection uses.
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
double GetY() const
Calculates the unrotated form of the current y value.
Definition: Projection.cpp:844
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition: Constants.h:60
double CenterRingLongitude() const
Returns the center longitude, in degrees.
void SetXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:819
PvlGroup MappingRingRadii()
This function returns the radii keywords that this projection uses.
double m_maximumX
See minimumX description.
Definition: Projection.h:342
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.
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.