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 
19 using namespace std;
20 namespace 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 
83  }
84 
93  bool Mercator::operator== (const Projection &proj) {
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) {
210  m_latitude = -HALFPI;
211  }
212  else {
213  m_latitude = HALFPI;
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 
342 extern "C" Isis::Projection *MercatorPlugin(Isis::Pvl &lab,
343  bool allowDefaults) {
344  return new Isis::Mercator(lab, allowDefaults);
345 }
346 
347 
Isis::TProjection::m_maximumLatitude
double m_maximumLatitude
Contains the maximum latitude for the entire ground range.
Definition: TProjection.h:356
Isis::HALFPI
const double HALFPI
The mathematical constant PI/2.
Definition: Constants.h:41
Isis::TProjection::m_longitude
double m_longitude
This contains the currently set longitude value.
Definition: TProjection.h:318
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::IException::Io
@ Io
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:155
Isis::TProjection::m_minimumLongitude
double m_minimumLongitude
Contains the minimum longitude for the entire ground range.
Definition: TProjection.h:358
Isis::TProjection::m_latitude
double m_latitude
This contains the currently set latitude value.
Definition: TProjection.h:316
Isis::PI
const double PI
The mathematical constant PI.
Definition: Constants.h:40
Isis::Mercator::TrueScaleLatitude
double TrueScaleLatitude() const
Returns the latitude of true scale in degrees.
Definition: Mercator.cpp:128
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::TProjection::m_longitudeDirection
LongitudeDirection m_longitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
Definition: TProjection.h:324
Isis::TProjection::m_minimumLatitude
double m_minimumLatitude
Contains the minimum latitude for the entire ground range.
Definition: TProjection.h:354
Isis::TProjection::PositiveWest
@ PositiveWest
Longitude values increase in the westerly direction.
Definition: TProjection.h:225
Isis::Mercator::SetCoordinate
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition: Mercator.cpp:195
Isis::Projection::m_minimumY
double m_minimumY
See minimumX description.
Definition: Projection.h:327
Isis::Mercator::IsEquatorialCylindrical
bool IsEquatorialCylindrical()
Indicates whether the projection is Equitorial Cylindrical.
Definition: Mercator.cpp:137
Isis::Mercator::MappingLatitudes
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
Definition: Mercator.cpp:306
Isis::Projection::GetX
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:818
Isis::TProjection::tCompute
double tCompute(const double phi, const double sinphi) const
A convience method to compute Snyder's t equation (15-9) for a given latitude, .
Definition: TProjection.cpp:1870
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::TProjection::Eccentricity
double Eccentricity() const
This returns the eccentricity of the target,.
Definition: TProjection.cpp:304
Isis::Projection::SetXY
void SetXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:804
Isis::TProjection::ToPlanetocentric
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude.
Definition: TProjection.cpp:418
Isis::TProjection::XYRangeCheck
void XYRangeCheck(const double latitude, const double longitude)
This convience function is established to assist in the development of the XYRange virtual method.
Definition: TProjection.cpp:1062
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::Projection::m_mappingGrp
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:329
Isis::Projection::GetY
double GetY() const
Calculates the unrotated form of the current y value.
Definition: Projection.cpp:829
Isis::Mercator::m_centerLatitude
double m_centerLatitude
The center latitude for the map projection.
Definition: Mercator.h:78
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::Mercator::XYRange
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
Isis::Projection::m_minimumX
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
Definition: Projection.h:317
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::Projection::m_good
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
Definition: Projection.h:300
Isis::TProjection
Base class for Map TProjections.
Definition: TProjection.h:166
Isis::Mercator::m_scalefactor
double m_scalefactor
Scaling factor.
Definition: Mercator.h:79
Isis::Mercator::SetGround
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
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::TProjection::MappingLongitudes
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
Definition: TProjection.cpp:1739
Isis::Mercator::Name
QString Name() const
Returns the name of the map projection, "Mercator".
Definition: Mercator.cpp:108
Isis::Projection::SetComputedXY
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:780
Isis::Mercator::MappingLongitudes
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
Definition: Mercator.cpp:319
std
Namespace for the standard library.
Isis::Mercator::Mapping
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition: Mercator.cpp:292
Isis::TProjection::m_maximumLongitude
double m_maximumLongitude
Contains the maximum longitude for the entire ground range.
Definition: TProjection.h:360
Isis::Mercator::m_centerLongitude
double m_centerLongitude
The center longitude for the map projection.
Definition: Mercator.h:77
Isis::Mercator::Version
QString Version() const
Returns the version of the map projection.
Definition: Mercator.cpp:118
Isis::TProjection::MappingLatitudes
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
Definition: TProjection.cpp:1723
Isis::TProjection::ToPlanetographic
double ToPlanetographic(const double lat) const
This method converts a planetocentric latitude to a planetographic latitude.
Definition: TProjection.cpp:463
Isis::Mercator
Mercator Map Projection.
Definition: Mercator.h:57
Isis::TProjection::phi2Compute
double phi2Compute(const double t) const
A convience method to compute latitude angle phi2 given small t, from Syder's recursive equation (7-9...
Definition: TProjection.cpp:1803
Isis::TProjection::Mapping
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition: TProjection.cpp:1698
Isis::TProjection::m_equatorialRadius
double m_equatorialRadius
Polar radius of the target.
Definition: TProjection.h:335
Isis::TProjection::IsPlanetocentric
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
Definition: TProjection.cpp:392
Isis::Mercator::operator==
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition: Mercator.cpp:93
Isis::Projection::m_maximumY
double m_maximumY
See minimumX description.
Definition: Projection.h:328
Isis::Projection
Base class for Map Projections.
Definition: Projection.h:155
Isis::Projection::m_maximumX
double m_maximumX
See minimumX description.
Definition: Projection.h:326
Isis::Mercator::~Mercator
~Mercator()
Destroys the Mercator object.
Definition: Mercator.cpp:82
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16