|
Isis 3 Programmer Reference
|
7 #include "UpturnedEllipsoidTransverseAzimuthal.h"
16 #include "Constants.h"
17 #include "IException.h"
19 #include "TProjection.h"
22 #include "PvlKeyword.h"
23 #include "SpecialPixel.h"
47 UpturnedEllipsoidTransverseAzimuthal::UpturnedEllipsoidTransverseAzimuthal(Pvl &label,
49 TProjection::TProjection(label) {
57 PvlGroup &mapGroup = label.findGroup(
"Mapping",
Pvl::Traverse);
61 double centerLongitude = 0.0;
62 if (!mapGroup.hasKeyword(
"CenterLongitude")) {
65 mapGroup += PvlKeyword(
"CenterLongitude",
toString(centerLongitude),
"Degrees");
68 QString message =
"Cannot project using upturned ellipsoid Transverse Azimuthal";
69 message +=
" without [CenterLongitude] value. Keyword does not exist";
70 message +=
" in labels and defaults are not allowed.";
75 centerLongitude = mapGroup[
"CenterLongitude"];
78 if (MinimumLongitude() < centerLongitude - 90.0) {
79 QString message =
"MinimumLongitude ["
81 +
"] is invalid. Must be within -90 degrees of the CenterLongitude ["
85 if (MaximumLongitude() > centerLongitude + 90.0) {
86 QString message =
"MaximumLongitude ["
88 +
"] is invalid. Must be within +90 degrees of the CenterLongitude ["
95 init(centerLongitude);
97 catch(IException &e) {
98 QString message =
"Invalid label group [Mapping]";
109 UpturnedEllipsoidTransverseAzimuthal::~UpturnedEllipsoidTransverseAzimuthal() {
128 UpturnedEllipsoidTransverseAzimuthal *tcyl = (UpturnedEllipsoidTransverseAzimuthal *) &proj;
130 (tcyl->m_a !=
m_a) ||
131 (tcyl->m_b !=
m_b))
return false;
145 return "UpturnedEllipsoidUpturnedEllipsoidTransverseAzimuthal";
170 void UpturnedEllipsoidTransverseAzimuthal::init(
double centerLongitude) {
197 m_a = qMax(axis1, axis2);
198 m_b = qMin(axis1, axis2);
201 if (qFuzzyCompare(0.0,
m_e)) {
245 if (qFuzzyCompare(90.0, qAbs(lat)) && qAbs(lat) > 90.0) {
246 phiNorm = copysign(
HALFPI, lat);
249 else if (qAbs(lat) > 90.0) {
275 double cosz = cos(phiNorm) * cos(lambdaNorm);
293 else if (cosz > 0.5) {
295 double sinz = sqrt( 1 - cosz*cosz );
299 double phi =
HALFPI - atan2( sinz,
m_t * cosz );
300 double sinPhi = sin(phi);
307 double rhoOverTanZ =
m_k * sinPhi / ( ( 1 + sinPhi )
309 * exp(
m_t1 * atan(
m_t1 * sinPhi ) ) );
310 x = rhoOverTanZ * tan(lambdaNorm);
311 y = rhoOverTanZ * (sin(phiNorm) / cosz );
327 double tolerance = 0.0016;
328 double coszmax = cos(
PI - tolerance);
329 double lambdaModulus = fmod(lambdaNorm,
TWOPI);
330 if (cosz < coszmax) {
337 if (-
PI - tolerance < lambdaModulus && lambdaModulus <= -
PI) {
338 lambdaNorm = -
PI - tolerance;
344 else if (-
PI < lambdaModulus && lambdaModulus <= -
PI + tolerance) {
345 lambdaNorm = -
PI + tolerance;
351 else if (
PI - tolerance < lambdaModulus && lambdaModulus <=
PI) {
352 lambdaNorm =
PI - tolerance;
358 else if (
PI < lambdaModulus && lambdaModulus <
PI + tolerance) {
359 lambdaNorm =
PI + tolerance;
363 double sinz = sqrt( 1 - cosz*cosz );
369 double phi = atan2(
m_t * cosz, sinz );
370 double sinPhi = sin(phi);
375 double rhoOverSinZ =
m_k * cos(phi) / ( ( 1 + sinPhi )
377 * exp(
m_t1 * atan(
m_t1 * sinPhi ) ) );
378 x = rhoOverSinZ * cos(phiNorm) * sin(lambdaNorm);
379 y = rhoOverSinZ * sin(phiNorm);
418 if (qFuzzyCompare(x + 1.0, 1.0) && qFuzzyCompare(y + 1.0, 1.0)) {
449 double phi0, fphi0, fprimephi0, phi1;
450 bool converged =
false;
452 double tolerance = 10e-10;
454 while (!converged && iterations < 1000) {
455 fphi0 =
m_k * cos(phi0) / ((1 + sin(phi0)) * exp(
m_t1 * atan(
m_t1 * sin(phi0) )))
460 * exp(
m_t1 * atan(
m_t1 * sin(phi0) ))
461 * (1 +
m_t1 *
m_t1 * sin(phi0) * sin(phi0)));
462 phi1 = phi0 - fphi0 / fprimephi0;
464 if (qAbs(phi1) >
HALFPI) {
466 if (phiDegrees > 90.0) {
469 if (phiDegrees < -180.0) {
474 if (qAbs(phi0 - phi1) < tolerance) {
496 double z = atan2((1 -
m_e *
m_e), tan(phi));
504 double rho = sqrt(x*x + y*y);
505 double phiNorm = asin( y * sin(z) / rho );
512 double cosLambdaNorm = cos(z) / cos(phiNorm);
513 if (cosLambdaNorm > 1.0) {
516 else if (cosLambdaNorm < -1.0) {
519 else if (x >= 0 && y >= 0) {
520 lambdaNorm = acos(cosLambdaNorm);
522 else if (x < 0 && y >= 0) {
523 lambdaNorm = -acos(cosLambdaNorm);
525 else if (y < 0 && x >= 0) {
526 lambdaNorm = acos(cosLambdaNorm);
529 lambdaNorm = -acos(cosLambdaNorm);
597 double &minY,
double &maxY) {
612 if (centerLongitudeInRange) {
616 if (centerLongitude90InRange) {
620 if (centerLongitude180InRange) {
624 if (centerLongitude270InRange) {
632 if (centerLongitudeInRange) {
635 if (centerLongitude90InRange) {
638 if (centerLongitude180InRange) {
641 if (centerLongitude270InRange) {
748 bool allowDefaults) {
double m_maximumLatitude
Contains the maximum latitude for the entire ground range.
const double HALFPI
The mathematical constant PI/2.
double m_longitude
This contains the currently set longitude value.
int m_longitudeDomain
This integer is either 180 or 360 and is read from the labels.
double m_minimumLongitude
Contains the minimum longitude for the entire ground range.
double m_latitude
This contains the currently set latitude value.
static double ToPositiveWest(const double lon, const int domain)
This method converts a longitude into the positive west direction.
bool IsPositiveWest() const
This indicates if the longitude direction type is positive east (as opposed to postive west).
const double PI
The mathematical constant PI.
double m_t1
Auxiliary value used to reduce calculations.
Upturned Ellipsoid Transverse Azimuthal Map Projection.
double m_minimumLatitude
Contains the minimum latitude for the entire ground range.
const double DEG2RAD
Multiplier for converting from degrees to radians.
@ Unknown
A type of error that cannot be classified as any of the other error types.
double m_minimumY
See minimumX description.
double m_t
Auxiliary value used to reduce calculations.
virtual 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...
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
const double TWOPI
Two * PI, a complete revolution.
Container for cube-like labels.
double Eccentricity() const
This returns the eccentricity of the target,.
void SetXY(double x, double y)
This protected method is a helper for derived classes.
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude.
void XYRangeCheck(const double latitude, const double longitude)
This convience function is established to assist in the development of the XYRange virtual method.
double EquatorialRadius() const
This returns the equatorial radius of the target.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
double m_lambda0
The longitude of the center of the projection.
@ Traverse
Search child objects.
bool inLongitudeRange(double longitude)
Determine whether the given longitude is within the range of the MinimumLongitude and MaximumLongitud...
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
bool operator==(const Projection &proj)
This method determines whether two map projection objects are equal by comparing the equatorial radiu...
bool IsPositiveEast() const
This indicates if the longitude direction type is positive west (as opposed to postive east).
double PolarRadius() const
This returns the polar radius of the target.
double m_k
The radius of the Equator of the transverse graticule on the Azimuthal projection under the condition...
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
static double To180Domain(const double lon)
This method converts a longitude into the -180 to 180 domain.
bool Has180Domain() const
This indicates if the longitude domain is -180 to 180 (as opposed to 0 to 360).
double m_b
Semi-minor axis of the ellipse.
const double Null
Value for an Isis Null pixel.
bool inLatitudeRange(double latitude)
Determine whether the given latitude is within the range of the MinimumLatitude and MaximumLatitude r...
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
Namespace for the standard library.
virtual bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
double m_maximumLongitude
Contains the maximum longitude for the entire ground range.
static double ToPositiveEast(const double lon, const int domain)
This method converts a longitude into the positive east direction.
virtual QString Version() const
This method returns the Version of the map projection.
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
double m_e
Eccentricity of the ellipse.
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
static double To360Domain(const double lon)
This method converts a longitude into the 0 to 360 domain.
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
double m_maximumY
See minimumX description.
Base class for Map Projections.
double m_maximumX
See minimumX description.
double m_a
Semi-major axis of the ellipse.
const double RAD2DEG
Multiplier for converting from radians to degrees.
virtual bool SetGround(const double lat, const double lon)
This method is used to set the latitude/longitude (assumed to be of the correct LatitudeType,...
virtual QString Name() const
This method returns the name of the map projection.
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
This is free and unencumbered software released into the public domain.