121         QString msg = 
"Projection failed. No target radii are available "   122                       "through keywords [EquatorialRadius and PolarRadius] "   129         QString msg = 
"Projection failed. Invalid value for keyword "   130                       "[EquatorialRadius]. It must be greater than zero";
   134         QString msg = 
"Projection failed. Invalid value for keyword "   135                       "[PolarRadius]. It must be greater than zero";
   140       if ((QString) 
m_mappingGrp[
"LatitudeType"] == 
"Planetographic") {
   143       else if ((QString) 
m_mappingGrp[
"LatitudeType"] == 
"Planetocentric") {
   147         QString msg = 
"Projection failed. Invalid value for keyword "   148                       "[LatitudeType] must be "   149                       "[Planetographic or Planetocentric]";
   154       if ((QString) 
m_mappingGrp[
"LongitudeDirection"] == 
"PositiveWest") {
   157       else if ((QString) 
m_mappingGrp[
"LongitudeDirection"] == 
"PositiveEast") {
   161         QString msg = 
"Projection failed. Invalid value for keyword "   162                       "[LongitudeDirection] must be "   163                       "[PositiveWest or PositiveEast]";
   168       if ((QString) 
m_mappingGrp[
"LongitudeDomain"] == 
"360") {
   171       else if ((QString) 
m_mappingGrp[
"LongitudeDomain"] == 
"180") {
   175         QString msg = 
"Projection failed. Invalid value for keyword "   176                       "[LongitudeDomain] must be [180 or 360]";
   192           QString msg = 
"Projection failed. "   194                         + 
"] is outside the range of [-90:90]";
   199           QString msg = 
"Projection failed. "   201                         + 
"] is outside the range of [-90:90]";
   206           QString msg = 
"Projection failed. "   207                         "[MinimumLatitude,MaximumLatitude] of ["   210                         + 
"properly ordered";
   215           QString msg = 
"Projection failed. "   216                         "[MinimumLongitude,MaximumLongitude] of ["   219                         + 
"properly ordered";
   235         QString msg = 
"Projection failed. Invalid keyword value(s). "   237                       + 
" must be greater than or equal to [PolarRadius] = "   256       QString msg = 
"Projection failed.  Invalid label group [Mapping]";
   276     if (!Projection::operator==(proj)) 
return false;
   342     if (latitude == 
Null) {
   344                        "Unable to calculate local radius. The given latitude value ["    345                        + 
toString(latitude) + 
"] is invalid.", 
   351     if (a - c < DBL_EPSILON) {
   355       double lat = latitude * 
PI / 180.0;
   356       return  a * c / sqrt(pow(c * cos(lat), 2) + pow(a * sin(lat), 2));
   450                                       double eRadius, 
double pRadius) {
   451     if (lat == 
Null || abs(lat) > 90.0) {
   453                        "Unable to convert to Planetocentric. The given latitude value ["    458     if (abs(mylat) < 90.0) {  
   460       mylat = atan(tan(mylat) * (pRadius / eRadius) *
   461                    (pRadius / eRadius));
   496                                       double eRadius, 
double pRadius) {
   498     if (qFuzzyCompare(fabs(lat), 90.0)) {
   501     if (lat == 
Null || fabs(lat) > 90.0) {
   503                        "Unable to convert to Planetographic. The given latitude value ["    508     if (fabs(mylat) < 90.0) {  
   510       mylat = atan(tan(mylat) * (eRadius / pRadius) *
   511                    (eRadius / pRadius));
   525     return "Planetocentric";
   566                        "Unable to convert to PositiveEast. The given longitude value ["    577     else if (domain == 180) {
   581       QString msg = 
"Unable to convert longitude.  Domain [" + 
toString(domain) 
   582                     + 
"] is not 180 or 360.";
   605                        "Unable to convert to PositiveWest. The given longitude value ["    616     else if (domain == 180) {
   620       QString msg = 
"Unable to convert longitude.  Domain [" + 
toString(domain)
   621                     + 
"] is not 180 or 360.";
   637     return "PositiveWest";
   675                        "Unable to convert to 180 degree domain. The given longitude value ["    693                        "Unable to convert to 360 degree domain. The given longitude value ["    699     if ( (lon < 0.0 || lon > 360.0) &&
   700         !qFuzzyCompare(lon, 0.0) && !qFuzzyCompare(lon, 360.0)) {
  1009                            double &minY, 
double &maxY) {
  1079     if (latitude == 
Null || longitude == 
Null) {
  1120     if (adjustedMinLon > adjustedMaxLon) {
  1121       if (adjustedLon > adjustedMinLon) {
  1124       adjustedMinLon -= 360;
  1128     if (qFuzzyCompare(maxLon - minLon, 360.0)) {
  1131     else if (adjustedMinLon <= adjustedLon && adjustedLon <= adjustedMaxLon) { 
  1211                                   double &minY, 
double &maxY) {
  1223     double minFoundX1, minFoundX2;
  1224     double minFoundY1, minFoundY2;
  1240     double minFoundX3, minFoundX4;
  1241     double minFoundY3, minFoundY4;
  1257     double minFoundX5 = min(minFoundX1, minFoundX2);
  1258     double minFoundX6 = min(minFoundX3, minFoundX4);
  1261     double minFoundY5 = min(minFoundY1, minFoundY2);
  1262     double minFoundY6 = min(minFoundY3, minFoundY4);
  1266     double maxFoundX1, maxFoundX2;
  1267     double maxFoundY1, maxFoundY2;
  1283     double maxFoundX3, maxFoundX4;
  1284     double maxFoundY3, maxFoundY4;
  1300     double maxFoundX5 = max(maxFoundX1, maxFoundX2);
  1301     double maxFoundX6 = max(maxFoundX3, maxFoundX4);
  1304     double maxFoundY5 = max(maxFoundY1, maxFoundY2);
  1305     double maxFoundY6 = max(maxFoundY3, maxFoundY4);
  1310     for (
unsigned int specialLatCase = 0; 
  1311         specialLatCase < specialLatCases.size(); 
  1312         specialLatCase ++) {
  1313       double minX, maxX, minY, maxY;
  1317                minX, specialLatCases[specialLatCase], 
true,  
false, 
true);
  1320                minY, specialLatCases[specialLatCase], 
false, 
false, 
true);
  1323                maxX, specialLatCases[specialLatCase], 
true,  
false, 
false);
  1326                maxY, specialLatCases[specialLatCase], 
false, 
false, 
false);
  1335     for (
unsigned int specialLonCase = 0; 
  1336         specialLonCase < specialLonCases.size(); 
  1337         specialLonCase ++) {
  1338       double minX, maxX, minY, maxY;
  1342                minX, specialLonCases[specialLonCase], 
true,  
true, 
true);
  1345                minY, specialLonCases[specialLonCase], 
false, 
true, 
true);
  1348                maxX, specialLonCases[specialLonCase], 
true,  
true, 
false);
  1351                maxY, specialLonCases[specialLonCase], 
false, 
true, 
false);
  1413                             double &extremeVal, 
const double constBorder, 
  1414                             bool searchX, 
bool searchLongitude, 
bool findMin) {
  1415     if (minBorder == 
Null || maxBorder == 
Null || constBorder == 
Null) {
  1419     const int NUM_ATTEMPTS = (
unsigned int)DBL_DIG; 
  1422     double minBorderX, minBorderY, maxBorderX, maxBorderY;
  1426       findExtreme(minBorder, maxBorder, minBorderX, minBorderY, maxBorderX, 
  1427                   maxBorderY, constBorder, searchX, searchLongitude, findMin);
  1428       if (minBorderX == 
Null && maxBorderX == 
Null   1429           && minBorderY == 
Null && maxBorderY == 
Null ) {
  1430         attempts = NUM_ATTEMPTS;
  1435     while ((fabs(minBorderX - maxBorderX) > TOLERANCE 
  1436            || fabs(minBorderY - maxBorderY) > TOLERANCE)
  1437            && (attempts < NUM_ATTEMPTS)); 
  1442     if (attempts >= NUM_ATTEMPTS) {
  1447       if (searchLongitude) {
  1457       if (searchX) extremeVal = min(minBorderX, maxBorderX);
  1458       else         extremeVal = min(minBorderY, maxBorderY);
  1461       if (searchX) extremeVal = max(minBorderX, maxBorderX);
  1462       else         extremeVal = max(minBorderY, maxBorderY);
  1527                                double &minBorderX, 
double &minBorderY,
  1528                                double &maxBorderX, 
double &maxBorderY, 
  1529                                const double constBorder, 
bool searchX, 
  1530                                bool searchLongitude, 
bool findMin) {
  1531     if (minBorder == 
Null || maxBorder == 
Null || constBorder == 
Null) {
  1533       minBorderY = minBorderX;
  1534       minBorderY = minBorderX;
  1537     if (!searchLongitude && (fabs(fabs(constBorder) - 90.0) < DBL_EPSILON)) {
  1542       maxBorderY = minBorderY;
  1546     const double STEP_SIZE = (maxBorder - minBorder) / 10.0;
  1547     const double LOOP_END = maxBorder + (STEP_SIZE / 2.0); 
  1550     double currBorderVal = minBorder;
  1558       while (!
m_good && currBorderVal <= LOOP_END) {
  1559         currBorderVal+=STEP_SIZE;
  1560         if (searchLongitude && (currBorderVal - 90.0 > DBL_EPSILON)) {
  1561           currBorderVal = 90.0;
  1575     double border1 = currBorderVal;
  1576     double border2 = currBorderVal;
  1577     double border3 = currBorderVal;
  1583     double value2 = value1;
  1587     double extremeVal2 = value2;
  1591     double extremeBorder1 = minBorder;
  1592     double extremeBorder3 = minBorder;
  1594     while (currBorderVal <= LOOP_END) {
  1601       if (searchLongitude && (currBorderVal - 90.0 > DBL_EPSILON)) {
  1602         currBorderVal = 90.0;
  1606       currBorderVal += STEP_SIZE;
  1615       border1 = currBorderVal;                                             
  1619       if ((findMin && value2 < extremeVal2) 
  1620           || (!findMin && value2 > extremeVal2)) {
  1625         extremeVal2 = value2;
  1627         extremeBorder3 = border3;
  1628         extremeBorder1 = border1;
  1635     minBorder = extremeBorder3; 
  1640     if (extremeBorder1 <= maxBorder ) {
  1641       maxBorder = extremeBorder1; 
  1689                                    const double constBorder, 
  1690                                    bool variableIsLat) {
  1691     if (variableBorder == 
Null || constBorder == 
Null) {
  1695     if (variableIsLat) {
  1696       lat = variableBorder;
  1701       lon = variableBorder;
  1717     keyNames << 
"TargetName" << 
"ProjectionName" << 
"EquatorialRadius" << 
"PolarRadius"  1718              << 
"LatitudeType" << 
"LongitudeDirection" << 
"LongitudeDomain"  1719              << 
"PixelResolution" << 
"Scale" << 
"UpperLeftCornerX" << 
"UpperLeftCornerY"  1720              << 
"MinimumLatitude" << 
"MaximumLatitude" << 
"MinimumLongitude" << 
"MaximumLongitude"  1723     foreach (QString keyName, keyNames) {
  1787       QString msg = 
"Snyder's q variable should only be computed for "  1788                     "ellipsoidal projections.";
  1793            * (sinPhi / (1 - eSinPhi * eSinPhi) 
  1794                - 1 / (2 * 
m_eccentricity) * log( (1 - eSinPhi) / (1 + eSinPhi) ));
  1819     double localPhi = 
HALFPI - 2.0 * atan(t);
  1821     double difference = DBL_MAX;
  1828     const int MAX_ITERATIONS = 45;
  1830     while ((iteration < MAX_ITERATIONS) && (difference > 0.0000000001))  {
  1831       double eccTimesSinphi = 
Eccentricity() * sin(localPhi);
  1833                       2.0 * atan(t * pow((1.0 - eccTimesSinphi) /
  1834                                          (1.0 + eccTimesSinphi), halfEcc));
  1835       difference = fabs(newPhi - localPhi);
  1840     if (iteration >= MAX_ITERATIONS) {
  1841       QString msg = 
"Failed to converge in TProjection::phi2Compute()";
  1864     double denominator = sqrt(1.0 - eccTimesSinphi * eccTimesSinphi);
  1865     return cosphi / denominator;
  1886     if ((
HALFPI) - fabs(phi) < DBL_EPSILON) 
return 0.0;
  1889     double denominator  = pow((1.0 - eccTimesSinphi) /
  1890                               (1.0 + eccTimesSinphi),
  1892     return tan(0.5 * (
HALFPI - phi)) / denominator;
  1910     return sqrt(pow(onePlusEcc, onePlusEcc) *
  1911                 pow(oneMinusEcc, oneMinusEcc));
 double EquatorialRadius() const
This returns the equatorial radius of the target. 
 
virtual ~TProjection()
Destroys the TProjection object. 
 
bool hasKeyword(const QString &name) const
Check to see if a keyword exists. 
 
bool inLatitudeRange(double latitude)
Determine whether the given latitude is within the range of the MinimumLatitude and MaximumLatitude r...
 
double MaximumLongitude() const
This returns the maximum longitude of the area of interest. 
 
const double Null
Value for an Isis Null pixel. 
 
std::vector< double > m_specialLonCases
Constant Longitudes that intersect a discontinuity. 
 
double mCompute(const double sinphi, const double cosphi) const
A convience method to compute Snyder's m equation (14-15) for a given latitude, . ...
 
WorldMapper * m_mapper
This points to a mapper passed into the SetWorldMapper method. 
 
double tCompute(const double phi, const double sinphi) const
A convience method to compute Snyder's t equation (15-9) for a given latitude, . 
 
bool xyRangeOblique(double &minX, double &maxX, double &minY, double &maxY)
This method is used to find the XY range for oblique aspect projections (non-polar projections) by "w...
 
bool SetUniversalGround(const double lat, const double lon)
This method is used to set the latitude/longitude which must be Planetocentric (latitude) and Positiv...
 
const double PI
The mathematical constant PI. 
 
double Scale() const
This method returns the scale for mapping world coordinates into projection coordinates. 
 
bool IsPositiveEast() const
This indicates if the longitude direction type is positive west (as opposed to postive east)...
 
Longitude values increase in the westerly direction. 
 
Base class for Map TProjections. 
 
QString LatitudeTypeString() const
This method returns the latitude type as a string. 
 
const double HALFPI
The mathematical constant PI/2. 
 
virtual bool operator==(const Projection &proj)
This method determines whether two map projection objects are equal by comparing the equatorial radiu...
 
virtual bool IsEquatorialCylindrical()
This method returns true if the projection is equatorial cylindrical. 
 
double PixelResolution() const
Returns the pixel resolution value from the PVL mapping group in meters/pixel. 
 
Namespace for the standard library. 
 
std::vector< double > m_specialLatCases
Constant Latitudes that intersect a discontinuity. 
 
Latitudes are measured as the angle from the equatorial plane to the normal to the surface of the pla...
 
Longitude force180Domain() const
This returns a longitude that is constricted to -180 to 180 degrees. 
 
double UniversalLongitude()
This returns a universal longitude (positive east in 0 to 360 domain). 
 
bool IsGood() const
This indicates if the last invocation of SetGround, SetCoordinate, SetUniversalGround, or SetWorld was with successful or not. 
 
double XCoord() const
This returns the projection X provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success. 
 
double m_minimumX
The data elements m_minimumX, m_minimumY, m_maximumX, and m_maximumY are convience data elements when...
 
double m_polarRadius
Polar radius of the target. 
 
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. 
 
Unless noted otherwise, the portions of Isis written by the USGS are public domain. 
 
void SetComputedXY(double x, double y)
This protected method is a helper for derived classes. 
 
Latitudes are measured as the angle from the equatorial plane to the plane through the center of the ...
 
double m_latitude
This contains the currently set latitude value. 
 
Longitude force360Domain() const
This returns a longitude that is constricted to 0-360 degrees. 
 
void setSearchGround(const double variableBorder, const double constBorder, bool variableIsLat)
This function sets the ground for the given border values. 
 
double degrees() const
Get the angle in units of Degrees. 
 
virtual PvlGroup MappingLatitudes()
This function returns the latitude keywords that this projection uses. 
 
double MinimumLongitude() const
This returns the minimum longitude of the area of interest. 
 
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_maximumLongitude
Contains the maximum longitude for the entire ground range. 
 
This class is designed to encapsulate the concept of a Longitude. 
 
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,. 
 
Degrees are generally considered more human readable, 0-360 is one circle, however most math does not...
 
double m_equatorialRadius
Polar radius of the target. 
 
bool HasGroundRange() const
This indicates if the longitude direction type is positive west (as opposed to postive east)...
 
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). 
 
void findExtreme(double &minBorder, double &maxBorder, double &minBorderX, double &minBorderY, double &maxBorderX, double &maxBorderY, const double constBorder, bool searchX, bool searchLongitude, bool findMin)
Searches for extreme (min/max/discontinuity) coordinate values across latitudes/longitudes. 
 
bool IsPlanetographic() const
This indicates if the latitude type is planetographic (as opposed to planetocentric). 
 
double Longitude() const
This returns a longitude with correct longitude direction and domain as specified in the label object...
 
Contains multiple PvlContainers. 
 
void setProjectionType(const ProjectionType ptype)
Sets the projection subclass type. 
 
bool m_groundRangeGood
Indicates if the ground range (min/max lat/lons) were read from the labels. 
 
#define _FILEINFO_
Macro for the filename and line number. 
 
double LocalRadius() const
This method returns the local radius in meters at the current latitude position. 
 
static PvlGroup radiiGroup(QString target)
Creates a Pvl Group with keywords TargetName, EquitorialRadius, and PolarRadius. 
 
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. 
 
A type of error that cannot be classified as any of the other error types. 
 
double YCoord() const
This returns the projection Y provided SetGround, SetCoordinate, SetUniversalGround, or SetWorld returned with success. 
 
QString LongitudeDirectionString() const
This method returns the longitude direction as a string. 
 
bool Has360Domain() const
This indicates if the longitude domain is 0 to 360 (as opposed to -180 to 180). 
 
Container for cube-like labels. 
 
double ToPlanetographic(const double lat) const
This method converts a planetocentric latitude to a planetographic latitude. 
 
double phi2Compute(const double t) const
A convience method to compute latitude angle phi2 given small t, from Syder's recursive equation (7-9...
 
double MinimumLatitude() const
This returns the minimum latitude of the area of interest. 
 
virtual PvlGroup Mapping()
This function returns the keywords that this projection uses. 
 
double UniversalLatitude()
This returns a universal latitude (planetocentric). 
 
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. 
 
Unless noted otherwise, the portions of Isis written by the USGS are public domain. 
 
double e4Compute() const
A convience method to compute. 
 
LongitudeDirection m_longitudeDirection
An enumerated type indicating the LongitudeDirection read from the labels. 
 
bool IsPositiveWest() const
This indicates if the longitude direction type is positive east (as opposed to postive west)...
 
virtual bool SetCoordinate(const double x, const double y)
This method is used to set the projection x/y. 
 
double PolarRadius() const
This returns the polar radius of the target. 
 
LatitudeType m_latitudeType
An enumerated type indicating the LatitudeType read from the labels. 
 
double Latitude() const
This returns a latitude with correct latitude type as specified in the label object. 
 
double m_eccentricity
The eccentricity of the target body. 
 
Namespace for ISIS/Bullet specific routines. 
 
double ToPlanetocentric(const double lat) const
This method converts a planetographic latitude to a planetocentric latitude. 
 
QString LongitudeDomainString() const
This method returns the longitude domain as a string. 
 
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. 
 
virtual double Resolution() const
This virtual method will the resolution of the world system relative to one unit in the projection sy...
 
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. 
 
bool SetUnboundUniversalGround(const double coord1, const double coord2)
This method is used to set the latitude/longitude. 
 
double m_maximumX
See minimumX description. 
 
void doSearch(double minBorder, double maxBorder, double &extremeVal, const double constBorder, bool searchX, bool searchLongitude, bool findMin)
This method searches for extreme (min/max/discontinuity) coordinate values along the constBorder line...
 
double qCompute(const double sinPhi) const
A convience method to compute Snyder's q equation (3-12) for a given latitude, . 
 
static double ToPositiveEast(const double lon, const int domain)
This method converts a longitude into the positive east direction. 
 
Longitude values increase in the easterly direction. 
 
PvlGroup m_mappingGrp
Mapping group that created this projection. 
 
virtual double TrueScaleLatitude() const
This method returns the latitude of true scale. 
 
These projections are used to map triaxial and irregular-shaped bodies. 
 
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...
 
double MaximumLatitude() const
This returns the maximum latitude of the area of interest.