USGS

Isis 3.0 Object Programmers' Reference

Home

Planar.cpp
Go to the documentation of this file.
1 
23 #include "Planar.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 
35 using namespace std;
36 namespace Isis {
55  Planar::Planar(Pvl &label, bool allowDefaults) :
57 
58  // latitude in ring plane is always zero
59  m_ringRadius = 0.0;
60 
61  try {
62  // Try to read the mapping group
63  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
64 
65  // Compute and write the default center longitude if allowed and
66  // necessary
67  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingLongitude"))) {
68  double azimuth = (m_minimumRingLongitude + m_maximumRingLongitude) / 2.0;
69  mapGroup += PvlKeyword("CenterRingLongitude", toString(azimuth));
70  }
71 
72  // Compute and write the default center radius if allowed and
73  // necessary
74  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingRadius"))) {
75  double radius = (m_minimumRingRadius + m_maximumRingRadius) / 2.0;
76  mapGroup += PvlKeyword("CenterRingRadius", toString(radius));
77  }
78 
79  // Get the center longitude & radius
80  m_centerRingLongitude = mapGroup["CenterRingLongitude"];
81  m_centerRingRadius = mapGroup["CenterRingRadius"];
82 
83  // convert to radians, adjust for azimuth direction
86  }
87  catch(IException &e) {
88  string message = "Invalid label group [Mapping]";
89  throw IException(e, IException::Io, message, _FILEINFO_);
90  }
91  }
92 
95  }
96 
105  bool Planar::operator== (const Projection &proj) {
106  if (!RingPlaneProjection::operator==(proj)) return false;
107  // dont do the below it is a recursive plunge
108  // if (Projection::operator!=(proj)) return false;
109  Planar *planar = (Planar *) &proj;
110  if ((planar->m_centerRingLongitude != m_centerRingLongitude) ||
111  (planar->m_centerRingRadius != m_centerRingRadius)) return false;
112  return true;
113  }
114 
120  QString Planar::Name() const {
121  return "Planar";
122  }
123 
138  return m_centerRingRadius;
139  // return 60268000.0;
140  }
141 
142 
149  double dir = 1.0;
150  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
151  return m_centerRingLongitude * RAD2DEG * dir;;
152  }
153 
154 
160  double Planar::CenterRingRadius() const {
161  return m_centerRingRadius;
162  }
163 
164 
171  QString Planar::Version() const {
172  return "1.0";
173  }
174 
175 
188  bool Planar::SetGround(const double ringRadius, const double ringLongitude) {
189 
190  // Convert azimuth to radians & adjust
191  m_ringLongitude = ringLongitude;
192  double azRadians = ringLongitude * DEG2RAD;
193  if (m_ringLongitudeDirection == Clockwise) azRadians *= -1.0;
194 
195  // Check to make sure radius is valid
196  if (ringRadius < 0) {
197  m_good = false;
198  // cout << "Unable to set radius. The given radius value ["
199  // << IString(ringRadius) << "] is invalid." << endl;
200  // throw IException(IException::Unknown,
201  // "Unable to set radius. The given radius value ["
202  // + IString(ringRadius) + "] is invalid.",
203  // _FILEINFO_);
204  return m_good;
205  }
206  m_ringRadius = ringRadius;
207 
208 
209  // Compute helper variables
210  double deltaAz = (azRadians - m_centerRingLongitude);
211 // double coslon = cos(deltaLon);
212 
213  // Lat/Lon cannot be projected
214 // double g = m_sinph0 * sinphi + m_cosph0 * cosphi * coslon;
215 // if ((g <= 0.0) && (fabs(g) > 1.0e-10)) {
216 // m_good = false;
217 // return m_good;
218 // }
219 
220  // Compute the coordinates
221  double x = ringRadius * cos(deltaAz);
222  double y = ringRadius * sin(deltaAz);
223 
224  SetComputedXY(x, y);
225  m_good = true;
226  return m_good;
227  }
228 
242  bool Planar::SetCoordinate(const double x, const double y) {
243 
244  // Save the coordinate
245  SetXY(x, y);
246 
247  // compute radius and azimuth in degrees
248  m_ringRadius = sqrt(x*x + y*y);
249 
250  if (y == 0.0)
252  else
253  m_ringLongitude = atan2(y,x) + m_centerRingLongitude;
254 
256 
257  // if ( m_ringLongitude < 0.0 )
258  // m_ringLongitude += 360.0;
259 
260  // Cleanup the azimuth
262 
263  // These need to be done for circular type projections
265 
266  if (m_ringLongitudeDomain == 180)
268 
269  m_good = true;
270  return m_good;
271  }
272 
295 /*
296  bool Planar::XYRange(double &minX, double &maxX,
297  double &minY, double &maxY) {
298  double lat, lon;
299 
300  // Check the corners of the lat/lon range
301  XYRangeCheck(m_minimumLatitude, m_minimumLongitude);
302  XYRangeCheck(m_maximumLatitude, m_minimumLongitude);
303  XYRangeCheck(m_minimumLatitude, m_maximumLongitude);
304  XYRangeCheck(m_maximumLatitude, m_maximumLongitude);
305 
306 //cout << " ************ WALK LATITUDE ******************\n";
307 //cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
308  // Walk top and bottom edges
309  for (lat = m_minimumLatitude; lat <= m_maximumLatitude; lat += 0.01) {
310 //cout << "WALKED A STEP - lat: " << lat << "\n";
311  lat = lat;
312  lon = m_minimumLongitude;
313  XYRangeCheck(lat, lon);
314 
315  lat = lat;
316  lon = m_maximumLongitude;
317  XYRangeCheck(lat, lon);
318 //cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
319  }
320 
321 //cout << " ************ WALK LONGITUDE ******************\n";
322  // Walk left and right edges
323  for (lon = m_minimumLongitude; lon <= m_maximumLongitude; lon += 0.01) {
324  lat = m_minimumLatitude;
325  lon = lon;
326  XYRangeCheck(lat, lon);
327 
328  lat = m_maximumLatitude;
329  lon = lon;
330  XYRangeCheck(lat, lon);
331  }
332 
333  // Walk the limb
334  for (double angle = 0.0; angle <= 360.0; angle += 0.01) {
335  double x = m_equatorialRadius * cos(angle * PI / 180.0);
336  double y = m_equatorialRadius * sin(angle * PI / 180.0);
337  if (SetCoordinate(x, y) == 0) {
338  if (m_latitude > m_maximumLatitude) {
339  continue;
340  }
341  if (m_longitude > m_maximumLongitude) {
342  continue;
343  }
344  if (m_latitude < m_minimumLatitude) {
345  continue;
346  }
347  if (m_longitude < m_minimumLongitude) {
348  continue;
349  }
350 
351  if (m_minimumX > x) m_minimumX = x;
352  if (m_maximumX < x) m_maximumX = x;
353  if (m_minimumY > y) m_minimumY = y;
354  if (m_maximumY < y) m_maximumY = y;
355  XYRangeCheck(m_latitude, m_longitude);
356  }
357  }
358 
359  // Make sure everything is ordered
360  if (m_minimumX >= m_maximumX) return false;
361  if (m_minimumY >= m_maximumY) return false;
362 
363  // Return X/Y min/maxs
364  minX = m_minimumX;
365  maxX = m_maximumX;
366  minY = m_minimumY;
367  maxY = m_maximumY;
368  return true;
369  }
370 */
371 
372 
395  bool Planar::XYRange(double &minX, double &maxX,
396  double &minY, double &maxY) {
397 
398  double rad, az;
399 
400  // Check the corners of the rad/az range
405 
406 //cout << " ************ WALK RADIUS ******************\n";
407 //cout << "MIN RAD: " << m_minimumRingRadius << " MAX LAT: " << m_maximumRingRadius << "\n";
408  // Walk top and bottom edges in half pixel increments
409  double radiusInc = 2. * (m_maximumRingRadius - m_minimumRingRadius) / PixelResolution();
410 
411  for (rad = m_minimumRingRadius; rad <= m_maximumRingRadius; rad += radiusInc) {
412 //cout << "WALKED A STEP - rad: " << rad << "\n";
413  rad = rad;
415  XYRangeCheck(rad, az);
416 
417  rad = rad;
419  XYRangeCheck(rad, az);
420 //cout << "MIN RAD: " << m_minimumRingRadius << " MAX RAD: " << m_maximumRingRadius << "\n";
421  }
422 
423 //cout << " ************ WALK AZIMUTH ******************\n";
424  // Walk left and right edges
425  for (az = m_minimumRingLongitude; az <= m_maximumRingLongitude; az += 0.01) {
426  rad = m_minimumRingRadius;
427  az = az;
428  XYRangeCheck(rad, az);
429 
430  rad = m_maximumRingRadius;
431  az = az;
432  XYRangeCheck(rad, az);
433  }
434 
435  // Walk the limb
436 /*
437  for (double angle = 0.0; angle <= 360.0; angle += 0.01) {
438  double x = m_equatorialRadius * cos(angle * PI / 180.0);
439  double y = m_equatorialRadius * sin(angle * PI / 180.0);
440  if (SetCoordinate(x, y) == 0) {
441  if (m_latitude > m_maximumLatitude) {
442  continue;
443  }
444  if (m_longitude > m_maximumRingLongitude) {
445  continue;
446  }
447  if (m_latitude < m_minimumLatitude) {
448  continue;
449  }
450  if (m_longitude < m_minimumRingLongitude) {
451  continue;
452  }
453 
454  if (m_minimumX > x) m_minimumX = x;
455  if (m_maximumX < x) m_maximumX = x;
456  if (m_minimumY > y) m_minimumY = y;
457  if (m_maximumY < y) m_maximumY = y;
458  XYRangeCheck(m_latitude, m_longitude);
459  }
460  } */
461 
462  // Make sure everything is ordered
463  if (m_minimumX >= m_maximumX) return false;
464  if (m_minimumY >= m_maximumY) return false;
465 
466  // Return X/Y min/maxs
467  // m_maximumX = m_maximumRingRadius*cos(m_maximumRingLongitude);
468  // m_minimumX = -m_maximumX;
469  // m_maximumY = m_maximumRingRadius*sin(m_maximumRingLongitude);
470  // m_minimumY = -m_maximumY;
471 
472  minX = m_minimumX;
473  maxX = m_maximumX;
474  minY = m_minimumY;
475  maxY = m_maximumY;
476 
477  return true;
478  }
479 
480 
488 
489  mapping += PvlKeyword("CenterRingRadius", toString(m_centerRingRadius));
490  double dir = 1.0;
491  if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
492  double lonDegrees = m_centerRingLongitude*RAD2DEG*dir;
493  mapping += PvlKeyword("CenterRingLongitude", toString(lonDegrees));
494 
495  return mapping;
496  }
497 
505 
506  if (HasGroundRange())
507  mapping += m_mappingGrp["CenterRingRadius"];
508 
509  return mapping;
510  }
511 
512 
520 
521  if (HasGroundRange())
522  mapping += m_mappingGrp["CenterRingLongitude"];
523 
524  return mapping;
525  }
526 
527 } // end namespace isis
528 
543  bool allowDefaults) {
544  return new Isis::Planar(lab, allowDefaults);
545 }
546