|
Isis 3.0 Object Programmers' Reference |
Home |
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