Isis 3 Programmer Reference
PointPerspective.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 #include "PointPerspective.h"
8 
9 #include <cfloat>
10 #include <cmath>
11 #include <iomanip>
12 
13 #include "Constants.h"
14 #include "IException.h"
15 #include "Pvl.h"
16 #include "PvlGroup.h"
17 #include "PvlKeyword.h"
18 #include "TProjection.h"
19 
20 using namespace std;
21 
22 namespace Isis {
39  PointPerspective::PointPerspective(Pvl &label, bool allowDefaults) :
40  TProjection::TProjection(label) {
41  try {
42  // Try to read the mapping group
43  PvlGroup &mapGroup = label.findGroup("Mapping", Pvl::Traverse);
44 
45  // Compute and write the default center longitude if allowed and
46  // necessary
47  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLongitude"))) {
48  double lon = (m_minimumLongitude + m_maximumLongitude) / 2.0;
49  mapGroup += PvlKeyword("CenterLongitude", toString(lon));
50  }
51 
52  // Compute and write the default center latitude if allowed and
53  // necessary
54  if ((allowDefaults) && (!mapGroup.hasKeyword("CenterLatitude"))) {
55  double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
56  mapGroup += PvlKeyword("CenterLatitude", toString(lat));
57  }
58 
59  // Get the center longitude & latitude
60  m_centerLongitude = mapGroup["CenterLongitude"];
61  m_centerLatitude = mapGroup["CenterLatitude"];
62  if (IsPlanetocentric()) {
64  }
65 
66  // convert to radians, adjust for longitude direction
67  m_centerLongitude *= PI / 180.0;
68  m_centerLatitude *= PI / 180.0;
70 
71  // Calculate sine & cosine of center latitude
74 
75  // Get the distance above planet center (the point of perspective from
76  // the center of planet), and calculate P
77  m_distance = mapGroup["Distance"];
78  m_distance *= 1000.;
79 
80  m_P = 1.0 + (m_distance / m_equatorialRadius);
81  }
82  catch(IException &e) {
83  QString message = "Invalid label group [Mapping]";
84  throw IException(e, IException::Io, message, _FILEINFO_);
85  }
86  }
87 
90  }
91 
101  if (!Projection::operator==(proj)) return false;
102  // dont do the below it is a recusive plunge
103  // if (Projection::operator!=(proj)) return false;
104  PointPerspective *point = (PointPerspective *) &proj;
105  if((point->m_centerLongitude != this->m_centerLongitude) ||
106  (point->m_centerLatitude != this->m_centerLatitude) ||
107  (point->m_distance != this->m_distance)) return false;
108  return true;
109  }
110 
116  QString PointPerspective::Name() const {
117  return "PointPerspective";
118  }
119 
125  QString PointPerspective::Version() const {
126  return "1.0";
127  }
128 
136  return m_centerLatitude * 180.0 / PI;
137  }
138 
159  bool PointPerspective::SetGround(const double lat, const double lon) {
160  // Convert longitude to radians & clean up
161  double projectionRadius = m_equatorialRadius*sqrt((m_P+1)/(m_P+1));
162 
163  m_longitude = lon;
164  double lonRadians = lon * PI / 180.0;
165  if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
166 
167  // Now convert latitude to radians & clean up ... it must be planetographic
168  m_latitude = lat;
169  double latRadians = lat;
170  if (IsPlanetocentric()) latRadians = ToPlanetographic(latRadians);
171  latRadians *= PI / 180.0;
172 
173  // Compute helper variables
174  double deltaLon = (lonRadians - m_centerLongitude);
175  double sinphi = sin(latRadians);
176  double cosphi = cos(latRadians);
177  double coslon = cos(deltaLon);
178 
179  // Lat/Lon cannot be projected
180  double g = m_sinph0 * sinphi + m_cosph0 * cosphi * coslon;
181  if (g < (1.0 / m_P)) {
182  m_good = false;
183  return m_good;
184  }
185  // Compute the coordinates
186  double ksp = (m_P - 1.0) / (m_P - g);
187 
188  double x = m_equatorialRadius * ksp * cosphi * sin(deltaLon);
189  double y = m_equatorialRadius * ksp *
190  (m_cosph0 * sinphi - m_sinph0 * cosphi * coslon);
191 
192  if (sqrt(x*x+y*y)> projectionRadius) {
193 
194  m_good =false;
195 
196  return m_good;
197  }
198 
199  SetComputedXY(x,y);
200  m_good = true;
201  return m_good;
202  }
203 
217  bool PointPerspective::SetCoordinate(const double x, const double y) {
218 
219 
220  // Save the coordinate
221  SetXY(x, y);
222 
223  // Declare instance variables and calculate rho
224  double rho, rp, con, com, z, sinz, cosz;
225  const double epsilon = 1.0e-10;
226  rho = sqrt(GetX() * GetX() + GetY() * GetY());
227  rp = rho / m_equatorialRadius;
228  con = m_P - 1.0;
229  com = m_P + 1.0;
230 
231  // Error calculating rho - should be less than equatorial radius
232  if (rp > (sqrt(con / com))) {
233  m_good = false;
234  return m_good;
235  }
236 
237  // Calculate the latitude and longitude
239  if (fabs(rho) <= epsilon) {
241  }
242  else {
243  if (rp <= epsilon) {
244  sinz = 0.0;
245  }
246  else {
247  sinz = (m_P - sqrt(1.0 - rp * rp * com / con)) / (con / rp + rp / con);
248  }
249  z = asin(sinz);
250  sinz = sin(z);
251  cosz = cos(z);
252  con = cosz * m_sinph0 + GetY() * sinz * m_cosph0 / rho;
253  if (con > 1.0) con = 1.0;
254  if (con < -1.0) con = -1.0;
255  m_latitude = asin(con);
256 
257  con = fabs(m_centerLatitude) - HALFPI;
258  if (fabs(con) <= epsilon) {
259  if (m_centerLatitude >= 0.0) {
260  m_longitude += atan2(GetX(), -GetY());
261  }
262  else {
263  m_longitude += atan2(-GetX(), GetY());
264  }
265  }
266  else {
267  con = cosz - m_sinph0 * sin(m_latitude);
268  if ((fabs(con) >= epsilon) || (fabs(GetX()) >= epsilon)) {
269  m_longitude += atan2(GetX() * sinz * m_cosph0, con * rho);
270  }
271  }
272  }
273 
274  // Convert to degrees
275  m_latitude *= 180.0 / PI;
276  m_longitude *= 180.0 / PI;
277 
278  // Cleanup the longitude
280  // These need to be done for circular type projections
283 
284  // Cleanup the latitude
286 
287 
288  m_good = true;
289  return m_good;
290  }
291 
324  bool PointPerspective::XYRange(double &minX, double &maxX, double &minY, double &maxY) {
325 
326  double projectionRadius = m_equatorialRadius*sqrt((m_P-1.0)/(m_P+1.0));
327 
328  SetCoordinate(0.0,0.0);
329  minX = XCoord() - projectionRadius;
330  maxX = XCoord() + projectionRadius;
331  minY = YCoord() - projectionRadius;
332  maxY = YCoord() + projectionRadius;
333 
334  return true;
335 
336  }
337 
338 
345  PvlGroup mapping = TProjection::Mapping();
346 
347  mapping += m_mappingGrp["CenterLatitude"];
348  mapping += m_mappingGrp["CenterLongitude"];
349  mapping += m_mappingGrp["Distance"];
350 
351  return mapping;
352  }
353 
361 
362  mapping += m_mappingGrp["CenterLatitude"];
363 
364  return mapping;
365  }
366 
374 
375  mapping += m_mappingGrp["CenterLongitude"];
376 
377  return mapping;
378  }
379 } // end namespace isis
380 
390 extern "C" Isis::Projection *PointPerspectivePlugin(Isis::Pvl &lab,
391  bool allowDefaults) {
392  return new Isis::PointPerspective(lab, allowDefaults);
393 }
Isis::PointPerspective::MappingLatitudes
PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
Definition: PointPerspective.cpp:359
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::PointPerspective::Name
QString Name() const
Returns the name of the map projection, "PointPerspective".
Definition: PointPerspective.cpp:116
Isis::TProjection::m_longitude
double m_longitude
This contains the currently set longitude value.
Definition: TProjection.h:318
Isis::TProjection::m_longitudeDomain
int m_longitudeDomain
This integer is either 180 or 360 and is read from the labels.
Definition: TProjection.h:331
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::PointPerspective
PointPerspective Map Projection.
Definition: PointPerspective.h:50
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::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::PointPerspective::MappingLongitudes
PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
Definition: PointPerspective.cpp:372
Isis::PointPerspective::m_P
double m_P
Perspective Point.
Definition: PointPerspective.h:74
Isis::PointPerspective::~PointPerspective
~PointPerspective()
Destroys the PointPerspective object.
Definition: PointPerspective.cpp:89
Isis::PointPerspective::m_centerLongitude
double m_centerLongitude
The center longitude for the map projection.
Definition: PointPerspective.h:69
Isis::Projection::GetX
double GetX() const
Calculates the unrotated form of current x value.
Definition: Projection.cpp:818
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::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::PointPerspective::m_centerLatitude
double m_centerLatitude
The center latitude for the map projection.
Definition: PointPerspective.h:70
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::PointPerspective::Mapping
PvlGroup Mapping()
This function returns the keywords that this projection uses.
Definition: PointPerspective.cpp:344
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::PointPerspective::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: PointPerspective.cpp:159
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::PointPerspective::operator==
bool operator==(const Projection &proj)
Compares two Projection objects to see if they are equal.
Definition: PointPerspective.cpp:100
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::PointPerspective::m_distance
double m_distance
Distance fromp perspective point to planet center.
Definition: PointPerspective.h:71
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::PointPerspective::m_cosph0
double m_cosph0
Cosine of the center latitude.
Definition: PointPerspective.h:73
Isis::TProjection::To180Domain
static double To180Domain(const double lon)
This method converts a longitude into the -180 to 180 domain.
Definition: TProjection.cpp:657
Isis::PointPerspective::TrueScaleLatitude
double TrueScaleLatitude() const
Returns the latitude of true scale, in degrees.
Definition: PointPerspective.cpp:135
Isis::TProjection::MappingLongitudes
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
Definition: TProjection.cpp:1739
Isis::Projection::SetComputedXY
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Definition: Projection.cpp:780
std
Namespace for the standard library.
Isis::PointPerspective::Version
QString Version() const
Returns the version of the map projection.
Definition: PointPerspective.cpp:125
Isis::TProjection::m_maximumLongitude
double m_maximumLongitude
Contains the maximum longitude for the entire ground range.
Definition: TProjection.h:360
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::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::To360Domain
static double To360Domain(const double lon)
This method converts a longitude into the 0 to 360 domain.
Definition: TProjection.cpp:675
Isis::PointPerspective::SetCoordinate
bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
Definition: PointPerspective.cpp:217
Isis::PointPerspective::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: PointPerspective.cpp:324
Isis::TProjection::IsPlanetocentric
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
Definition: TProjection.cpp:392
Isis::Projection::YCoord
double YCoord() const
This returns the projection Y provided SetGround, SetCoordinate, SetUniversalGround,...
Definition: Projection.cpp:400
Isis::Projection
Base class for Map Projections.
Definition: Projection.h:155
Isis::PointPerspective::m_sinph0
double m_sinph0
Sine of the center latitude.
Definition: PointPerspective.h:72
Isis::Projection::XCoord
double XCoord() const
This returns the projection X provided SetGround, SetCoordinate, SetUniversalGround,...
Definition: Projection.cpp:387
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16