Isis 3 Programmer Reference
Mercator.cpp
1
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "Mercator.h"
8
9#include <cmath>
10#include <cfloat>
11
12#include "IException.h"
13#include "Constants.h"
14#include "TProjection.h"
15#include "Pvl.h"
16#include "PvlGroup.h"
17#include "PvlKeyword.h"
18
19using namespace std;
20namespace Isis {
37 Mercator::Mercator(Pvl &label, bool allowDefaults) :
38 TProjection::TProjection(label) {
39 try {
40 // Try to read the mapping group
41 PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
42
43 // Compute and write the default center longitude if allowed and
44 // necessary
45 if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
46 double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
47 mapGroup += PvlKeyword("CenterLongitude", toString(lon));
48 }
49
50 // Compute and write the default center latitude if allowed and
51 // necessary
52 if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLatitude"))) {
53 double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
54 mapGroup += PvlKeyword("CenterLatitude", toString(lat));
55 }
56
57 // Get the center longitude & latitude
58 m_centerLongitude = mapGroup["CenterLongitude"];
59 m_centerLatitude = mapGroup["CenterLatitude"];
60 if (IsPlanetocentric()) {
62 }
63
64 // convert to radians, adjust for longitude direction
65 m_centerLongitude *= PI / 180.0;
66 m_centerLatitude *= PI / 180.0;
68
69 // Compute the scale factor
70 double cos_clat = cos(m_centerLatitude);
71 double sin_clat = sin(m_centerLatitude);
72 double m_eccsq = Eccentricity() * Eccentricity();
73 m_scalefactor = cos_clat / sqrt(1.0 - m_eccsq * sin_clat * sin_clat);
74 }
75 catch (IException &e) {
76 QString message = "Invalid label group [Mapping]";
77 throw IException(e, IException::Io, message, _FILEINFO_);
78 }
79 }
80
84
94 if (!Projection::operator==(proj)) return false;
95 // don't do the below it is a recusive plunge
96 // if (Projection::operator!=(proj)) return false;
97 Mercator *merc = (Mercator *) &proj;
98 if ((merc->m_centerLongitude != m_centerLongitude) ||
99 (merc->m_centerLatitude != m_centerLatitude)) return false;
100 return true;
101 }
102
108 QString Mercator::Name() const {
109 return "Mercator";
110 }
111
118 QString Mercator::Version() const {
119 return "1.0";
120 }
121
129 return m_centerLatitude * 180.0 / PI;
130 }
131
138 return true;
139 }
140
153 bool Mercator::SetGround(const double lat, const double lon) {
154 // Convert longitude to radians & clean up
155 m_longitude = lon;
156 double lonRadians = lon * PI / 180.0;
157 if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
158
159 // Now convert latitude to radians & clean up ... it must be planetographic
160 m_latitude = lat;
161 double latRadians = lat;
162 if (IsPlanetocentric()) latRadians = ToPlanetographic(latRadians);
163 latRadians *= PI / 180.0;
164
165 // Make sure latitude value is not too close to either pole
166 if (fabs(fabs(m_latitude) - 90.0) <= DBL_EPSILON) {
167 m_good = false;
168 return m_good;
169 }
170
171 // Compute the coordinate
172 double deltaLon = (lonRadians - m_centerLongitude);
173 double x = m_equatorialRadius * deltaLon * m_scalefactor;
174 double sinphi = sin(latRadians);
175 double t = tCompute(latRadians, sinphi);
176 double y = -m_equatorialRadius * m_scalefactor * log(t);
177 SetComputedXY(x, y);
178 m_good = true;
179 return m_good;
180 }
181
195 bool Mercator::SetCoordinate(const double x, const double y) {
196 // Save the coordinate
197 SetXY(x, y);
198
199 // Compute Snyder's t
200 double snyders_t = exp(-GetY() / (m_equatorialRadius * m_scalefactor));
201
202 // Compute latitude and make sure it is not above 90
203 m_latitude = phi2Compute(snyders_t);
204 if (fabs(m_latitude) > HALFPI) {
205 if (fabs(HALFPI - fabs(m_latitude)) > DBL_EPSILON) {
206 m_good = false;
207 return m_good;
208 }
209 else if (m_latitude < 0.0) {
211 }
212 else {
214 }
215 }
216
217 // Compute longitude
218 double coslat = cos(m_latitude);
219 if (coslat <= DBL_EPSILON) {
221 }
222 else {
225 }
226
227 // Convert to degrees
228 m_latitude *= 180.0 / PI;
229 m_longitude *= 180.0 / PI;
230
231 // Cleanup the longitude
233 // These need to be done for circular type projections
234 // m_longitude = To360Domain (m_longitude);
235 // if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude);
236
237 // Cleanup the latitude
239
240 m_good = true;
241 return m_good;
242 }
243
267 bool Mercator::XYRange(double &minX, double &maxX,
268 double &minY, double &maxY) {
269 // Check the corners of the lat/lon range
274
275 // Make sure everything is ordered
276 if (m_minimumX >= m_maximumX) return false;
277 if (m_minimumY >= m_maximumY) return false;
278
279 // Return X/Y min/maxs
280 minX = m_minimumX;
281 maxX = m_maximumX;
282 minY = m_minimumY;
283 maxY = m_maximumY;
284 return true;
285 }
286
293 PvlGroup mapping = TProjection::Mapping();
294
295 mapping += m_mappingGrp["CenterLatitude"];
296 mapping += m_mappingGrp["CenterLongitude"];
297
298 return mapping;
299 }
300
308
309 mapping += m_mappingGrp["CenterLatitude"];
310
311 return mapping;
312 }
313
321
322 mapping += m_mappingGrp["CenterLongitude"];
323
324 return mapping;
325 }
326
327} // end namespace isis
328
342extern "C" Isis::Projection *MercatorPlugin(Isis::Pvl &lab,
343 bool allowDefaults) {
344 return new Isis::Mercator(lab, allowDefaults);
345}
346
347
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
Mercator Map Projection.
Definition Mercator.h:57
double m_centerLongitude
The center longitude for the map projection.
Definition Mercator.h:77
double m_centerLatitude
The center latitude for the map projection.
Definition Mercator.h:78
double TrueScaleLatitude() const
Returns the latitude of true scale in degrees.
Definition Mercator.cpp:128
double m_scalefactor
Scaling factor.
Definition Mercator.h:79
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition Mercator.cpp:292
QString Name() const
Returns the name of the map projection, "Mercator".
Definition Mercator.cpp:108
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
Definition Mercator.cpp:306
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 Mercator.cpp:267
~Mercator()
Destroys the Mercator object.
Definition Mercator.cpp:82
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition Mercator.cpp:195
QString Version() const
Returns the version of the map projection.
Definition Mercator.cpp:118
bool SetGround(const double lat, const double lon)
This method is used to set the latitude/longitude (assumed to be of the correct LatitudeType,...
Definition Mercator.cpp:153
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
Definition Mercator.cpp:319
bool IsEquatorialCylindrical()
Indicates whether the projection is Equitorial Cylindrical.
Definition Mercator.cpp:137
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition Mercator.cpp:93
Mercator(Pvl &label, bool allowDefaults=false)
Constructs a Mercator object.
Definition Mercator.cpp:37
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
double GetY() const
Calculates the unrotated form of the current y value.
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.
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
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.
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude.
void XYRangeCheck(const double latitude, const double longitude)
This convience function is established to assist in the development of the XYRange virtual method.
double Eccentricity() const
This returns the eccentricity of the target,.
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
double phi2Compute(const double t) const
A convience method to compute latitude angle phi2 given small t, from Syder's recursive equation (7-9...
double m_minimumLongitude
Contains the minimum longitude for the entire ground range.
double tCompute(const double phi, const double sinphi) const
A convience method to compute Snyder's t equation (15-9) for a given latitude, .
@ 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 ToPlanetographic(const double lat) const
This method converts a planetocentric latitude to a planetographic latitude.
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.