USGS

Isis 3.0 Object Programmers' Reference

Home

Equirectangular.cpp
Go to the documentation of this file.
1 
23 #include "Equirectangular.h"
24 
25 #include <cmath>
26 #include <cfloat>
27 
28 #include "Constants.h"
29 #include "IException.h"
30 #include "TProjection.h"
31 #include "Pvl.h"
32 #include "PvlGroup.h"
33 #include "PvlKeyword.h"
34 
35 using namespace std;
36 namespace Isis {
65  Equirectangular::Equirectangular(Pvl &label, bool allowDefaults) :
66  TProjection::TProjection(label) {
67  try {
68  // Try to read the mapping group
69  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
70 
71  // Compute the default value if allowed and needed
72  if (!mapGroup.hasKeyword("CenterLongitude")) {
73  if (allowDefaults) {
74  double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
75  mapGroup += PvlKeyword("CenterLongitude", toString(lon));
76  }
77  else {
78  QString message = "Cannot project using Equirectangular Cylindrical";
79  message += " without [CenterLongitude] value. Keyword does not exist";
80  message += " in labels and defaults are not allowed.";
81  throw IException(IException::Unknown, message, _FILEINFO_);
82  }
83  }
84 
85  if (!mapGroup.hasKeyword("CenterLatitude")) {
86  if (allowDefaults) {
87  double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
88  mapGroup += PvlKeyword("CenterLatitude", toString(lat));
89  }
90  else {
91  QString message = "Cannot project using Equirectangular Cylindrical";
92  message += " without [CenterLatitude] value. Keyword does not exist";
93  message += " in labels and defaults are not allowed.";
94  throw IException(IException::Unknown, message, _FILEINFO_);
95  }
96  }
97 
98  // Get the center longitude, convert to radians, adjust for longitude
99  // direction
100  m_centerLongitude = mapGroup["CenterLongitude"];
101  m_centerLongitude *= PI / 180.0;
103 
104  // Get the center latitude, the radius at the clat, and convert to radians
105  m_centerLatitude = mapGroup["CenterLatitude"];
107  m_centerLatitude *= PI / 180.0;
108 
109  // This keyword is just for user's information, and was put in for Hirise
110  if (!mapGroup.hasKeyword("CenterLatitudeRadius")) {
111  mapGroup += PvlKeyword("CenterLatitudeRadius");
112  }
113 
114  mapGroup["CenterLatitudeRadius"] = toString(m_clatRadius);
115 
116  // Compute cos of the center latitude and make sure it is valid as
117  // we will be dividing with it later on
119  if (fabs(m_cosCenterLatitude) < DBL_EPSILON) {
120  QString message = "Keyword value for CenterLatitude is "
121  "too close to the pole";
122  throw IException(IException::Io, message, _FILEINFO_);
123  }
124  }
125  catch(IException &e) {
126  QString message = "Invalid label group [Mapping]";
127  throw IException(e, IException::Io, message, _FILEINFO_);
128  }
129  }
130 
133  }
134 
144  if (!Projection::operator==(proj)) return false;
145  // dont do the below it is a recusive plunge
146  // if (Projection::operator!=(proj)) return false;
147  Equirectangular *equi = (Equirectangular *) &proj;
148  if (equi->m_centerLongitude != m_centerLongitude) return false;
149  if (equi->m_centerLatitude != m_centerLatitude) return false;
150  return true;
151  }
152 
158  QString Equirectangular::Name() const {
159  return "Equirectangular";
160  }
161 
167  QString Equirectangular::Version() const {
168  return "1.0";
169  }
170 
178  return m_centerLatitude * 180.0 / PI;
179  }
180 
187  return true;
188  }
189 
201  bool Equirectangular::SetGround(const double lat, const double lon) {
202  // Convert to radians
203  m_latitude = lat;
204  m_longitude = lon;
205  double latRadians = lat * PI / 180.0;
206  double lonRadians = lon * PI / 180.0;
207  if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
208 
209  // Compute the coordinate
210  double deltaLon = (lonRadians - m_centerLongitude);
211  double x = m_clatRadius * m_cosCenterLatitude * deltaLon;
212  double y = m_clatRadius * latRadians;
213  SetComputedXY(x, y);
214  m_good = true;
215  return m_good;
216  }
217 
231  bool Equirectangular::SetCoordinate(const double x, const double y) {
232  // Save the coordinate
233  SetXY(x, y);
234 
235  // Compute latitude and make sure it is not above 90
237  if ((fabs(m_latitude) - HALFPI) > DBL_EPSILON) {
238  m_good = false;
239  return m_good;
240  }
241 
242  // Compute longitude
245 
246  // Convert to degrees
247  m_latitude *= 180.0 / PI;
248  m_longitude *= 180.0 / PI;
249 
250  // Cleanup the longitude
252  // Do these if the projection is circular
253  // m_longitude = To360Domain (m_longitude);
254  // if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude);
255 
256  m_good = true;
257  return m_good;
258  }
259 
283  bool Equirectangular::XYRange(double &minX, double &maxX,
284  double &minY, double &maxY) {
285  // Check the corners of the lat/lon range
290 
291  // Make sure everything is ordered
292  if (m_minimumX >= m_maximumX) return false;
293  if (m_minimumY >= m_maximumY) return false;
294 
295  // Return X/Y min/maxs
296  minX = m_minimumX;
297  maxX = m_maximumX;
298  minY = m_minimumY;
299  maxY = m_maximumY;
300  return true;
301  }
302 
310  PvlGroup mapping = TProjection::Mapping();
311 
312  mapping += m_mappingGrp["CenterLatitude"];
313  mapping += m_mappingGrp["CenterLongitude"];
314 
315  return mapping;
316  }
317 
326 
327  mapping += m_mappingGrp["CenterLatitude"];
328 
329  return mapping;
330  }
331 
340 
341  mapping += m_mappingGrp["CenterLongitude"];
342 
343  return mapping;
344  }
345 
346 }
347 
361  bool allowDefaults) {
362  return new Isis::Equirectangular(lab, allowDefaults);
363 }
364