Isis 3 Programmer Reference
ObliqueCylindrical.cpp
Go to the documentation of this file.
1 
23 #include "ObliqueCylindrical.h"
24 
25 #include <cfloat>
26 #include <cmath>
27 
28 #include <SpiceUsr.h>
29 
30 #include "Constants.h"
31 #include "IException.h"
32 #include "TProjection.h"
33 #include "Pvl.h"
34 #include "PvlGroup.h"
35 #include "PvlKeyword.h"
36 #include "NaifStatus.h"
37 
38 using namespace std;
39 namespace Isis {
53  ObliqueCylindrical::ObliqueCylindrical(Pvl &label, bool allowDefaults) :
54  TProjection::TProjection(label) {
55  try {
56  // Try to read the mapping group
57  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
58 
59  m_poleLatitude = mapGroup["PoleLatitude"];
60 
61  // All latitudes must be planetographic
62  if (IsPlanetocentric()) {
64  }
65 
66  if (m_poleLatitude < -90 || m_poleLatitude > 90) {
68  "Pole latitude must be between -90 and 90.",
69  _FILEINFO_);
70  }
71 
72  m_poleLongitude = mapGroup["PoleLongitude"];
73 
74  if (m_poleLongitude < -360 || m_poleLongitude > 360) {
76  "Pole longitude must be between -360 and 360.",
77  _FILEINFO_);
78  }
79 
80  m_poleRotation = mapGroup["PoleRotation"];
81 
82  if (m_poleRotation < -360 || m_poleRotation > 360) {
84  "Pole rotation must be between -360 and 360.",
85  _FILEINFO_);
86  }
87 
88  bool calculateVectors = false;
89 
90  // Check vectors for the right array size
91  if (!mapGroup.hasKeyword("XAxisVector")
92  || mapGroup["XAxisVector"].size() != 3) {
93  calculateVectors = true;
94  }
95 
96  if (!mapGroup.hasKeyword("YAxisVector")
97  || mapGroup["YAxisVector"].size() != 3) {
98  calculateVectors = true;
99  }
100 
101  if (!mapGroup.hasKeyword("ZAxisVector")
102  || mapGroup["ZAxisVector"].size() != 3) {
103  calculateVectors = true;
104  }
105 
106  if (!calculateVectors) {
107  // Read in vectors
108  m_xAxisVector.push_back(toDouble(mapGroup["XAxisVector"][0]));
109  m_xAxisVector.push_back(toDouble(mapGroup["XAxisVector"][1]));
110  m_xAxisVector.push_back(toDouble(mapGroup["XAxisVector"][2]));
111 
112  m_yAxisVector.push_back(toDouble(mapGroup["YAxisVector"][0]));
113  m_yAxisVector.push_back(toDouble(mapGroup["YAxisVector"][1]));
114  m_yAxisVector.push_back(toDouble(mapGroup["YAxisVector"][2]));
115 
116  m_zAxisVector.push_back(toDouble(mapGroup["ZAxisVector"][0]));
117  m_zAxisVector.push_back(toDouble(mapGroup["ZAxisVector"][1]));
118  m_zAxisVector.push_back(toDouble(mapGroup["ZAxisVector"][2]));
119  }
120  else {
121  // Calculate the vectors and store them in the labels
122  // The vectors are useful for processing later on, but are
123  // not actually used here
124  double rotationAngle = m_poleRotation * (PI / 180.0);
125  double latitudeAngle = (90.0 - m_poleLatitude) * (PI / 180.0);
126  double longitudeAngle = (360.0 - m_poleLongitude) * (PI / 180.0);
127  double pvec[3][3];
128 
130  eul2m_c(rotationAngle, latitudeAngle, longitudeAngle, 3, 2, 3, pvec);
132 
133  // Reset the vector keywords
134  if (mapGroup.hasKeyword("XAxisVector")) {
135  mapGroup.deleteKeyword("XAxisVector");
136  }
137  if (mapGroup.hasKeyword("YAxisVector")) {
138  mapGroup.deleteKeyword("YAxisVector");
139  }
140  if (mapGroup.hasKeyword("ZAxisVector")) {
141  mapGroup.deleteKeyword("ZAxisVector");
142  }
143 
144  mapGroup += PvlKeyword("XAxisVector");
145  mapGroup += PvlKeyword("YAxisVector");
146  mapGroup += PvlKeyword("ZAxisVector");
147 
148  // Store calculations both in vector and PVL
149  for (int i = 0; i < 3; i++) {
150  m_xAxisVector.push_back(pvec[0][i]); //X[i]
151  m_yAxisVector.push_back(pvec[1][i]); //Y[i]
152  m_zAxisVector.push_back(pvec[2][i]); //Z[i]
153 
154  mapGroup["XAxisVector"] += toString(pvec[0][i]); //X[i]
155  mapGroup["YAxisVector"] += toString(pvec[1][i]); //Y[i]
156  mapGroup["ZAxisVector"] += toString(pvec[2][i]); //Z[i]
157  }
158  }
159 
160  init();
161  }
162  catch(IException &e) {
163  QString message = "Invalid label group [Mapping]";
164  throw IException(e, IException::Io, message, _FILEINFO_);
165  }
166  }
167 
170  }
171 
181  if (!Projection::operator==(proj)) return false;
182 
183  ObliqueCylindrical *obProjection = (ObliqueCylindrical *) &proj;
184 
185  if (obProjection->poleLatitude() != poleLatitude()) return false;
186  if (obProjection->poleLongitude() != poleLongitude()) return false;
187  if (obProjection->poleRotation() != poleRotation()) return false;
188 
189  return true;
190  }
191 
197  QString ObliqueCylindrical::Name() const {
198  return "ObliqueCylindrical";
199  }
200 
207  QString ObliqueCylindrical::Version() const {
208  return "1.0";
209  }
210 
223  bool ObliqueCylindrical::SetGround(const double lat, const double lon) {
224  double normalLat, normalLon; // normal lat/lon
225  double obliqueLat, obliqueLon; // oblique lat/lon copy
226 
227  // Store lat,lon
228  m_latitude = lat;
229  m_longitude = lon;
230 
231  // Use oblat,oblon as radians version of lat,lon now for calculations
232  normalLat = m_latitude * PI / 180.0;
233  normalLon = m_longitude * PI / 180.0;
234  if (m_longitudeDirection == PositiveWest) normalLon *= -1.0;
235 
236 
237  /***************************************************************************
238  * Calculate the oblique lat/lon from the normal lat/lon
239  ***************************************************************************/
240  double poleLatitude = (m_poleLatitude * PI / 180.0);
241  double poleLongitude = (m_poleLongitude * PI / 180.0);
242  double poleRotation = (m_poleRotation * PI / 180.0);
243 
244  obliqueLat = asin(sin(poleLatitude) * sin(normalLat) +
245  cos(poleLatitude) * cos(normalLat)
246  * cos(normalLon - poleLongitude));
247 
248  obliqueLon = atan2(cos(normalLat) * sin(normalLon - poleLongitude),
249  sin(poleLatitude) * cos(normalLat)
250  * cos(normalLon - poleLongitude) -
251  cos(poleLatitude) * sin(normalLat)) - poleRotation;
252 
253  while(obliqueLon < - PI) {
254  obliqueLon += (2.0 * PI);
255  }
256 
257  while(obliqueLon >= PI) {
258  obliqueLon -= (2.0 * PI);
259  }
260 
261  // Compute the coordinate
262  double x = m_equatorialRadius * obliqueLon;
263  double y = m_equatorialRadius * obliqueLat;
264  SetComputedXY(x, y);
265 
266  m_good = true;
267  return m_good;
268  }
269 
283  bool ObliqueCylindrical::SetCoordinate(const double x, const double y) {
284  // Save the coordinate
285  SetXY(x, y);
286 
287  /***************************************************************************
288  * Calculate the oblique latitude and check to see if it is outside or equal
289  * to [-90,90]. If it is, return with an error.
290  ***************************************************************************/
292 
293  if (abs(abs(m_latitude) - HALFPI) < DBL_EPSILON) {
294  m_good = false;
295  return m_good;
296  }
297 
298  /***************************************************************************
299  * The check to see if m_equatorialRadius == 0 is done in the init function
300  ***************************************************************************/
302 
303  /***************************************************************************
304  * Convert the oblique lat/lon to normal lat/lon
305  ***************************************************************************/
306  double obliqueLat, obliqueLon;
307  double poleLatitude = (m_poleLatitude * PI / 180.0);
308  double poleLongitude = (m_poleLongitude * PI / 180.0);
309  double poleRotation = (m_poleRotation * PI / 180.0);
310 
311  obliqueLat = asin(sin(poleLatitude) * sin(m_latitude) -
312  cos(poleLatitude) * cos(m_latitude) * cos(m_longitude + poleRotation));
313 
314  obliqueLon = atan2(cos(m_latitude) * sin(m_longitude + poleRotation),
315  sin(poleLatitude) * cos(m_latitude) * cos(m_longitude + poleRotation) +
316  cos(poleLatitude) * sin(m_latitude)) + poleLongitude;
317 
318  /***************************************************************************
319  * Convert the latitude/longitude to degrees and apply target longitude
320  * direction correction to the longitude
321  ***************************************************************************/
322  m_latitude = obliqueLat * 180.0 / PI;
323  m_longitude = obliqueLon * 180.0 / PI;
324 
325  // Cleanup the longitude
327 
328  m_good = true;
329  return m_good;
330  }
331 
361  bool ObliqueCylindrical::XYRange(double &minX, double &maxX,
362  double &minY, double &maxY) {
363  return xyRangeOblique(minX, maxX, minY, maxY);
364  }
365 
366 
373  PvlGroup mapping = TProjection::Mapping();
374 
375  mapping += m_mappingGrp["PoleLatitude"];
376  mapping += m_mappingGrp["PoleLongitude"];
377  mapping += m_mappingGrp["PoleRotation"];
378 
379  return mapping;
380  }
381 
389 
390  return mapping;
391  }
392 
400 
401  return mapping;
402  }
403 
411  return m_poleLatitude;
412  }
413 
421  return m_poleLongitude;
422  }
423 
431  return m_poleRotation;
432  }
433 
434  void ObliqueCylindrical::init() {
435  /***************************************************************************
436  * Apply target correction for longitude direction
437  ***************************************************************************/
440 
441  /***************************************************************************
442  * Check that m_equatorialRadius isn't zero because we'll divide by it later
443  ***************************************************************************/
444  if (abs(m_equatorialRadius) <= DBL_EPSILON) {
446  "The input center latitude is too close to a pole "
447  "which will result in a division by zero.",
448  _FILEINFO_);
449  }
450  }
451 
452 } // end namespace isis
453 
466  bool allowDefaults) {
467  return new Isis::ObliqueCylindrical(lab, allowDefaults);
468 }
~ObliqueCylindrical()
Destroys the ObliqueCylindrical object.
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
bool operator==(const Isis::Projection &proj)
Compares two Projection objects to see if they are equal.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
bool xyRangeOblique(double &minX, double &maxX, double &minY, double &maxY)
This method is used to find the XY range for oblique aspect projections (non-polar projections) by "w...
const double PI
The mathematical constant PI.
Definition: Constants.h:56
Longitude values increase in the westerly direction.
Definition: TProjection.h:241
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
Isis::Projection * ObliqueCylindricalPlugin(Isis::Pvl &lab, bool allowDefaults)
This is the function that is called in order to instantiate an ObliqueCylindrical object...
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...
Base class for Map TProjections.
Definition: TProjection.h:182
const double HALFPI
The mathematical constant PI/2.
Definition: Constants.h:57
Namespace for the standard library.
double poleLatitude() const
Returns the value of the pole latitude.
Search child objects.
Definition: PvlObject.h:170
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:833
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
double toDouble(const QString &string)
Global function to convert from a string to a double.
Definition: IString.cpp:164
double m_poleLongitude
The Oblique Pole Longitude.
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
double m_latitude
This contains the currently set latitude value.
Definition: TProjection.h:332
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
double m_longitude
This contains the currently set longitude value.
Definition: TProjection.h:334
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
Base class for Map Projections.
Definition: Projection.h:171
double poleRotation() const
Returns the value of the pole rotation.
double m_equatorialRadius
Polar radius of the target.
Definition: TProjection.h:351
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
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
PvlGroup Mapping()
This function returns the keywords that this projection uses.
A single keyword-value pair.
Definition: PvlKeyword.h:98
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:134
bool SetGround(const double lat, const double lon)
This method is used to set the latitude/longitude (assumed to be of the correct LatitudeType, LongitudeDirection, and LongitudeDomain.
std::vector< double > m_zAxisVector
The z-axis vector, read from the mapping group in the label.
double poleLongitude() const
Returns the value of the pole longitude.
std::vector< double > m_yAxisVector
The y-axis vector, read from the mapping group in the label.
Container for cube-like labels.
Definition: Pvl.h:135
double ToPlanetographic(const double lat) const
This method converts a planetocentric latitude to a planetographic latitude.
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
Definition: Projection.h:316
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
LongitudeDirection m_longitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
Definition: TProjection.h:340
QString Version() const
Returns the version of the map projection.
QString Name() const
Returns the name of the map projection, "ObliqueCylindrical".
static void CheckErrors(bool resetNaif=true)
This method looks for any naif errors that might have occurred.
Definition: NaifStatus.cpp:43
Isis exception class.
Definition: IException.h:107
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
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
void SetXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:819
std::vector< double > m_xAxisVector
The x-axis vector, read from the mapping group in the label.
double m_poleLatitude
The Oblique Pole Latitude.
Oblique Cylindrical Map Projection.
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:345
void deleteKeyword(const QString &name)
Remove a specified keyword.
double m_poleRotation
The Oblique Pole Rotation.