Isis 3 Programmer Reference
Planar.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Planar.h"
8
9#include <cmath>
10#include <cfloat>
11
12#include "Constants.h"
13#include "IException.h"
14#include "Pvl.h"
15#include "PvlGroup.h"
16#include "PvlKeyword.h"
17#include "RingPlaneProjection.h"
18
19using namespace std;
20namespace Isis {
39 Planar::Planar(Pvl &label, bool allowDefaults) :
41
42 // latitude in ring plane is always zero
43 m_ringRadius = 0.0;
44
45 try {
46 // Try to read the mapping group
47 PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
48
49 // Compute and write the default center longitude if allowed and
50 // necessary
51 if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingLongitude"))) {
52 double azimuth = (m_minimumRingLongitude + m_maximumRingLongitude) / 2.0;
53 mapGroup += PvlKeyword("CenterRingLongitude", toString(azimuth));
54 }
55
56 // Compute and write the default center radius if allowed and
57 // necessary
58 if ((allowDefaults) && (!mapGroup.hasKeyword("CenterRingRadius"))) {
59 double radius = (m_minimumRingRadius + m_maximumRingRadius) / 2.0;
60 mapGroup += PvlKeyword("CenterRingRadius", toString(radius));
61 }
62
63 // Get the center longitude & radius
64 m_centerRingLongitude = mapGroup["CenterRingLongitude"];
65 m_centerRingRadius = mapGroup["CenterRingRadius"];
66
67 // convert to radians, adjust for azimuth direction
70 }
71 catch(IException &e) {
72 string message = "Invalid label group [Mapping]";
73 throw IException(e, IException::Io, message, _FILEINFO_);
74 }
75 }
76
80
89 bool Planar::operator== (const Projection &proj) {
90 if (!RingPlaneProjection::operator==(proj)) return false;
91 // dont do the below it is a recursive plunge
92 // if (Projection::operator!=(proj)) return false;
93 Planar *planar = (Planar *) &proj;
94 if ((planar->m_centerRingLongitude != m_centerRingLongitude) ||
95 (planar->m_centerRingRadius != m_centerRingRadius)) return false;
96 return true;
97 }
98
104 QString Planar::Name() const {
105 return "Planar";
106 }
107
122 return m_centerRingRadius;
123 // return 60268000.0;
124 }
125
126
133 double dir = 1.0;
134 if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
135 return m_centerRingLongitude * RAD2DEG * dir;;
136 }
137
138
145 return m_centerRingRadius;
146 }
147
148
155 QString Planar::Version() const {
156 return "1.0";
157 }
158
159
172 bool Planar::SetGround(const double ringRadius, const double ringLongitude) {
173
174 // Convert azimuth to radians & adjust
175 m_ringLongitude = ringLongitude;
176 double azRadians = ringLongitude * DEG2RAD;
177 if (m_ringLongitudeDirection == Clockwise) azRadians *= -1.0;
178
179 // Check to make sure radius is valid
180 if (ringRadius < 0) {
181 m_good = false;
182 // cout << "Unable to set radius. The given radius value ["
183 // << IString(ringRadius) << "] is invalid." << endl;
184 // throw IException(IException::Unknown,
185 // "Unable to set radius. The given radius value ["
186 // + IString(ringRadius) + "] is invalid.",
187 // _FILEINFO_);
188 return m_good;
189 }
190 m_ringRadius = ringRadius;
191
192
193 // Compute helper variables
194 double deltaAz = (azRadians - m_centerRingLongitude);
195// double coslon = cos(deltaLon);
196
197 // Lat/Lon cannot be projected
198// double g = m_sinph0 * sinphi + m_cosph0 * cosphi * coslon;
199// if ((g <= 0.0) && (fabs(g) > 1.0e-10)) {
200// m_good = false;
201// return m_good;
202// }
203
204 // Compute the coordinates
205 double x = ringRadius * cos(deltaAz);
206 double y = ringRadius * sin(deltaAz);
207
208 SetComputedXY(x, y);
209 m_good = true;
210 return m_good;
211 }
212
226 bool Planar::SetCoordinate(const double x, const double y) {
227
228 // Save the coordinate
229 SetXY(x, y);
230
231 // compute radius and azimuth in degrees
232 m_ringRadius = sqrt(x*x + y*y);
233
234 if (y == 0.0)
236 else
238
240
241 // if ( m_ringLongitude < 0.0 )
242 // m_ringLongitude += 360.0;
243
244 // Cleanup the azimuth
246
247 // These need to be done for circular type projections
249
250 if (m_ringLongitudeDomain == 180)
252
253 m_good = true;
254 return m_good;
255 }
256
279/*
280 bool Planar::XYRange(double &minX, double &maxX,
281 double &minY, double &maxY) {
282 double lat, lon;
283
284 // Check the corners of the lat/lon range
285 XYRangeCheck(m_minimumLatitude, m_minimumLongitude);
286 XYRangeCheck(m_maximumLatitude, m_minimumLongitude);
287 XYRangeCheck(m_minimumLatitude, m_maximumLongitude);
288 XYRangeCheck(m_maximumLatitude, m_maximumLongitude);
289
290//cout << " ************ WALK LATITUDE ******************\n";
291//cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
292 // Walk top and bottom edges
293 for (lat = m_minimumLatitude; lat <= m_maximumLatitude; lat += 0.01) {
294//cout << "WALKED A STEP - lat: " << lat << "\n";
295 lat = lat;
296 lon = m_minimumLongitude;
297 XYRangeCheck(lat, lon);
298
299 lat = lat;
300 lon = m_maximumLongitude;
301 XYRangeCheck(lat, lon);
302//cout << "MIN LAT: " << m_minimumLatitude << " MAX LAT: " << m_maximumLatitude << "\n";
303 }
304
305//cout << " ************ WALK LONGITUDE ******************\n";
306 // Walk left and right edges
307 for (lon = m_minimumLongitude; lon <= m_maximumLongitude; lon += 0.01) {
308 lat = m_minimumLatitude;
309 lon = lon;
310 XYRangeCheck(lat, lon);
311
312 lat = m_maximumLatitude;
313 lon = lon;
314 XYRangeCheck(lat, lon);
315 }
316
317 // Walk the limb
318 for (double angle = 0.0; angle <= 360.0; angle += 0.01) {
319 double x = m_equatorialRadius * cos(angle * PI / 180.0);
320 double y = m_equatorialRadius * sin(angle * PI / 180.0);
321 if (SetCoordinate(x, y) == 0) {
322 if (m_latitude > m_maximumLatitude) {
323 continue;
324 }
325 if (m_longitude > m_maximumLongitude) {
326 continue;
327 }
328 if (m_latitude < m_minimumLatitude) {
329 continue;
330 }
331 if (m_longitude < m_minimumLongitude) {
332 continue;
333 }
334
335 if (m_minimumX > x) m_minimumX = x;
336 if (m_maximumX < x) m_maximumX = x;
337 if (m_minimumY > y) m_minimumY = y;
338 if (m_maximumY < y) m_maximumY = y;
339 XYRangeCheck(m_latitude, m_longitude);
340 }
341 }
342
343 // Make sure everything is ordered
344 if (m_minimumX >= m_maximumX) return false;
345 if (m_minimumY >= m_maximumY) return false;
346
347 // Return X/Y min/maxs
348 minX = m_minimumX;
349 maxX = m_maximumX;
350 minY = m_minimumY;
351 maxY = m_maximumY;
352 return true;
353 }
354*/
355
356
379 bool Planar::XYRange(double &minX, double &maxX,
380 double &minY, double &maxY) {
381
382 double rad, az;
383
384 // Check the corners of the rad/az range
389
390 // Walk top and bottom edges in half pixel increments
391 double radiusInc = 2. * (m_maximumRingRadius - m_minimumRingRadius) / PixelResolution();
392
393 for (rad = m_minimumRingRadius; rad <= m_maximumRingRadius; rad += radiusInc) {
395 XYRangeCheck(rad, az);
396
398 XYRangeCheck(rad, az);
399 }
400
401 // Walk left and right edges
402 for (az = m_minimumRingLongitude; az <= m_maximumRingLongitude; az += 0.01) {
404 XYRangeCheck(rad, az);
405
407 XYRangeCheck(rad, az);
408 }
409
410 // Make sure everything is ordered
411 if (m_minimumX >= m_maximumX) return false;
412 if (m_minimumY >= m_maximumY) return false;
413
414 // Return X/Y min/maxs
415 // m_maximumX = m_maximumRingRadius*cos(m_maximumRingLongitude);
416 // m_minimumX = -m_maximumX;
417 // m_maximumY = m_maximumRingRadius*sin(m_maximumRingLongitude);
418 // m_minimumY = -m_maximumY;
419
420 minX = m_minimumX;
421 maxX = m_maximumX;
422 minY = m_minimumY;
423 maxY = m_maximumY;
424
425 return true;
426 }
427
428
436
437 mapping += PvlKeyword("CenterRingRadius", toString(m_centerRingRadius));
438 double dir = 1.0;
439 if (m_ringLongitudeDirection == Clockwise) dir = -1.0;
440 double lonDegrees = m_centerRingLongitude*RAD2DEG*dir;
441 mapping += PvlKeyword("CenterRingLongitude", toString(lonDegrees));
442
443 return mapping;
444 }
445
453
454 if (HasGroundRange())
455 mapping += m_mappingGrp["CenterRingRadius"];
456
457 return mapping;
458 }
459
460
468
469 if (HasGroundRange())
470 mapping += m_mappingGrp["CenterRingLongitude"];
471
472 return mapping;
473 }
474
475} // end namespace isis
476
490extern "C" Isis::Projection *PlanarPlugin(Isis::Pvl &lab,
491 bool allowDefaults) {
492 return new Isis::Planar(lab, allowDefaults);
493}
Isis exception class.
Definition IException.h:91
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition IException.h:155
Planar Map Projection.
Definition Planar.h:40
Planar(Pvl &label, bool allowDefaults=false)
TODO: correct documentation in this file.
Definition Planar.cpp:39
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...
Definition Planar.cpp:379
PvlGroup MappingRingLongitudes()
This function returns the azimuth keywords that this projection uses.
Definition Planar.cpp:466
double CenterRingRadius() const
Returns the center radius, in meters.
Definition Planar.cpp:144
bool SetGround(const double ringRadius, const double ringLongitude)
This method is used to set the radius/azimuth (assumed to be of the correct RingLongitudeDirection,...
Definition Planar.cpp:172
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition Planar.cpp:434
double m_centerRingRadius
The center radius for the map projection.
Definition Planar.h:65
QString Version() const
Returns the version of the map projection.
Definition Planar.cpp:155
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition Planar.cpp:89
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition Planar.cpp:226
double TrueScaleRingRadius() const
Returns the center radius, in meters.
Definition Planar.cpp:121
double m_centerRingLongitude
The center longitude for the map projection.
Definition Planar.h:64
~Planar()
Destroys the Planar object.
Definition Planar.cpp:78
double CenterRingLongitude() const
Returns the center longitude, in degrees.
Definition Planar.cpp:132
QString Name() const
Returns the name of the map projection, "Planar".
Definition Planar.cpp:104
PvlGroup MappingRingRadii()
This function returns the radius keywords that this projection uses.
Definition Planar.cpp:451
Base class for Map Projections.
Definition Projection.h:155
double m_maximumX
See minimumX description.
Definition Projection.h:326
virtual bool HasGroundRange() const
This indicates if the longitude direction type is positive west (as opposed to postive east).
double PixelResolution() const
Returns the pixel resolution value from the PVL mapping group in meters/pixel.
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
Definition Projection.h:300
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
Definition Projection.h:317
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition Projection.h:329
double m_minimumY
See minimumX description.
Definition Projection.h:327
void SetXY(double x, double y)
This protected method is a helper for derived classes.
double m_maximumY
See minimumX description.
Definition Projection.h:328
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Contains multiple PvlContainers.
Definition PvlGroup.h:41
Container for cube-like labels.
Definition Pvl.h:119
A single keyword-value pair.
Definition PvlKeyword.h:87
@ Traverse
Search child objects.
Definition PvlObject.h:158
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition PvlObject.h:129
Base class for Map Projections of plane shapes.
double m_minimumRingLongitude
Contains the minimum longitude for the entire ground range.
static double To360Domain(const double lon)
This method converts an ring longitude into the 0 to 360 domain.
virtual PvlGroup MappingRingLongitudes()
This function returns the ring longitude keywords that this projection uses.
int m_ringLongitudeDomain
This integer is either 180 or 360 and is read from the labels.
virtual PvlGroup Mapping()
This method is used to find the XY range for oblique aspect projections (non-polar projections) by "w...
double m_maximumRingRadius
Contains the maximum ring radius for the entire ground range.
static double To180Domain(const double lon)
This method converts a ring longitude into the -180 to 180 domain.
double m_maximumRingLongitude
Contains the maximum longitude for the entire ground range.
void XYRangeCheck(const double ringRadius, const double ringLongitude)
This convience function is established to assist in the development of the XYRange virtual method.
double m_ringRadius
This contain a ring radius value in m.
virtual PvlGroup MappingRingRadii()
This function returns the ring radius keywords that this projection uses.
double m_ringLongitude
This contain a ring longitude value.
@ Clockwise
Ring longitude values increase in the clockwise direction.
RingLongitudeDirection m_ringLongitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
double m_minimumRingRadius
Contains the minimum ring radius for the entire ground range.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition IString.cpp:211
const double DEG2RAD
Multiplier for converting from degrees to radians.
Definition Constants.h:43
const double RAD2DEG
Multiplier for converting from radians to degrees.
Definition Constants.h:44
Namespace for the standard library.