USGS

Isis 3.0 Object Programmers' Reference

Home

Equirectangular.cpp

Go to the documentation of this file.
00001 
00023 #include "Equirectangular.h"
00024 
00025 #include <cmath>
00026 #include <cfloat>
00027 
00028 #include "Constants.h"
00029 #include "IException.h"
00030 #include "Projection.h"
00031 #include "Pvl.h"
00032 #include "PvlGroup.h"
00033 #include "PvlKeyword.h"
00034 
00035 using namespace std;
00036 namespace Isis {
00055   Equirectangular::Equirectangular(Pvl &label, bool allowDefaults) :
00056     Projection::Projection(label) {
00057     try {
00058       // Try to read the mapping group
00059       PvlGroup &mapGroup = label.FindGroup("Mapping", Pvl::Traverse);
00060 
00061       // Compute the default value if allowed and needed
00062       if ((allowDefaults) && (!mapGroup.HasKeyword("CenterLongitude"))) {
00063         double lon = 0.0;
00064         mapGroup += PvlKeyword("CenterLongitude", toString(lon));
00065       }
00066 
00067       if ((allowDefaults) && (!mapGroup.HasKeyword("CenterLatitude"))) {
00068         double lat = (m_minimumLatitude + m_maximumLatitude) / 2.0;
00069         if (lat >= 65.0) {
00070           lat = 65.0;
00071         }
00072         else if (lat <= -65.0) {
00073           lat = -65.0;
00074         }
00075         else {
00076           lat = 0.0;
00077         }
00078         mapGroup += PvlKeyword("CenterLatitude", toString(lat));
00079       }
00080 
00081       // Get the center longitude, convert to radians, adjust for longitude
00082       // direction
00083       m_centerLongitude = mapGroup["CenterLongitude"];
00084       m_centerLongitude *= PI / 180.0;
00085       if (m_longitudeDirection == PositiveWest) m_centerLongitude *= -1.0;
00086 
00087       // Get the center latitude, the radius at the clat, and convert to radians
00088       m_centerLatitude = mapGroup["CenterLatitude"];
00089       m_clatRadius = LocalRadius(m_centerLatitude);
00090       m_centerLatitude *= PI / 180.0;
00091 
00092       // This keyword is just for user's information, and was put in for Hirise
00093       if (!mapGroup.HasKeyword("CenterLatitudeRadius")) {
00094         mapGroup += PvlKeyword("CenterLatitudeRadius");
00095       }
00096 
00097       mapGroup["CenterLatitudeRadius"] = toString(m_clatRadius);
00098 
00099       // Compute cos of the center latitude and make sure it is valid as
00100       // we will be dividing with it later on
00101       m_cosCenterLatitude = cos(m_centerLatitude);
00102       if (fabs(m_cosCenterLatitude) < DBL_EPSILON) {
00103         QString message = "Keyword value for CenterLatitude is "
00104                          "too close to the pole";
00105         throw IException(IException::Io, message, _FILEINFO_);
00106       }
00107     }
00108     catch(IException &e) {
00109       QString message = "Invalid label group [Mapping]";
00110       throw IException(e, IException::Io, message, _FILEINFO_);
00111     }
00112   }
00113 
00115   Equirectangular::~Equirectangular() {
00116   }
00117 
00126   bool Equirectangular::operator== (const Projection &proj) {
00127     if (!Projection::operator==(proj)) return false;
00128     // dont do the below it is a recusive plunge
00129     //  if (Projection::operator!=(proj)) return false;
00130     Equirectangular *equi = (Equirectangular *) &proj;
00131     if (equi->m_centerLongitude != m_centerLongitude) return false;
00132     if (equi->m_centerLatitude != m_centerLatitude) return false;
00133     return true;
00134   }
00135 
00141   QString Equirectangular::Name() const {
00142     return "Equirectangular";
00143   }
00144 
00150   QString Equirectangular::Version() const {
00151     return "1.0";
00152   }
00153 
00160   double Equirectangular::TrueScaleLatitude() const {
00161     return m_centerLatitude * 180.0 / PI;
00162   }
00163 
00169   bool Equirectangular::IsEquatorialCylindrical() {
00170     return true;
00171   }
00172 
00185   bool Equirectangular::SetGround(const double lat, const double lon) {
00186     // Convert to radians
00187     m_latitude = lat;
00188     m_longitude = lon;
00189     double latRadians = lat * PI / 180.0;
00190     double lonRadians = lon * PI / 180.0;
00191     if (m_longitudeDirection == PositiveWest) lonRadians *= -1.0;
00192 
00193     // Compute the coordinate
00194     double deltaLon = (lonRadians - m_centerLongitude);
00195     double x = m_clatRadius * m_cosCenterLatitude * deltaLon;
00196     double y = m_clatRadius * latRadians;
00197     SetComputedXY(x, y);
00198     m_good = true;
00199     return m_good;
00200   }
00201 
00215   bool Equirectangular::SetCoordinate(const double x, const double y) {
00216     // Save the coordinate
00217     SetXY(x, y);
00218 
00219     // Compute latitude and make sure it is not above 90
00220     m_latitude = GetY() / m_clatRadius;
00221     if ((fabs(m_latitude) - HALFPI) > DBL_EPSILON) {
00222       m_good = false;
00223       return m_good;
00224     }
00225 
00226     // Compute longitude
00227     m_longitude = m_centerLongitude +
00228                   GetX() / (m_clatRadius * m_cosCenterLatitude);
00229 
00230     // Convert to degrees
00231     m_latitude *= 180.0 / PI;
00232     m_longitude *= 180.0 / PI;
00233 
00234     // Cleanup the longitude
00235     if (m_longitudeDirection == PositiveWest) m_longitude *= -1.0;
00236     // Do these if the projection is circular
00237     //  m_longitude = To360Domain (m_longitude);
00238     //  if (m_longitudeDomain == 180) m_longitude = To180Domain(m_longitude);
00239 
00240     m_good = true;
00241     return m_good;
00242   }
00243 
00267   bool Equirectangular::XYRange(double &minX, double &maxX,
00268                                 double &minY, double &maxY) {
00269     // Check the corners of the lat/lon range
00270     XYRangeCheck(m_minimumLatitude, m_minimumLongitude);
00271     XYRangeCheck(m_maximumLatitude, m_minimumLongitude);
00272     XYRangeCheck(m_minimumLatitude, m_maximumLongitude);
00273     XYRangeCheck(m_maximumLatitude, m_maximumLongitude);
00274 
00275     // Make sure everything is ordered
00276     if (m_minimumX >= m_maximumX) return false;
00277     if (m_minimumY >= m_maximumY) return false;
00278 
00279     // Return X/Y min/maxs
00280     minX = m_minimumX;
00281     maxX = m_maximumX;
00282     minY = m_minimumY;
00283     maxY = m_maximumY;
00284     return true;
00285   }
00286 
00292   PvlGroup Equirectangular::Mapping() {
00293     PvlGroup mapping = Projection::Mapping();
00294 
00295     mapping += m_mappingGrp["CenterLatitude"];
00296     mapping += m_mappingGrp["CenterLongitude"];
00297 
00298     return mapping;
00299   }
00300 
00306   PvlGroup Equirectangular::MappingLatitudes() {
00307     PvlGroup mapping = Projection::MappingLatitudes();
00308 
00309     mapping += m_mappingGrp["CenterLatitude"];
00310 
00311     return mapping;
00312   }
00313 
00319   PvlGroup Equirectangular::MappingLongitudes() {
00320     PvlGroup mapping = Projection::MappingLongitudes();
00321 
00322     mapping += m_mappingGrp["CenterLongitude"];
00323 
00324     return mapping;
00325   }
00326 
00327 }
00328 
00341 extern "C" Isis::Projection *EquirectangularPlugin(Isis::Pvl &lab,
00342     bool allowDefaults) {
00343   return new Isis::Equirectangular(lab, allowDefaults);
00344 }
00345