63 UpturnedEllipsoidTransverseAzimuthal::UpturnedEllipsoidTransverseAzimuthal(Pvl &label,
65 TProjection::TProjection(label) {
73 PvlGroup &mapGroup = label.findGroup(
"Mapping",
Pvl::Traverse);
77 double centerLongitude = 0.0;
78 if (!mapGroup.hasKeyword(
"CenterLongitude")) {
81 mapGroup += PvlKeyword(
"CenterLongitude",
toString(centerLongitude),
"Degrees");
84 QString message =
"Cannot project using upturned ellipsoid Transverse Azimuthal";
85 message +=
" without [CenterLongitude] value. Keyword does not exist";
86 message +=
" in labels and defaults are not allowed.";
91 centerLongitude = mapGroup[
"CenterLongitude"];
94 if (MinimumLongitude() < centerLongitude - 90.0) {
95 QString message =
"MinimumLongitude [" 97 +
"] is invalid. Must be within -90 degrees of the CenterLongitude [" 101 if (MaximumLongitude() > centerLongitude + 90.0) {
102 QString message =
"MaximumLongitude [" 104 +
"] is invalid. Must be within +90 degrees of the CenterLongitude [" 111 init(centerLongitude);
113 catch(IException &e) {
114 QString message =
"Invalid label group [Mapping]";
125 UpturnedEllipsoidTransverseAzimuthal::~UpturnedEllipsoidTransverseAzimuthal() {
144 UpturnedEllipsoidTransverseAzimuthal *tcyl = (UpturnedEllipsoidTransverseAzimuthal *) &proj;
146 (tcyl->m_a !=
m_a) ||
147 (tcyl->m_b !=
m_b))
return false;
161 return "UpturnedEllipsoidUpturnedEllipsoidTransverseAzimuthal";
186 void UpturnedEllipsoidTransverseAzimuthal::init(
double centerLongitude) {
213 m_a = qMax(axis1, axis2);
214 m_b = qMin(axis1, axis2);
217 if (qFuzzyCompare(0.0,
m_e)) {
261 if (qFuzzyCompare(90.0, qAbs(lat)) && qAbs(lat) > 90.0) {
262 phiNorm = copysign(
HALFPI, lat);
265 else if (qAbs(lat) > 90.0) {
291 double cosz = cos(phiNorm) * cos(lambdaNorm);
309 else if (cosz > 0.5) {
311 double sinz = sqrt( 1 - cosz*cosz );
315 double phi =
HALFPI - atan2( sinz,
m_t * cosz );
316 double sinPhi = sin(phi);
323 double rhoOverTanZ =
m_k * sinPhi / ( ( 1 + sinPhi )
325 * exp(
m_t1 * atan(
m_t1 * sinPhi ) ) );
326 x = rhoOverTanZ * tan(lambdaNorm);
327 y = rhoOverTanZ * (sin(phiNorm) / cosz );
343 double tolerance = 0.0016;
344 double coszmax = cos(
PI - tolerance);
345 double lambdaModulus = fmod(lambdaNorm,
TWOPI);
346 if (cosz < coszmax) {
353 if (-
PI - tolerance < lambdaModulus && lambdaModulus <= -
PI) {
354 lambdaNorm = -
PI - tolerance;
360 else if (-
PI < lambdaModulus && lambdaModulus <= -
PI + tolerance) {
361 lambdaNorm = -
PI + tolerance;
367 else if (
PI - tolerance < lambdaModulus && lambdaModulus <=
PI) {
368 lambdaNorm =
PI - tolerance;
374 else if (
PI < lambdaModulus && lambdaModulus <
PI + tolerance) {
375 lambdaNorm =
PI + tolerance;
379 double sinz = sqrt( 1 - cosz*cosz );
385 double phi = atan2(
m_t * cosz, sinz );
386 double sinPhi = sin(phi);
391 double rhoOverSinZ =
m_k * cos(phi) / ( ( 1 + sinPhi )
393 * exp(
m_t1 * atan(
m_t1 * sinPhi ) ) );
394 x = rhoOverSinZ * cos(phiNorm) * sin(lambdaNorm);
395 y = rhoOverSinZ * sin(phiNorm);
434 if (qFuzzyCompare(x + 1.0, 1.0) && qFuzzyCompare(y + 1.0, 1.0)) {
465 double phi0, fphi0, fprimephi0, phi1;
466 bool converged =
false;
468 double tolerance = 10e-10;
470 while (!converged && iterations < 1000) {
471 fphi0 =
m_k * cos(phi0) / ((1 + sin(phi0)) * exp(
m_t1 * atan(
m_t1 * sin(phi0) )))
476 * exp(
m_t1 * atan(
m_t1 * sin(phi0) ))
477 * (1 +
m_t1 *
m_t1 * sin(phi0) * sin(phi0)));
478 phi1 = phi0 - fphi0 / fprimephi0;
480 if (qAbs(phi1) >
HALFPI) {
482 if (phiDegrees > 90.0) {
485 if (phiDegrees < -180.0) {
490 if (qAbs(phi0 - phi1) < tolerance) {
512 double z = atan2((1 -
m_e *
m_e), tan(phi));
520 double rho = sqrt(x*x + y*y);
521 double phiNorm = asin( y * sin(z) / rho );
528 double cosLambdaNorm = cos(z) / cos(phiNorm);
529 if (cosLambdaNorm > 1.0) {
532 else if (cosLambdaNorm < -1.0) {
535 else if (x >= 0 && y >= 0) {
536 lambdaNorm = acos(cosLambdaNorm);
538 else if (x < 0 && y >= 0) {
539 lambdaNorm = -acos(cosLambdaNorm);
541 else if (y < 0 && x >= 0) {
542 lambdaNorm = acos(cosLambdaNorm);
545 lambdaNorm = -acos(cosLambdaNorm);
613 double &minY,
double &maxY) {
628 if (centerLongitudeInRange) {
632 if (centerLongitude90InRange) {
636 if (centerLongitude180InRange) {
640 if (centerLongitude270InRange) {
648 if (centerLongitudeInRange) {
651 if (centerLongitude90InRange) {
654 if (centerLongitude180InRange) {
657 if (centerLongitude270InRange) {
764 bool allowDefaults) {
double EquatorialRadius() const
This returns the equatorial radius of the target.
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, LongitudeDirection, and LongitudeDomain.
virtual QString Name() const
This method returns the name of the map projection.
bool inLatitudeRange(double latitude)
Determine whether the given latitude is within the range of the MinimumLatitude and MaximumLatitude r...
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
const double Null
Value for an Isis Null pixel.
const double PI
The mathematical constant PI.
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...
bool IsPositiveEast() const
This indicates if the longitude direction type is positive west (as opposed to postive east)...
const double HALFPI
The mathematical constant PI/2.
Namespace for the standard library.
double m_k
The radius of the Equator of the transverse graticule on the Azimuthal projection under the condition...
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
virtual QString Version() const
This method returns the Version of the map projection.
bool inLongitudeRange(double longitude)
Determine whether the given longitude is within the range of the MinimumLongitude and MaximumLongitud...
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
double m_a
Semi-major axis of the ellipse.
double m_t
Auxiliary value used to reduce calculations.
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes.
double m_latitude
This contains the currently set latitude value.
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses.
virtual PvlGroup MappingLongitudes()
This function returns the longitude keywords that this projection uses.
virtual bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y.
double m_maximumY
See minimumX description.
double m_longitude
This contains the currently set longitude value.
bool IsPlanetocentric() const
This indicates if the latitude type is planetocentric (as opposed to planetographic).
double m_e
Eccentricity of the ellipse.
double m_maximumLongitude
Contains the maximum longitude for the entire ground range.
double m_minimumLatitude
Contains the minimum latitude for the entire ground range.
static double ToPositiveWest(const double lon, const int domain)
This method converts a longitude into the positive west direction.
double m_maximumLatitude
Contains the maximum latitude for the entire ground range.
Base class for Map Projections.
double m_minimumY
See minimumX description.
double Eccentricity() const
This returns the eccentricity of the target,.
const double TWOPI
Two * PI, a complete revolution.
int m_longitudeDomain
This integer is either 180 or 360 and is read from the labels.
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).
Upturned Ellipsoid Transverse Azimuthal Map Projection.
#define _FILEINFO_
Macro for the filename and line number.
bool operator==(const Projection &proj)
This method determines whether two map projection objects are equal by comparing the equatorial radiu...
A type of error that cannot be classified as any of the other error types.
double m_lambda0
The longitude of the center of the projection.
Container for cube-like labels.
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
const double DEG2RAD
Multiplier for converting from degrees to radians.
bool m_good
Indicates if the contents of m_x, m_y, m_latitude, and m_longitude are valid.
static double To360Domain(const double lon)
This method converts a longitude into the 0 to 360 domain.
bool IsPositiveWest() const
This indicates if the longitude direction type is positive east (as opposed to postive west)...
double PolarRadius() const
This returns the polar radius of the target.
Namespace for ISIS/Bullet specific routines.
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses.
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude.
const double RAD2DEG
Multiplier for converting from radians to degrees.
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.
double m_b
Semi-minor axis of the ellipse.
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.
double m_t1
Auxiliary value used to reduce calculations.
double m_maximumX
See minimumX description.
static double ToPositiveEast(const double lon, const int domain)
This method converts a longitude into the positive east direction.