Isis 3 Programmer Reference
Mollweide.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Mollweide.h"
8
9
10#include <cfloat>
11#include <cmath>
12#include <iomanip>
13
14#include "Constants.h"
15#include "IException.h"
16#include "TProjection.h"
17#include "Pvl.h"
18#include "PvlGroup.h"
19#include "PvlKeyword.h"
20
21using namespace std;
22
23
24namespace Isis {
25
26
44 Mollweide::Mollweide(Pvl &label, bool allowDefaults) :
45 TProjection::TProjection(label) {
46 try {
47 // Try to read the mapping group
48 PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
49
50 // Compute and write the default center longitude if allowed and
51 // necessary
52 if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
53 double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
54 mapGroup += PvlKeyword("CenterLongitude", toString(lon));
55 }
56
57 // Get the center longitude
58 m_centerLongitude = mapGroup["CenterLongitude"];
59
60 // convert to radians, adjust for longitude direction
61 m_centerLongitude *= PI / 180.0;
63 }
64 catch(IException &e) {
65 QString message = "Invalid label group [Mapping]";
66 throw IException(e, IException::Io, message, _FILEINFO_);
67 }
68 }
69
73
74
84 if (!TProjection::operator==(proj)) return false;
85 // dont do the below it is a recursive plunge
86 // if (TProjection::operator!=(proj)) return false;
87 Mollweide *moll = (Mollweide *) &proj;
88 if (moll->m_centerLongitude != m_centerLongitude) return false;
89 return true;
90 }
91
92
98 QString Mollweide::Name() const {
99 return "Mollweide";
100 }
101
102
107 QString Mollweide::Version() const {
108 return "1.0";
109 }
110
111
131 bool Mollweide::newton_rapheson(double phi, double &result) {
132
133 double dtheta = 1.0;
134 int niter = 0;
135 double theta[2];
136
137 theta[0] = asin(2*phi/PI);
138 theta[1]=0.0;
139
140 //If this condition is too strict, a larger epsilon value than DBL_EPSILON
141 //can be used to decrease the number of iterations.
142 while (dtheta > DBL_EPSILON) {
143
144 theta[1] = theta[0] - (2*theta[0]+sin(2*theta[0]) -(Isis::PI)*sin(phi))/(2+2*cos(theta[0]));
145 dtheta = fabs(theta[1]-theta[0]);
146 theta[0] = theta[1];
147 niter++;
148
149 if (niter > 15000000) {
150 //cout << setprecision(10) << phi*(180/PI) << "," << niter << endl;
151 return false;
152 }
153 }
154 result = theta[1];
155
156
157 //cout << setprecision(10) << phi*(180/PI) << "," << niter << endl;
158 return true;
159 }
160
161
176 bool Mollweide::SetGround(const double lat, const double lon) {
177
178 // Convert to radians
179 m_latitude = lat;
180 m_longitude = lon;
181 double theta;
182 double latRadians = lat * PI / 180.0;
183 double lonRadians = lon * PI / 180.0;
184 if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
185
186 // Compute the coordinate
187 double deltaLon = lonRadians - m_centerLongitude;
188
189 if (newton_rapheson(latRadians,theta) ) {
190
191 double x = (2*sqrt(2)/PI )*m_equatorialRadius*(deltaLon)*cos(theta);
192 double y = sqrt(2)*m_equatorialRadius*sin(theta);
193
194 SetComputedXY(x, y);
195 m_good = true;
196 return m_good;
197 }
198 else {
199
200 m_good = false;
201 return m_good;
202 }
203 }
204
205
219 bool Mollweide::SetCoordinate(const double x, const double y) {
220 // Save the coordinate
221
222 SetXY(x, y);
223
224 double theta = asin(y/(m_equatorialRadius*sqrt(2)));
225
226 // Compute latitude and make sure it is not above 90
227 m_latitude = asin((2*theta+sin(2*theta))/(Isis::PI));
228
229 if (fabs(m_latitude) > HALFPI) {
230 if (fabs(HALFPI - fabs(m_latitude)) > DBL_EPSILON) {
231 m_good = false;
232 return m_good;
233 }
234 else if (m_latitude < 0.0) {
236 }
237 else {
239 }
240 }
241
242 // Compute longitude
243
244 double cosLat = cos(m_latitude);
245
246 if (cosLat <= DBL_EPSILON) {
248 }
249
250 else {
251 m_longitude = m_centerLongitude+(Isis::PI)*GetX()/(2*m_equatorialRadius*sqrt(2)*cos(theta));
252 }
253
254
255 // Convert to degrees
256 m_latitude *= 180.0 / PI;
257 m_longitude *= 180.0 / PI;
258
259 // Cleanup the longitude
261
262
263 // Our double precision is not good once we pass a certain magnitude of
264 // longitude. Prevent failures down the road by failing now.
265 m_good = (fabs(m_longitude) < 1E10);
266
267
268 return m_good;
269 }
270
271
297 bool Mollweide::XYRange(double &minX, double &maxX,
298 double &minY, double &maxY) {
299 // Check the corners of the lat/lon range
304
305 // If the latitude crosses the equator check there
306 if ((m_minimumLatitude < 0.0) && (m_maximumLatitude > 0.0)) {
309 }
310
311 // Make sure everything is ordered
312 if (m_minimumX >= m_maximumX) return false;
313 if (m_minimumY >= m_maximumY) return false;
314
315 // Return X/Y min/maxs
316 minX = m_minimumX;
317 maxX = m_maximumX;
318 minY = m_minimumY;
319 maxY = m_maximumY;
320 return true;
321 }
322
323
329 PvlGroup Mollweide::Mapping() {
330 PvlGroup mapping = TProjection::Mapping();
331
332 mapping += m_mappingGrp["CenterLongitude"];
333
334 return mapping;
335 }
336
337
343 PvlGroup Mollweide::MappingLatitudes() {
344 PvlGroup mapping = TProjection::MappingLatitudes();
345
346 return mapping;
347 }
348
349
356 PvlGroup mapping = TProjection::MappingLongitudes();
357
358 mapping += m_mappingGrp["CenterLongitude"];
359
360 return mapping;
361 }
362
363} // end namespace isis
364
365
378extern "C" Isis::TProjection *MollweidePlugin(Isis::Pvl &lab,
379 bool allowDefaults) {
380 return new Isis::Mollweide(lab, allowDefaults);
381}
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
Mollweide Map Projection.
Definition Mollweide.h:50
QString Version() const
Returns the version of the map projection.
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition Mollweide.cpp:83
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
Mollweide(Pvl &label, bool allowDefaults=false)
Constructs a Mollweide object.
Definition Mollweide.cpp:44
double m_centerLongitude
The center longitude for the map projection.
Definition Mollweide.h:69
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...
~Mollweide()
Destroys the Mollweide object.
Definition Mollweide.cpp:71
bool SetGround(const double lat, const double lon)
This method is used to set the latitude/longitude (assumed to be of the correct LatitudeType,...
PvlGroup Mapping()
This function returns the keywords that this projection uses.
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
QString Name() const
Returns the name of the map projection, "Mollweide".
Definition Mollweide.cpp:98
Base class for Map Projections.
Definition Projection.h:155
double m_maximumX
See minimumX description.
Definition Projection.h:326
double GetX() const
Calculates the unrotated form of current x value.
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 TProjections.
double m_longitude
This contains the currently set longitude value.
double m_minimumLatitude
Contains the minimum latitude for the entire ground range.
double m_maximumLongitude
Contains the maximum longitude for the entire ground range.
double m_equatorialRadius
Polar radius of the target.
LongitudeDirection m_longitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
void XYRangeCheck(const double latitude, const double longitude)
This convience function is established to assist in the development of the XYRange virtual method.
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
double m_minimumLongitude
Contains the minimum longitude for the entire ground range.
@ PositiveWest
Longitude values increase in the westerly direction.
double m_maximumLatitude
Contains the maximum latitude for the entire ground range.
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
double m_latitude
This contains the currently set latitude value.
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 HALFPI
The mathematical constant PI/2.
Definition Constants.h:41
const double PI
The mathematical constant PI.
Definition Constants.h:40
Namespace for the standard library.