Isis 3 Programmer Reference
Mercator.cpp
Go to the documentation of this file.
1 
23 #include "Mercator.h"
24 
25 #include <cmath>
26 #include <cfloat>
27 
28 #include "IException.h"
29 #include "Constants.h"
30 #include "TProjection.h"
31 #include "Pvl.h"
32 #include "PvlGroup.h"
33 #include "PvlKeyword.h"
34 
35 using namespace std;
36 namespace Isis {
53  Mercator::Mercator(Pvl &label, bool allowDefaults) :
54  TProjection::TProjection(label) {
55  try {
56  // Try to read the mapping group
57  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
58 
59  // Compute and write the default center longitude if allowed and
60  // necessary
61  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
62  double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
63  mapGroup += PvlKeyword("CenterLongitude", toString(lon));
64  }
65 
66  // Compute and write the default center latitude if allowed and
67  // necessary
68  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLatitude"))) {
69  double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
70  mapGroup += PvlKeyword("CenterLatitude", toString(lat));
71  }
72 
73  // Get the center longitude & latitude
74  m_centerLongitude = mapGroup["CenterLongitude"];
75  m_centerLatitude = mapGroup["CenterLatitude"];
76  if (IsPlanetocentric()) {
78  }
79 
80  // convert to radians, adjust for longitude direction
81  m_centerLongitude *= PI / 180.0;
82  m_centerLatitude *= PI / 180.0;
84 
85  // Compute the scale factor
86  double cos_clat = cos(m_centerLatitude);
87  double sin_clat = sin(m_centerLatitude);
88  double m_eccsq = Eccentricity() * Eccentricity();
89  m_scalefactor = cos_clat / sqrt(1.0 - m_eccsq * sin_clat * sin_clat);
90  }
91  catch (IException &e) {
92  QString message = "Invalid label group [Mapping]";
93  throw IException(e, IException::Io, message, _FILEINFO_);
94  }
95  }
96 
99  }
100 
109  bool Mercator::operator== (const Projection &proj) {
110  if (!Projection::operator==(proj)) return false;
111  // don't do the below it is a recusive plunge
112  // if (Projection::operator!=(proj)) return false;
113  Mercator *merc = (Mercator *) &proj;
114  if ((merc->m_centerLongitude != m_centerLongitude) ||
115  (merc->m_centerLatitude != m_centerLatitude)) return false;
116  return true;
117  }
118 
124  QString Mercator::Name() const {
125  return "Mercator";
126  }
127 
134  QString Mercator::Version() const {
135  return "1.0";
136  }
137 
145  return m_centerLatitude * 180.0 / PI;
146  }
147 
154  return true;
155  }
156 
169  bool Mercator::SetGround(const double lat, const double lon) {
170  // Convert longitude to radians & clean up
171  m_longitude = lon;
172  double lonRadians = lon * PI / 180.0;
173  if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
174 
175  // Now convert latitude to radians & clean up ... it must be planetographic
176  m_latitude = lat;
177  double latRadians = lat;
178  if (IsPlanetocentric()) latRadians = ToPlanetographic(latRadians);
179  latRadians *= PI / 180.0;
180 
181  // Make sure latitude value is not too close to either pole
182  if (fabs(fabs(m_latitude) - 90.0) <= DBL_EPSILON) {
183  m_good = false;
184  return m_good;
185  }
186 
187  // Compute the coordinate
188  double deltaLon = (lonRadians - m_centerLongitude);
189  double x = m_equatorialRadius * deltaLon * m_scalefactor;
190  double sinphi = sin(latRadians);
191  double t = tCompute(latRadians, sinphi);
192  double y = -m_equatorialRadius * m_scalefactor * log(t);
193  SetComputedXY(x, y);
194  m_good = true;
195  return m_good;
196  }
197 
211  bool Mercator::SetCoordinate(const double x, const double y) {
212  // Save the coordinate
213  SetXY(x, y);
214 
215  // Compute Snyder's t
216  double snyders_t = exp(-GetY() / (m_equatorialRadius * m_scalefactor));
217 
218  // Compute latitude and make sure it is not above 90
219  m_latitude = phi2Compute(snyders_t);
220  if (fabs(m_latitude) > HALFPI) {
221  if (fabs(HALFPI - fabs(m_latitude)) > DBL_EPSILON) {
222  m_good = false;
223  return m_good;
224  }
225  else if (m_latitude < 0.0) {
226  m_latitude = -HALFPI;
227  }
228  else {
229  m_latitude = HALFPI;
230  }
231  }
232 
233  // Compute longitude
234  double coslat = cos(m_latitude);
235  if (coslat <= DBL_EPSILON) {
237  }
238  else {
241  }
242 
243  // Convert to degrees
244  m_latitude *= 180.0 / PI;
245  m_longitude *= 180.0 / PI;
246 
247  // Cleanup the longitude
249  // These need to be done for circular type projections
250  // m_longitude = To360Domain (m_longitude);
251  // if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude);
252 
253  // Cleanup the latitude
255 
256  m_good = true;
257  return m_good;
258  }
259 
283  bool Mercator::XYRange(double &minX, double &maxX,
284  double &minY, double &maxY) {
285  // Check the corners of the lat/lon range
290 
291  // Make sure everything is ordered
292  if (m_minimumX >= m_maximumX) return false;
293  if (m_minimumY >= m_maximumY) return false;
294 
295  // Return X/Y min/maxs
296  minX = m_minimumX;
297  maxX = m_maximumX;
298  minY = m_minimumY;
299  maxY = m_maximumY;
300  return true;
301  }
302 
309  PvlGroup mapping = TProjection::Mapping();
310 
311  mapping += m_mappingGrp["CenterLatitude"];
312  mapping += m_mappingGrp["CenterLongitude"];
313 
314  return mapping;
315  }
316 
324 
325  mapping += m_mappingGrp["CenterLatitude"];
326 
327  return mapping;
328  }
329 
337 
338  mapping += m_mappingGrp["CenterLongitude"];
339 
340  return mapping;
341  }
342 
343 } // end namespace isis
344 
359  bool allowDefaults) {
360  return new Isis::Mercator(lab, allowDefaults);
361 }
362 
363 
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
bool SetGround(const double lat, const double lon)
This method is used to set the latitude/longitude (assumed to be of the correct LatitudeType, LongitudeDirection, and LongitudeDomain.
Definition: Mercator.cpp:169
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
double tCompute(const double phi, const double sinphi) const
A convience method to compute Snyder&#39;s t equation (15-9) for a given latitude, .
double m_centerLongitude
The center longitude for the map projection.
Definition: Mercator.h:93
const double PI
The mathematical constant PI.
Definition: Constants.h:56
Longitude values increase in the westerly direction.
Definition: TProjection.h:241
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition: Mercator.cpp:109
Base class for Map TProjections.
Definition: TProjection.h:182
const double HALFPI
The mathematical constant PI/2.
Definition: Constants.h:57
Namespace for the standard library.
QString Version() const
Returns the version of the map projection.
Definition: Mercator.cpp:134
Search child objects.
Definition: PvlObject.h:170
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:833
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
Definition: Projection.h:333
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
Definition: Mercator.cpp:335
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:171
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:795
double m_latitude
This contains the currently set latitude value.
Definition: TProjection.h:332
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
double m_maximumY
See minimumX description.
Definition: Projection.h:344
double m_longitude
This contains the currently set longitude value.
Definition: TProjection.h:334
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
double m_maximumLongitude
Contains the maximum longitude for the entire ground range.
Definition: TProjection.h:376
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition: Mercator.cpp:308
double m_minimumLatitude
Contains the minimum latitude for the entire ground range.
Definition: TProjection.h:370
double m_maximumLatitude
Contains the maximum latitude for the entire ground range.
Definition: TProjection.h:372
Base class for Map Projections.
Definition: Projection.h:171
double m_minimumY
See minimumX description.
Definition: Projection.h:343
QString Name() const
Returns the name of the map projection, "Mercator".
Definition: Mercator.cpp:124
double Eccentricity() const
This returns the eccentricity of the target,.
~Mercator()
Destroys the Mercator object.
Definition: Mercator.cpp:98
double m_equatorialRadius
Polar radius of the target.
Definition: TProjection.h:351
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:40
A single keyword-value pair.
Definition: PvlKeyword.h:98
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition: Mercator.cpp:211
double TrueScaleLatitude() const
Returns the latitude of true scale in degrees.
Definition: Mercator.cpp:144
Container for cube-like labels.
Definition: Pvl.h:135
double ToPlanetographic(const double lat) const
This method converts a planetocentric latitude to a planetographic latitude.
double phi2Compute(const double t) const
A convience method to compute latitude angle phi2 given small t, from Syder&#39;s recursive equation (7-9...
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
Definition: Projection.h:316
double m_scalefactor
Scaling factor.
Definition: Mercator.h:95
LongitudeDirection m_longitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
Definition: TProjection.h:340
Mercator Map Projection.
Definition: Mercator.h:73
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
Definition: Mercator.cpp:322
double m_centerLatitude
The center latitude for the map projection.
Definition: Mercator.h:94
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:283
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
bool IsEquatorialCylindrical()
Indicates whether the projection is Equitorial Cylindrical.
Definition: Mercator.cpp:153
double GetY() const
Calculates the unrotated form of the current y value.
Definition: Projection.cpp:844
Isis::Projection * MercatorPlugin(Isis::Pvl &lab, bool allowDefaults)
This is the function that is called in order to instantiate a Mercator object.
Definition: Mercator.cpp:358
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude.
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
void SetXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:819
void XYRangeCheck(const double latitude, const double longitude)
This convience function is established to assist in the development of the XYRange virtual method...
double m_minimumLongitude
Contains the minimum longitude for the entire ground range.
Definition: TProjection.h:374
double m_maximumX
See minimumX description.
Definition: Projection.h:342
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:345