Isis 3.0 Programmer Reference
Back | Home
PointPerspective.cpp
Go to the documentation of this file.
1 
23 #include "PointPerspective.h"
24 
25 #include <cfloat>
26 #include <cmath>
27 #include <iomanip>
28 
29 #include "Constants.h"
30 #include "IException.h"
31 #include "Pvl.h"
32 #include "PvlGroup.h"
33 #include "PvlKeyword.h"
34 #include "TProjection.h"
35 
36 using namespace std;
37 
38 namespace Isis {
55  PointPerspective::PointPerspective(Pvl &label, bool allowDefaults) :
56  TProjection::TProjection(label) {
57  try {
58  // Try to read the mapping group
59  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
60 
61  // Compute and write the default center longitude if allowed and
62  // necessary
63  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
64  double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
65  mapGroup += PvlKeyword("CenterLongitude", toString(lon));
66  }
67 
68  // Compute and write the default center latitude if allowed and
69  // necessary
70  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLatitude"))) {
71  double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
72  mapGroup += PvlKeyword("CenterLatitude", toString(lat));
73  }
74 
75  // Get the center longitude & latitude
76  m_centerLongitude = mapGroup["CenterLongitude"];
77  m_centerLatitude = mapGroup["CenterLatitude"];
78  if (IsPlanetocentric()) {
80  }
81 
82  // convert to radians, adjust for longitude direction
83  m_centerLongitude *= PI / 180.0;
84  m_centerLatitude *= PI / 180.0;
86 
87  // Calculate sine & cosine of center latitude
90 
91  // Get the distance above planet center (the point of perspective from
92  // the center of planet), and calculate P
93  m_distance = mapGroup["Distance"];
94  m_distance *= 1000.;
95 
96  m_P = 1.0 + (m_distance / m_equatorialRadius);
97  }
98  catch(IException &e) {
99  QString message = "Invalid label group [Mapping]";
100  throw IException(e, IException::Io, message, _FILEINFO_);
101  }
102  }
103 
106  }
107 
117  if (!Projection::operator==(proj)) return false;
118  // dont do the below it is a recusive plunge
119  // if (Projection::operator!=(proj)) return false;
120  PointPerspective *point = (PointPerspective *) &proj;
121  if((point->m_centerLongitude != this->m_centerLongitude) ||
122  (point->m_centerLatitude != this->m_centerLatitude) ||
123  (point->m_distance != this->m_distance)) return false;
124  return true;
125  }
126 
132  QString PointPerspective::Name() const {
133  return "PointPerspective";
134  }
135 
141  QString PointPerspective::Version() const {
142  return "1.0";
143  }
144 
152  return m_centerLatitude * 180.0 / PI;
153  }
154 
175  bool PointPerspective::SetGround(const double lat, const double lon) {
176  // Convert longitude to radians & clean up
177  double projectionRadius = m_equatorialRadius*sqrt((m_P+1)/(m_P+1));
178 
179  m_longitude = lon;
180  double lonRadians = lon * PI / 180.0;
181  if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
182 
183  // Now convert latitude to radians & clean up ... it must be planetographic
184  m_latitude = lat;
185  double latRadians = lat;
186  if (IsPlanetocentric()) latRadians = ToPlanetographic(latRadians);
187  latRadians *= PI / 180.0;
188 
189  // Compute helper variables
190  double deltaLon = (lonRadians - m_centerLongitude);
191  double sinphi = sin(latRadians);
192  double cosphi = cos(latRadians);
193  double coslon = cos(deltaLon);
194 
195  // Lat/Lon cannot be projected
196  double g = m_sinph0 * sinphi + m_cosph0 * cosphi * coslon;
197  if (g < (1.0 / m_P)) {
198  m_good = false;
199  return m_good;
200  }
201  // Compute the coordinates
202  double ksp = (m_P - 1.0) / (m_P - g);
203 
204  double x = m_equatorialRadius * ksp * cosphi * sin(deltaLon);
205  double y = m_equatorialRadius * ksp *
206  (m_cosph0 * sinphi - m_sinph0 * cosphi * coslon);
207 
208  if (sqrt(x*x+y*y)> projectionRadius) {
209 
210  m_good =false;
211 
212  return m_good;
213  }
214 
215  SetComputedXY(x,y);
216  m_good = true;
217  return m_good;
218  }
219 
233  bool PointPerspective::SetCoordinate(const double x, const double y) {
234 
235 
236  // Save the coordinate
237  SetXY(x, y);
238 
239  // Declare instance variables and calculate rho
240  double rho, rp, con, com, z, sinz, cosz;
241  const double epsilon = 1.0e-10;
242  rho = sqrt(GetX() * GetX() + GetY() * GetY());
243  rp = rho / m_equatorialRadius;
244  con = m_P - 1.0;
245  com = m_P + 1.0;
246 
247  // Error calculating rho - should be less than equatorial radius
248  if (rp > (sqrt(con / com))) {
249  m_good = false;
250  return m_good;
251  }
252 
253  // Calculate the latitude and longitude
255  if (fabs(rho) <= epsilon) {
257  }
258  else {
259  if (rp <= epsilon) {
260  sinz = 0.0;
261  }
262  else {
263  sinz = (m_P - sqrt(1.0 - rp * rp * com / con)) / (con / rp + rp / con);
264  }
265  z = asin(sinz);
266  sinz = sin(z);
267  cosz = cos(z);
268  con = cosz * m_sinph0 + GetY() * sinz * m_cosph0 / rho;
269  if (con > 1.0) con = 1.0;
270  if (con < -1.0) con = -1.0;
271  m_latitude = asin(con);
272 
273  con = fabs(m_centerLatitude) - HALFPI;
274  if (fabs(con) <= epsilon) {
275  if (m_centerLatitude >= 0.0) {
276  m_longitude += atan2(GetX(), -GetY());
277  }
278  else {
279  m_longitude += atan2(-GetX(), GetY());
280  }
281  }
282  else {
283  con = cosz - m_sinph0 * sin(m_latitude);
284  if ((fabs(con) >= epsilon) || (fabs(GetX()) >= epsilon)) {
285  m_longitude += atan2(GetX() * sinz * m_cosph0, con * rho);
286  }
287  }
288  }
289 
290  // Convert to degrees
291  m_latitude *= 180.0 / PI;
292  m_longitude *= 180.0 / PI;
293 
294  // Cleanup the longitude
296  // These need to be done for circular type projections
299 
300  // Cleanup the latitude
302 
303 
304  m_good = true;
305  return m_good;
306  }
307 
340  bool PointPerspective::XYRange(double &minX, double &maxX, double &minY, double &maxY) {
341 
342  double projectionRadius = m_equatorialRadius*sqrt((m_P-1.0)/(m_P+1.0));
343 
344  SetCoordinate(0.0,0.0);
345  minX = XCoord() - projectionRadius;
346  maxX = XCoord() + projectionRadius;
347  minY = YCoord() - projectionRadius;
348  maxY = YCoord() + projectionRadius;
349 
350  return true;
351 
352  }
353 
354 
361  PvlGroup mapping = TProjection::Mapping();
362 
363  mapping += m_mappingGrp["CenterLatitude"];
364  mapping += m_mappingGrp["CenterLongitude"];
365  mapping += m_mappingGrp["Distance"];
366 
367  return mapping;
368  }
369 
377 
378  mapping += m_mappingGrp["CenterLatitude"];
379 
380  return mapping;
381  }
382 
390 
391  mapping += m_mappingGrp["CenterLongitude"];
392 
393  return mapping;
394  }
395 } // end namespace isis
396 
407  bool allowDefaults) {
408  return new Isis::PointPerspective(lab, allowDefaults);
409 }
double m_distance
Distance fromp perspective point to planet center.
double TrueScaleLatitude() const
Returns the latitude of true scale, in degrees.
PointPerspective Map Projection.
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.
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:804
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:141
Longitude values increase in the westerly direction.
Definition: TProjection.h:237
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
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.
const double PI(3.14159265358979323846)
The mathematical constant PI.
double XCoord() const
This returns the projection X provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:402
~PointPerspective()
Destroys the PointPerspective object.
Search child objects.
Definition: PvlObject.h:170
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
A type of error that occurred when performing an actual I/O operation.
Definition: IException.h:163
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
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
double m_longitude
This contains the currently set longitude value.
Definition: TProjection.h:329
double m_centerLatitude
The center latitude for the map projection.
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
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
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 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_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 single keyword-value pair.
Definition: PvlKeyword.h:98
double m_P
Perspective Point.
double m_centerLongitude
The center longitude for the map projection.
QString Version() const
Returns the version of the map projection.
QString Name() const
Returns the name of the map projection, &quot;PointPerspective&quot;.
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
double YCoord() const
This returns the projection Y provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:415
static double To360Domain(const double lon)
This method converts a longitude into the 0 to 360 domain.
double m_cosph0
Cosine of the center latitude.
Isis::Projection * PointPerspectivePlugin(Isis::Pvl &lab, bool allowDefaults)
This is the function that is called in order to instantiate a PointPerspectve object.
LongitudeDirection m_longitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels.
Definition: TProjection.h:335
Isis exception class.
Definition: IException.h:99
double GetY() const
Calculates the unrotated form of the current y value.
Definition: Projection.cpp:815
double m_sinph0
Sine of the center 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:790
double m_minimumLongitude
Contains the minimum longitude for the entire ground range.
Definition: TProjection.h:369
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:342
PvlGroup Mapping()
This function returns the keywords that this projection uses.

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:47