USGS

Isis 3.0 Object Programmers' Reference

Home

Sinusoidal.cpp
Go to the documentation of this file.
1 
23 #include "Sinusoidal.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 {
37 
54  Sinusoidal::Sinusoidal(Pvl &label, bool allowDefaults) :
55  TProjection::TProjection(label) {
56  try {
57  // Try to read the mapping group
58  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
59 
60  // Compute and write the default center longitude if allowed and
61  // necessary
62  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
63  double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
64  mapGroup += PvlKeyword("CenterLongitude", toString(lon));
65  }
66 
67  // Get the center longitude
68  m_centerLongitude = mapGroup["CenterLongitude"];
69 
70  // convert to radians, adjust for longitude direction
71  m_centerLongitude *= PI / 180.0;
73  }
74  catch(IException &e) {
75  QString message = "Invalid label group [Mapping]";
76  throw IException(e, IException::Io, message, _FILEINFO_);
77  }
78  }
79 
82  }
83 
92  bool Sinusoidal::operator== (const Projection &proj) {
93  if (!TProjection::operator==(proj)) return false;
94  // dont do the below it is a recusive plunge
95  // if (TProjection::operator!=(proj)) return false;
96  Sinusoidal *sinu = (Sinusoidal *) &proj;
97  if (sinu->m_centerLongitude != m_centerLongitude) return false;
98  return true;
99  }
100 
106  QString Sinusoidal::Name() const {
107  return "Sinusoidal";
108  }
109 
116  QString Sinusoidal::Version() const {
117  return "1.0";
118  }
119 
132  bool Sinusoidal::SetGround(const double lat, const double lon) {
133  // Convert to radians
134  m_latitude = lat;
135  m_longitude = lon;
136  double latRadians = lat * PI / 180.0;
137  double lonRadians = lon * PI / 180.0;
138  if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
139 
140  // Compute the coordinate
141  double deltaLon = (lonRadians - m_centerLongitude);
142  double x = m_equatorialRadius * deltaLon * cos(latRadians);
143  double y = m_equatorialRadius * latRadians;
144  SetComputedXY(x, y);
145  m_good = true;
146  return m_good;
147  }
148 
162  bool Sinusoidal::SetCoordinate(const double x, const double y) {
163  // Save the coordinate
164  SetXY(x, y);
165 
166  // Compute latitude and make sure it is not above 90
168  if (fabs(m_latitude) > HALFPI) {
169  if (fabs(HALFPI - fabs(m_latitude)) > DBL_EPSILON) {
170  m_good = false;
171  return m_good;
172  }
173  else if (m_latitude < 0.0) {
174  m_latitude = -HALFPI;
175  }
176  else {
177  m_latitude = HALFPI;
178  }
179  }
180 
181  // Compute longitude
182  double coslat = cos(m_latitude);
183  if (coslat <= DBL_EPSILON) {
185  }
186  else {
188  }
189 
190  // Convert to degrees
191  m_latitude *= 180.0 / PI;
192  m_longitude *= 180.0 / PI;
193 
194  // Cleanup the longitude
196  // These need to be done for circular type projections
197  // m_longitude = To360Domain (m_longitude);
198  // if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude);
199 
200  // Our double precision is not good once we pass a certain magnitude of
201  // longitude. Prevent failures down the road by failing now.
202  m_good = (fabs(m_longitude) < 1E10);
203 
204  return m_good;
205  }
206 
230  bool Sinusoidal::XYRange(double &minX, double &maxX,
231  double &minY, double &maxY) {
232  // Check the corners of the lat/lon range
237 
238  // If the latitude crosses the equator check there
239  if ((m_minimumLatitude < 0.0) && (m_maximumLatitude > 0.0)) {
242  }
243 
244  // Make sure everything is ordered
245  if (m_minimumX >= m_maximumX) return false;
246  if (m_minimumY >= m_maximumY) return false;
247 
248  // Return X/Y min/maxs
249  minX = m_minimumX;
250  maxX = m_maximumX;
251  minY = m_minimumY;
252  maxY = m_maximumY;
253  return true;
254  }
255 
256 
263  PvlGroup mapping = TProjection::Mapping();
264 
265  mapping += m_mappingGrp["CenterLongitude"];
266 
267  return mapping;
268  }
269 
277 
278  return mapping;
279  }
280 
288 
289  mapping += m_mappingGrp["CenterLongitude"];
290 
291  return mapping;
292  }
293 
294 } // end namespace isis
295 
309  bool allowDefaults) {
310  return new Isis::Sinusoidal(lab, allowDefaults);
311 }