USGS

Isis 3.0 Object Programmers' Reference

Home

LunarAzimuthalEqualArea.cpp
Go to the documentation of this file.
1 
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 
34 using namespace std;
35 namespace Isis {
46  LunarAzimuthalEqualArea::LunarAzimuthalEqualArea(
47  Pvl &label) : TProjection::TProjection(label) {
48  try {
49  // Try to read the mapping group
50  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
51 
52  // Get the max libration
53  m_maxLibration = mapGroup["MaximumLibration"];
54  m_maxLibration *= PI / 180.0;
55  }
56  catch(IException &e) {
57  QString message = "Invalid label group [Mapping]";
58  throw IException(IException::Unknown, message, _FILEINFO_);
59  }
60  }
61 
64  }
65 
75  if (!Projection::operator==(proj))
76  return false;
77  // dont use != (it is a recusive plunge)
78  // if (Projection::operator!=(proj)) return false;
79 
81  if (LKAEA->m_maxLibration != m_maxLibration)
82  return false;
83  return true;
84  }
85 
92  return "LunarAzimuthalEqualArea";
93  }
94 
102  return "0.1";
103  }
104 
117  bool LunarAzimuthalEqualArea::SetGround(const double lat,
118  const double lon) {
119  // Convert longitude to radians
120  m_longitude = lon;
121  double lonRadians = lon * Isis::PI / 180.0;
123  lonRadians *= -1.0;
124 
125  // Now convert latitude to radians... it must be planetographic
126  m_latitude = lat;
127  double latRadians = lat;
128  if (IsPlanetocentric())
129  latRadians = ToPlanetographic(latRadians);
130  latRadians *= Isis::PI / 180.0;
131 
132  double x, y;
133  if (lonRadians == 0.0 && latRadians == 0.0) {
134  x = 0.0;
135  y = 0.0;
136  SetComputedXY(x, y);
137  m_good = true;
138  return true;
139  }
140 
141  double E = acos(cos(latRadians) * cos(lonRadians));
142  double test = (sin(lonRadians) * cos(latRadians)) / sin(E);
143 
144  if (test > 1.0) test = 1.0;
145  else if (test < -1.0) test = -1.0;
146 
147  double D = HALFPI - asin(test);
148  if (latRadians < 0.0)
149  D = -D;
150 
151  double radius = m_equatorialRadius;
152  double PFAC = (HALFPI + m_maxLibration) / HALFPI;
153  double RP = radius * sin(E / PFAC);
154 
155  x = RP * cos(D);
156  y = RP * sin(D);
157 
158  SetComputedXY(x, y);
159  m_good = true;
160  return true;
161 
162  } // of SetGround
163 
164 
179  const double y) {
180  // Save the coordinate
181  SetXY(x, y);
182 
183  double RP = sqrt((x * x) + (y * y));
184 
185  double lat, lon;
186  if (y == 0.0 && x == 0.0) {
187  lat = 0.0;
188  lon = 0.0;
189  return true;
190  }
191 
192  double radius = m_equatorialRadius;
193 
194  double D = atan2(y, x);
195  double test = RP / radius;
196  if (abs(test) > 1.0) {
197  return false;
198  }
199 
200  double EPSILON = 0.0000000001;
201  double PFAC = (HALFPI + m_maxLibration) / HALFPI;
202  double E = PFAC * asin(RP / radius);
203 
204  lat = HALFPI - (acos(sin(D) * sin(E)));
205 
206  if (abs(HALFPI - abs(lat)) <= EPSILON) {
207  lon = 0.0;
208  }
209  else {
210  test = sin(E) * cos(D) / sin(HALFPI - lat);
211  if (test > 1.0) test = 1.0;
212  else if (test < -1.0) test = -1.0;
213 
214  lon = asin(test);
215  }
216 
217  if (E >= HALFPI) {
218  if (lon <= 0.0) lon = -PI - lon;
219  else lon = PI - lon;
220  }
221 
222  // Convert to degrees
223  m_latitude = lat * 180.0 / Isis::PI;
224  m_longitude = lon * 180.0 / Isis::PI;
225 
226  // Cleanup the latitude
227  if (IsPlanetocentric())
229 
230  m_good = true;
231  return m_good;
232  }
233 
234 
258  bool LunarAzimuthalEqualArea::XYRange(double &minX, double &maxX,
259  double &minY, double &maxY) {
260  // Check the corners of the lat/lon range
265 
266  // If the latitude range contains 0
267  if ((m_minimumLatitude < 0.0) && (m_maximumLatitude > 0.0)) {
270  }
271 
272  // If the longitude range contains 0
273  if ((m_minimumLongitude < 0.0) && (m_maximumLongitude > 0.0)) {
276  }
277 
278  // Make sure everything is ordered
279  if (m_minimumX >= m_maximumX) return false;
280  if (m_minimumY >= m_maximumY) return false;
281 
282  // Return X/Y min/maxs
283  minX = m_minimumX;
284  maxX = m_maximumX;
285  minY = m_minimumY;
286  maxY = m_maximumY;
287  return true;
288  }
289 
296  PvlGroup mapping = TProjection::Mapping();
297  mapping += m_mappingGrp["MaximumLibration"];
298  return mapping;
299  }
300 
301 } // end namespace isis
302 
316  bool allowDefaults) {
317  return new Isis::LunarAzimuthalEqualArea(lab);
318 }