Isis 3 Programmer Reference
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.
PointPerspective Map Projection.
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.
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
const double PI
The mathematical constant PI.
Definition: Constants.h:56
Longitude values increase in the westerly direction.
Definition: TProjection.h:241
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
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.
~PointPerspective()
Destroys the PointPerspective object.
Search child objects.
Definition: PvlObject.h:170
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:833
double XCoord() const
This returns the projection X provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:402
double TrueScaleLatitude() const
Returns the latitude of true scale, in degrees.
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: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.
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:334
double m_centerLatitude
The center latitude for the map projection.
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
double m_minimumLatitude
Contains the minimum latitude for the entire ground range.
Definition: TProjection.h:370
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
QString Name() const
Returns the name of the map projection, "PointPerspective".
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:372
Base class for Map Projections.
Definition: Projection.h:171
double m_equatorialRadius
Polar radius of the target.
Definition: TProjection.h:351
int m_longitudeDomain
This integer is either 180 or 360 and is read from the labels.
Definition: TProjection.h:347
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:40
A single keyword-value pair.
Definition: PvlKeyword.h:98
double m_P
Perspective Point.
double YCoord() const
This returns the projection Y provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success.
Definition: Projection.cpp:415
double m_centerLongitude
The center longitude for the map projection.
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.
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
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:340
QString Version() const
Returns the version of the map projection.
Isis exception class.
Definition: IException.h:107
Namespace for ISIS/Bullet specific routines.
Definition: Apollo.h:31
double GetY() const
Calculates the unrotated form of the current y value.
Definition: Projection.cpp:844
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude.
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:819
double m_minimumLongitude
Contains the minimum longitude for the entire ground range.
Definition: TProjection.h:374
PvlGroup m_mappingGrp
Mapping group that created this projection.
Definition: Projection.h:345
PvlGroup Mapping()
This function returns the keywords that this projection uses.