Isis 3.0 Programmer Reference
Back | Home
PolarStereographic.cpp
Go to the documentation of this file.
1 
23 #include "PolarStereographic.h"
24 
25 #include <cmath>
26 #include <cfloat>
27 #include <iostream>
28 
29 #include "Constants.h"
30 #include "IException.h"
31 #include "TProjection.h"
32 #include "Pvl.h"
33 #include "PvlGroup.h"
34 #include "PvlKeyword.h"
35 
36 using namespace std;
37 namespace Isis {
58  PolarStereographic::PolarStereographic(Pvl &label, bool allowDefaults) :
59  TProjection::TProjection(label) {
60  try {
61  // Try to read the mapping group
62  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
63 
64  // Compute and write the default center longitude if allowed and
65  // necessary
66  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
67  double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
68  mapGroup += PvlKeyword("CenterLongitude", toString(lon));
69  }
70 
71  // Compute and write the default center latitude if allowed and
72  // necessary
73  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLatitude"))) {
74  double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
75  if (lat > 0.0) {
76  mapGroup += PvlKeyword("CenterLatitude", toString(90.0));
77  }
78  else {
79  mapGroup += PvlKeyword("CenterLatitude", toString(-90.0));
80  }
81  }
82 
83  // Get the center longitude, convert to radians and adjust for longitude
84  // direction
85  m_centerLongitude = mapGroup["CenterLongitude"];
86  m_centerLongitude *= PI / 180.0;
88 
89  // Get the center latitude, make sure it is ographic, and convert to
90  // radians.
91  m_centerLatitude = mapGroup["CenterLatitude"];
92  if (m_centerLatitude == 0) {
93  QString msg = "Invalid value for keyword [CenterLatitude] in map file.";
94  msg += " CenterLatitude cannot equal 0.0";
96  }
97  if (IsPlanetocentric()) {
99  }
100  m_centerLatitude *= PI / 180.0;
101 
102  // Compute some constants
103  m_e4 = e4Compute();
104  m_signFactor = 1.0;
105  if (m_centerLatitude < 0.0) m_signFactor = -1.0;
106 
107  if ((HALFPI - fabs(m_centerLatitude)) > DBL_EPSILON) {
108  m_poleFlag = true; // We are not at a pole
109  double phi = m_signFactor * m_centerLatitude;
110  double sinphi = sin(phi);
111  double cosphi = cos(phi);
112  m_m = mCompute(sinphi, cosphi);
113  m_t = tCompute(phi, sinphi);
114  if (fabs(m_t) < DBL_EPSILON) m_poleFlag = false;
115  }
116  else {
117  m_poleFlag = false; // Implies we are at a pole
118  m_m = 0;
119  m_t = 0;
120  }
121  }
122  catch(IException &e) {
123  QString message = "Invalid label group [Mapping]";
124  throw IException(e, IException::Unknown, message, _FILEINFO_);
125  }
126  }
127 
128 
131  }
132 
133 
143  if (!Projection::operator==(proj)) return false;
144  // dont do the below it is a recusive plunge
145  // if (Projection::operator!=(proj)) return false;
146  PolarStereographic *pola = (PolarStereographic *) &proj;
147  if (pola->m_centerLongitude != m_centerLongitude) return false;
148  if (pola->m_centerLatitude != m_centerLatitude) return false;
149  return true;
150  }
151 
152 
158  QString PolarStereographic::Name() const {
159  return "PolarStereographic";
160  }
161 
162 
169  QString PolarStereographic::Version() const {
170  return "1.0";
171  }
172 
173 
183  return m_centerLatitude * 180.0 / PI;
184  }
185 
186 
199  bool PolarStereographic::SetGround(const double lat, const double lon) {
200  // Fix up longitude
201  m_longitude = lon;
202  double lonRadians = lon * PI / 180.0;
203  if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
204 
205  // Now do latitude ... it must be planetographic
206  m_latitude = lat;
207  double latRadians = lat;
208  if (IsPlanetocentric()) latRadians = ToPlanetographic(latRadians);
209  latRadians = latRadians * PI / 180.0;
210 
211  // Compute easting and northing
212  double lamda = m_signFactor * (lonRadians - m_centerLongitude);
213  double phi = m_signFactor * latRadians;
214  double sinphi = sin(phi);
215  double t = tCompute(phi, sinphi);
216 
217  double dist;
218  if (m_poleFlag) {
219  dist = m_equatorialRadius * m_m * t / m_t;
220  }
221  else {
222  dist = m_equatorialRadius * 2.0 * t / m_e4;
223  }
224 
225  double x = m_signFactor * dist * sin(lamda);
226  double y = -(m_signFactor * dist * cos(lamda));
227  SetComputedXY(x, y);
228 
229  m_good = true;
230 
231  //So we don't project the wrong pole.
232  if (qFuzzyCompare(lat * m_signFactor, -90.0))
233  m_good = false;
234 
235  return m_good;
236  }
237 
238 
252  bool PolarStereographic::SetCoordinate(const double x, const double y) {
253  // Save the coordinate
254  SetXY(x, y);
255 
256  double east = m_signFactor * GetX();
257  double north = m_signFactor * GetY();
258  double dist = sqrt(east * east + north * north);
259 
260  double t;
261  if (m_poleFlag) {
262  t = dist * m_t / (m_m * m_equatorialRadius); // Snyder eqn (21-40)
263  }
264  else {
265  t = dist * m_e4 / (2.0 * m_equatorialRadius); //Snyder eqn (24-39)
266  //when latitude of true scale is North Polar
267  }
268 
269  // Compute the latitude
270  double phi = phi2Compute(t);
271  m_latitude = m_signFactor * phi;
272 
273  if (fabs(m_latitude) > HALFPI) {
274  QString msg = "X,Y causes latitude to be outside [-90,90] "
275  "in PolarStereographic Class";
277  }
278 
279  // Compute the longitude
280  if (dist == 0.0) {
282  }
283  else {
284  m_longitude = m_signFactor * atan2(east, -north) + m_centerLongitude;
285  }
286 
287  // Cleanup the longitude
288  m_longitude *= 180.0 / PI;
292 
293  // Cleanup the latitude
294  m_latitude *= 180.0 / PI;
296 
297  m_good = true;
298  return m_good;
299  }
300 
301 
325  bool PolarStereographic::XYRange(double &minX, double &maxX,
326  double &minY, double &maxY) {
327  // Check the corners of the lat/lon range
332 
333  // Find the closest longitude >= to the minimum longitude that is offset
334  // from the center longitude by a multiple of 90.
335  double lon1 = m_centerLongitude * 180.0 / PI;
336  if (m_longitudeDirection == PositiveWest) lon1 *= -1.0;
337  while(lon1 > m_minimumLongitude) lon1 -= 90.0;
338  while(lon1 < m_minimumLongitude) lon1 += 90.0;
339 
340  while(lon1 <= m_maximumLongitude) {
343  lon1 += 90.0;
344  }
345 
346  // Make sure everything is ordered
347  if (m_minimumX >= m_maximumX) return false;
348  if (m_minimumY >= m_maximumY) return false;
349 
350  // Return X/Y min/maxs
351  minX = m_minimumX;
352  maxX = m_maximumX;
353  minY = m_minimumY;
354  maxY = m_maximumY;
355  return true;
356  }
357 
358 
365  PvlGroup mapping = TProjection::Mapping();
366 
367  mapping += m_mappingGrp["CenterLatitude"];
368  mapping += m_mappingGrp["CenterLongitude"];
369 
370  return mapping;
371  }
372 
373 
381 
382  mapping += m_mappingGrp["CenterLatitude"];
383 
384  return mapping;
385  }
386 
387 
395 
396  mapping += m_mappingGrp["CenterLongitude"];
397 
398  return mapping;
399  }
400 }
401 
402 
418  bool allowDefaults) {
419  return new Isis::PolarStereographic(lab, allowDefaults);
420 }
double m_centerLatitude
The center latitude for the map projection.
double m_signFactor
If the center latitude is positive, the sign factor is 1.
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:804
QString Version() const
Returns the version of the map projection.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
~PolarStereographic()
Destroys the PolarStereographic object.
double TrueScaleLatitude() const
Returns the latitude of true scale.
Isis::Projection * PolarStereographicPlugin(Isis::Pvl &lab, bool allowDefaults)
This is the function that is called in order to instantiate an PolarStereographic object...
Longitude values increase in the westerly direction.
Definition: TProjection.h:237
Base class for Map TProjections.
Definition: TProjection.h:178
double ToPlanetographic(const double lat) const
This method converts a planetocentric latitude to a planetographic latitude.
double m_e4
Convenience variable for calculations.
const double PI(3.14159265358979323846)
The mathematical constant PI.
double m_centerLongitude
The center longitude for the map projection.
Search child objects.
Definition: PvlObject.h:170
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
Definition: Projection.h:330
const double HALFPI(1.57079632679489661923)
The mathematical constant PI/2.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:226
double e4Compute() const
A convience method to compute.
This error is for when a programmer made an API call that was illegal.
Definition: IException.h:154
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:766
double m_latitude
This contains the currently set latitude value.
Definition: TProjection.h:327
Stereographic Map Projection for Polar Aspect.
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
double m_m
Snyder&#39;s m-value from equation (14-15).
double m_maximumY
See minimumX description.
Definition: Projection.h:341
double m_longitude
This contains the currently set longitude value.
Definition: TProjection.h:329
double m_maximumLongitude
Contains the maximum longitude for the entire ground range.
Definition: TProjection.h:371
double m_minimumLatitude
Contains the minimum latitude for the entire ground range.
Definition: TProjection.h:365
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...
double m_maximumLatitude
Contains the maximum latitude for the entire ground range.
Definition: TProjection.h:367
Base class for Map Projections.
Definition: Projection.h:169
double m_minimumY
See minimumX description.
Definition: Projection.h:340
double m_equatorialRadius
Polar radius of the target.
Definition: TProjection.h:346
int m_longitudeDomain
This integer is either 180 or 360 and is read from the labels.
Definition: TProjection.h:342
static double To180Domain(const double lon)
This method converts a longitude into the -180 to 180 domain.
Contains multiple PvlContainers.
Definition: PvlGroup.h:57
#define _FILEINFO_
Macro for the filename and line number.
Definition: IException.h:38
A type of error that could only have occurred due to a mistake on the user&#39;s part (e...
Definition: IException.h:134
A single keyword-value pair.
Definition: PvlKeyword.h:98
A type of error that cannot be classified as any of the other error types.
Definition: IException.h:126
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
double m_t
Snyder&#39;s t-value from equation (15-19).
Container for cube-like labels.
Definition: Pvl.h:135
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude.
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:313
static double To360Domain(const double lon)
This method converts a longitude into the 0 to 360 domain.
LongitudeDirection m_longitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
Definition: TProjection.h:335
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
double mCompute(const double sinphi, const double cosphi) const
A convience method to compute Snyder&#39;s m equation (14-15) for a given latitude, . ...
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Isis exception class.
Definition: IException.h:99
double GetY() const
Calculates the unrotated form of the current y value.
Definition: Projection.cpp:815
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.
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
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:790
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...
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, .
QString Name() const
Returns the name of the map projection, &quot;PolarStereographic&quot;.
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:369
double m_poleFlag
Indicates whether the center latitude is at a pole.
double m_maximumX
See minimumX description.
Definition: Projection.h:339
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:342

U.S. Department of the Interior | U.S. Geological Survey
ISIS | Privacy & Disclaimers | Astrogeology Research Program
To contact us, please post comments and questions on the ISIS Support Center
File Modified: 07/12/2023 23:25:51