Isis 3.0 Application Source Code Reference |
Home |
00001 #define GUIHELPERS 00002 00003 #include "Isis.h" 00004 #include "ProcessRubberSheet.h" 00005 #include "ProjectionFactory.h" 00006 #include "Projection.h" 00007 #include "map2map.h" 00008 00009 using namespace std; 00010 using namespace Isis; 00011 00012 void PrintMap(); 00013 void LoadMapRange(); 00014 00015 map <string, void *> GuiHelpers() { 00016 map <string, void *> helper; 00017 helper ["PrintMap"] = (void *) PrintMap; 00018 helper ["LoadMapRange"] = (void *) LoadMapRange; 00019 return helper; 00020 } 00021 00022 void IsisMain() { 00023 // We will be warping a cube 00024 ProcessRubberSheet p; 00025 00026 // Get the map projection file provided by the user 00027 UserInterface &ui = Application::GetUserInterface(); 00028 Pvl userPvl(ui.GetFilename("MAP")); 00029 PvlGroup &userMappingGrp = userPvl.FindGroup("Mapping", Pvl::Traverse); 00030 00031 // Open the input cube and get the projection 00032 Cube *icube = p.SetInputCube("FROM"); 00033 00034 // Get the mapping group 00035 PvlGroup fromMappingGrp = icube->getGroup("Mapping"); 00036 Projection *inproj = icube->getProjection(); 00037 PvlGroup outMappingGrp = fromMappingGrp; 00038 00039 // If the default range is FROM, then wipe out any range data in user mapping file 00040 if(ui.GetString("DEFAULTRANGE").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { 00041 if(userMappingGrp.HasKeyword("MinimumLatitude")) { 00042 userMappingGrp.DeleteKeyword("MinimumLatitude"); 00043 } 00044 00045 if(userMappingGrp.HasKeyword("MaximumLatitude")) { 00046 userMappingGrp.DeleteKeyword("MaximumLatitude"); 00047 } 00048 00049 if(userMappingGrp.HasKeyword("MinimumLongitude")) { 00050 userMappingGrp.DeleteKeyword("MinimumLongitude"); 00051 } 00052 00053 if(userMappingGrp.HasKeyword("MaximumLongitude")) { 00054 userMappingGrp.DeleteKeyword("MaximumLongitude"); 00055 } 00056 } 00057 00058 // Deal with user overrides entered in the GUI. Do this by changing the user's mapping group, which 00059 // will then overlay anything in the output mapping group. 00060 if(ui.WasEntered("MINLAT") && !ui.GetBoolean("MATCHMAP")) { 00061 userMappingGrp.AddKeyword(PvlKeyword("MinimumLatitude", ui.GetDouble("MINLAT")), Pvl::Replace); 00062 } 00063 00064 if(ui.WasEntered("MAXLAT") && !ui.GetBoolean("MATCHMAP")) { 00065 userMappingGrp.AddKeyword(PvlKeyword("MaximumLatitude", ui.GetDouble("MAXLAT")), Pvl::Replace); 00066 } 00067 00068 if(ui.WasEntered("MINLON") && !ui.GetBoolean("MATCHMAP")) { 00069 userMappingGrp.AddKeyword(PvlKeyword("MinimumLongitude", ui.GetDouble("MINLON")), Pvl::Replace); 00070 } 00071 00072 if(ui.WasEntered("MAXLON") && !ui.GetBoolean("MATCHMAP")) { 00073 userMappingGrp.AddKeyword(PvlKeyword("MaximumLongitude", ui.GetDouble("MAXLON")), Pvl::Replace); 00074 } 00075 00076 /** 00077 * If the user is changing from positive east to positive west, or vice-versa, the output minimum is really 00078 * the input maximum. However, the user mapping group must be left unaffected (an input minimum must be the 00079 * output minimum). To accomplish this, we swap the minimums/maximums in the output group ahead of time. This 00080 * causes the minimums and maximums to correlate to the output minimums and maximums. That way when we copy 00081 * the user mapping group into the output group a mimimum overrides a minimum and a maximum overrides a maximum. 00082 */ 00083 bool sameDirection = true; 00084 if(userMappingGrp.HasKeyword("LongitudeDirection")) { 00085 if(((string)userMappingGrp["LongitudeDirection"]).compare(fromMappingGrp["LongitudeDirection"]) != 0) { 00086 sameDirection = false; 00087 } 00088 } 00089 00090 // Since the out mapping group came from the from mapping group, which came from a valid cube, 00091 // we can assume both min/max lon exists if min longitude exists. 00092 if(!sameDirection && outMappingGrp.HasKeyword("MinimumLongitude")) { 00093 double minLon = outMappingGrp["MinimumLongitude"]; 00094 double maxLon = outMappingGrp["MaximumLongitude"]; 00095 00096 outMappingGrp["MaximumLongitude"] = minLon; 00097 outMappingGrp["MinimumLongitude"] = maxLon; 00098 } 00099 00100 if(ui.GetString("PIXRES").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { 00101 // Resolution will be in fromMappingGrp and outMappingGrp at this time 00102 // delete from user mapping grp 00103 if(userMappingGrp.HasKeyword("Scale")) { 00104 userMappingGrp.DeleteKeyword("Scale"); 00105 } 00106 00107 if(userMappingGrp.HasKeyword("PixelResolution")) { 00108 userMappingGrp.DeleteKeyword("PixelResolution"); 00109 } 00110 } 00111 else if(ui.GetString("PIXRES").compare("MAP") == 0 || ui.GetBoolean("MATCHMAP")) { 00112 // Resolution will be in userMappingGrp - delete all others 00113 if(outMappingGrp.HasKeyword("Scale")) { 00114 outMappingGrp.DeleteKeyword("Scale"); 00115 } 00116 00117 if(outMappingGrp.HasKeyword("PixelResolution")) { 00118 outMappingGrp.DeleteKeyword("PixelResolution"); 00119 } 00120 00121 if(fromMappingGrp.HasKeyword("Scale")); 00122 { 00123 fromMappingGrp.DeleteKeyword("Scale"); 00124 } 00125 00126 if(fromMappingGrp.HasKeyword("PixelResolution")) { 00127 fromMappingGrp.DeleteKeyword("PixelResolution"); 00128 } 00129 } 00130 else if(ui.GetString("PIXRES").compare("MPP") == 0) { 00131 // Resolution specified - delete all and add to outMappingGrp 00132 if(outMappingGrp.HasKeyword("Scale")) { 00133 outMappingGrp.DeleteKeyword("Scale"); 00134 } 00135 00136 if(outMappingGrp.HasKeyword("PixelResolution")) { 00137 outMappingGrp.DeleteKeyword("PixelResolution"); 00138 } 00139 00140 if(fromMappingGrp.HasKeyword("Scale")) { 00141 fromMappingGrp.DeleteKeyword("Scale"); 00142 } 00143 00144 if(fromMappingGrp.HasKeyword("PixelResolution")) { 00145 fromMappingGrp.DeleteKeyword("PixelResolution"); 00146 } 00147 00148 if(userMappingGrp.HasKeyword("Scale")) { 00149 userMappingGrp.DeleteKeyword("Scale"); 00150 } 00151 00152 if(userMappingGrp.HasKeyword("PixelResolution")) { 00153 userMappingGrp.DeleteKeyword("PixelResolution"); 00154 } 00155 00156 outMappingGrp.AddKeyword(PvlKeyword("PixelResolution", ui.GetDouble("RESOLUTION"), "meters/pixel"), Pvl::Replace); 00157 } 00158 else if(ui.GetString("PIXRES").compare("PPD") == 0) { 00159 // Resolution specified - delete all and add to outMappingGrp 00160 if(outMappingGrp.HasKeyword("Scale")) { 00161 outMappingGrp.DeleteKeyword("Scale"); 00162 } 00163 00164 if(outMappingGrp.HasKeyword("PixelResolution")) { 00165 outMappingGrp.DeleteKeyword("PixelResolution"); 00166 } 00167 00168 if(fromMappingGrp.HasKeyword("Scale")) { 00169 fromMappingGrp.DeleteKeyword("Scale"); 00170 } 00171 00172 if(fromMappingGrp.HasKeyword("PixelResolution")) { 00173 fromMappingGrp.DeleteKeyword("PixelResolution"); 00174 } 00175 00176 if(userMappingGrp.HasKeyword("Scale")) { 00177 userMappingGrp.DeleteKeyword("Scale"); 00178 } 00179 00180 if(userMappingGrp.HasKeyword("PixelResolution")) { 00181 userMappingGrp.DeleteKeyword("PixelResolution"); 00182 } 00183 00184 outMappingGrp.AddKeyword(PvlKeyword("Scale", ui.GetDouble("RESOLUTION"), "pixels/degree"), Pvl::Replace); 00185 } 00186 00187 // Rotation will NOT Propagate 00188 if(outMappingGrp.HasKeyword("Rotation")) { 00189 outMappingGrp.DeleteKeyword("Rotation"); 00190 } 00191 00192 00193 /** 00194 * The user specified map template file overrides what ever is in the 00195 * cube's mapping group. 00196 */ 00197 for(int keyword = 0; keyword < userMappingGrp.Keywords(); keyword ++) { 00198 outMappingGrp.AddKeyword(userMappingGrp[keyword], Pvl::Replace); 00199 } 00200 00201 /** 00202 * Now, we have to deal with unit conversions. We convert only if the following are true: 00203 * 1) We used values from the input cube 00204 * 2) The values are longitudes or latitudes 00205 * 3) The map file or user-specified information uses a different measurement system than 00206 * the input cube for said values. 00207 * 00208 * The data is corrected for: 00209 * 1) Positive east/positive west 00210 * 2) Longitude domain 00211 * 3) planetographic/planetocentric. 00212 */ 00213 00214 // First, the longitude direction 00215 if(!sameDirection) { 00216 PvlGroup longitudes = inproj->MappingLongitudes(); 00217 00218 for(int index = 0; index < longitudes.Keywords(); index ++) { 00219 if(!userMappingGrp.HasKeyword(longitudes[index].Name())) { 00220 // use the from domain because that's where our values are coming from 00221 if(((string)userMappingGrp["LongitudeDirection"]).compare("PositiveEast") == 0) { 00222 outMappingGrp[longitudes[index].Name()] = 00223 Projection::ToPositiveEast(outMappingGrp[longitudes[index].Name()], outMappingGrp["LongitudeDomain"]); 00224 } 00225 else { 00226 outMappingGrp[longitudes[index].Name()] = 00227 Projection::ToPositiveWest(outMappingGrp[longitudes[index].Name()], outMappingGrp["LongitudeDomain"]); 00228 } 00229 } 00230 } 00231 } 00232 00233 // Second, longitude domain 00234 if(userMappingGrp.HasKeyword("LongitudeDomain")) { // user set a new domain? 00235 if((int)userMappingGrp["LongitudeDomain"] != (int)fromMappingGrp["LongitudeDomain"]) { // new domain different? 00236 PvlGroup longitudes = inproj->MappingLongitudes(); 00237 00238 for(int index = 0; index < longitudes.Keywords(); index ++) { 00239 if(!userMappingGrp.HasKeyword(longitudes[index].Name())) { 00240 if((int)userMappingGrp["LongitudeDomain"] == 180) { 00241 outMappingGrp[longitudes[index].Name()] = Projection::To180Domain(outMappingGrp[longitudes[index].Name()]); 00242 } 00243 else { 00244 outMappingGrp[longitudes[index].Name()] = Projection::To360Domain(outMappingGrp[longitudes[index].Name()]); 00245 } 00246 } 00247 } 00248 00249 } 00250 } 00251 00252 // Third, planetographic/planetocentric 00253 if(userMappingGrp.HasKeyword("LatitudeType")) { // user set a new domain? 00254 if(((string)userMappingGrp["LatitudeType"]).compare(fromMappingGrp["LatitudeType"]) != 0) { // new lat type different? 00255 00256 PvlGroup latitudes = inproj->MappingLatitudes(); 00257 00258 for(int index = 0; index < latitudes.Keywords(); index ++) { 00259 if(!userMappingGrp.HasKeyword(latitudes[index].Name())) { 00260 if(((string)userMappingGrp["LatitudeType"]).compare("Planetographic") == 0) { 00261 outMappingGrp[latitudes[index].Name()] = Projection::ToPlanetographic( 00262 (double)fromMappingGrp[latitudes[index].Name()], 00263 (double)fromMappingGrp["EquatorialRadius"], 00264 (double)fromMappingGrp["PolarRadius"]); 00265 } 00266 else { 00267 outMappingGrp[latitudes[index].Name()] = Projection::ToPlanetocentric( 00268 (double)fromMappingGrp[latitudes[index].Name()], 00269 (double)fromMappingGrp["EquatorialRadius"], 00270 (double)fromMappingGrp["PolarRadius"]); 00271 } 00272 } 00273 } 00274 00275 } 00276 } 00277 00278 // Try a couple equivalent longitudes to fix the ordering of min,max for border cases 00279 if ((double)outMappingGrp["MinimumLongitude"] >= 00280 (double)outMappingGrp["MaximumLongitude"]) { 00281 00282 if ((string)outMappingGrp["MinimumLongitude"] == "180.0" && 00283 (int)userMappingGrp["LongitudeDomain"] == 180) 00284 outMappingGrp["MinimumLongitude"] = "-180"; 00285 00286 if ((string)outMappingGrp["MaximumLongitude"] == "-180.0" && 00287 (int)userMappingGrp["LongitudeDomain"] == 180) 00288 outMappingGrp["MaximumLongitude"] = "180"; 00289 00290 if ((string)outMappingGrp["MinimumLongitude"] == "360.0" && 00291 (int)userMappingGrp["LongitudeDomain"] == 360) 00292 outMappingGrp["MinimumLongitude"] = "0"; 00293 00294 if ((string)outMappingGrp["MaximumLongitude"] == "0.0" && 00295 (int)userMappingGrp["LongitudeDomain"] == 360) 00296 outMappingGrp["MaximumLongitude"] = "360"; 00297 } 00298 00299 // If MinLon/MaxLon out of order, we weren't able to calculate the correct values 00300 if((double)outMappingGrp["MinimumLongitude"] >= (double)outMappingGrp["MaximumLongitude"]) { 00301 if(!ui.WasEntered("MINLON") || !ui.WasEntered("MAXLON")) { 00302 string msg = "Unable to determine the correct [MinimumLongitude,MaximumLongitude]."; 00303 msg += " Please specify these values in the [MINLON,MAXLON] parameters"; 00304 throw iException::Message(iException::Pvl, msg, _FILEINFO_); 00305 } 00306 } 00307 00308 int samples, lines; 00309 Pvl mapData; 00310 // Copy to preserve cube labels so we can match cube size 00311 if(userPvl.HasObject("IsisCube")) { 00312 mapData = userPvl; 00313 mapData.FindObject("IsisCube").DeleteGroup("Mapping"); 00314 mapData.FindObject("IsisCube").AddGroup(outMappingGrp); 00315 } 00316 else { 00317 mapData.AddGroup(outMappingGrp); 00318 } 00319 00320 // *NOTE: The UpperLeftX,UpperLeftY keywords will not be used in the CreateForCube 00321 // method, and they will instead be recalculated. This is correct. 00322 Projection *outproj = ProjectionFactory::CreateForCube(mapData, samples, lines, 00323 ui.GetBoolean("MATCHMAP")); 00324 00325 // Set up the transform object which will simply map 00326 // output line/samps -> output lat/lons -> input line/samps 00327 Transform *transform = new map2map(icube->getSampleCount(), 00328 icube->getLineCount(), 00329 icube->getProjection(), 00330 samples, 00331 lines, 00332 outproj, 00333 ui.GetBoolean("TRIM")); 00334 00335 // Allocate the output cube and add the mapping labels 00336 Cube *ocube = p.SetOutputCube("TO", transform->OutputSamples(), 00337 transform->OutputLines(), 00338 icube->getBandCount()); 00339 00340 PvlGroup cleanOutGrp = outproj->Mapping(); 00341 00342 // ProjectionFactory::CreateForCube updated mapData to have the correct 00343 // upperleftcornerx, upperleftcornery, scale and resolution. Use these 00344 // updated numbers. 00345 cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping", Pvl::Traverse)["UpperLeftCornerX"], Pvl::Replace); 00346 cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping", Pvl::Traverse)["UpperLeftCornerY"], Pvl::Replace); 00347 cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping", Pvl::Traverse)["Scale"], Pvl::Replace); 00348 cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping", Pvl::Traverse)["PixelResolution"], Pvl::Replace); 00349 00350 ocube->putGroup(cleanOutGrp); 00351 00352 // Set up the interpolator 00353 Interpolator *interp; 00354 if(ui.GetString("INTERP") == "NEARESTNEIGHBOR") { 00355 interp = new Interpolator(Interpolator::NearestNeighborType); 00356 } 00357 else if(ui.GetString("INTERP") == "BILINEAR") { 00358 interp = new Interpolator(Interpolator::BiLinearType); 00359 } 00360 else if(ui.GetString("INTERP") == "CUBICCONVOLUTION") { 00361 interp = new Interpolator(Interpolator::CubicConvolutionType); 00362 } 00363 else { 00364 string msg = "Unknow value for INTERP [" + ui.GetString("INTERP") + "]"; 00365 throw iException::Message(iException::Programmer, msg, _FILEINFO_); 00366 } 00367 00368 // Warp the cube 00369 p.StartProcess(*transform, *interp); 00370 p.EndProcess(); 00371 00372 Application::Log(cleanOutGrp); 00373 00374 // Cleanup 00375 delete transform; 00376 delete interp; 00377 } 00378 00379 // Transform object constructor 00380 map2map::map2map(const int inputSamples, const int inputLines, Projection *inmap, 00381 const int outputSamples, const int outputLines, Projection *outmap, 00382 bool trim) { 00383 p_inputSamples = inputSamples; 00384 p_inputLines = inputLines; 00385 p_inmap = inmap; 00386 00387 p_outputSamples = outputSamples; 00388 p_outputLines = outputLines; 00389 p_outmap = outmap; 00390 00391 p_trim = trim; 00392 00393 p_inputWorldSize = 0; 00394 bool wrapPossible = inmap->IsEquatorialCylindrical(); 00395 00396 if(inmap->IsEquatorialCylindrical()) { 00397 // Figure out how many samples 360 degrees is 00398 wrapPossible = wrapPossible && inmap->SetUniversalGround(0, 0); 00399 int worldStart = (int)(inmap->WorldX() + 0.5); 00400 wrapPossible = wrapPossible && inmap->SetUniversalGround(0, 180); 00401 int worldEnd = (int)(inmap->WorldX() + 0.5); 00402 00403 p_inputWorldSize = abs(worldEnd - worldStart) * 2; 00404 } 00405 } 00406 00407 // Transform method mapping output line/samps to lat/lons to input line/samps 00408 bool map2map::Xform(double &inSample, double &inLine, 00409 const double outSample, const double outLine) { 00410 // See if the output image coordinate converts to lat/lon 00411 if(!p_outmap->SetWorld(outSample, outLine)) return false; 00412 00413 // See if we should trim 00414 if((p_trim) && (p_outmap->HasGroundRange())) { 00415 if(p_outmap->Latitude() < p_outmap->MinimumLatitude()) return false; 00416 if(p_outmap->Latitude() > p_outmap->MaximumLatitude()) return false; 00417 if(p_outmap->Longitude() < p_outmap->MinimumLongitude()) return false; 00418 if(p_outmap->Longitude() > p_outmap->MaximumLongitude()) return false; 00419 } 00420 00421 // Get the universal lat/lon and see if it can be converted to input line/samp 00422 double lat = p_outmap->UniversalLatitude(); 00423 double lon = p_outmap->UniversalLongitude(); 00424 if(!p_inmap->SetUniversalGround(lat, lon)) return false; 00425 00426 inSample = p_inmap->WorldX(); 00427 inLine = p_inmap->WorldY(); 00428 00429 if(p_inputWorldSize != 0) { 00430 // Try to correct the sample if we can, 00431 // this is the simplest way to code the 00432 // translation although it probably could 00433 // be done in one "if" 00434 while(inSample < 0.5) { 00435 inSample += p_inputWorldSize; 00436 } 00437 00438 while(inSample > p_inputSamples + 0.5) { 00439 inSample -= p_inputWorldSize; 00440 } 00441 } 00442 00443 // Make sure the point is inside the input image 00444 if(inSample < 0.5) return false; 00445 if(inLine < 0.5) return false; 00446 if(inSample > p_inputSamples + 0.5) return false; 00447 if(inLine > p_inputLines + 0.5) return false; 00448 00449 // Everything is good 00450 return true; 00451 } 00452 00453 int map2map::OutputSamples() const { 00454 return p_outputSamples; 00455 } 00456 00457 int map2map::OutputLines() const { 00458 return p_outputLines; 00459 } 00460 00461 00462 // Helper function to print out mapfile to session log 00463 void PrintMap() { 00464 UserInterface &ui = Application::GetUserInterface(); 00465 00466 // Get mapping group from map file 00467 Pvl userMap; 00468 userMap.Read(ui.GetFilename("MAP")); 00469 PvlGroup &userGrp = userMap.FindGroup("Mapping", Pvl::Traverse); 00470 00471 //Write map file out to the log 00472 Isis::Application::GuiLog(userGrp); 00473 } 00474 00475 void LoadMapRange() { 00476 UserInterface &ui = Application::GetUserInterface(); 00477 00478 // Get map file 00479 Pvl userMap; 00480 00481 try { 00482 userMap.Read(ui.GetFilename("MAP")); 00483 } 00484 catch(iException &e) { 00485 e.Clear(); 00486 } 00487 00488 // Get input cube 00489 Pvl fromMap; 00490 00491 try { 00492 fromMap.Read(ui.GetFilename("FROM")); 00493 } 00494 catch(iException &e) { 00495 e.Clear(); 00496 } 00497 00498 // Try to get the mapping groups 00499 PvlGroup fromMapping("Mapping"); 00500 00501 try { 00502 fromMapping = fromMap.FindGroup("Mapping", Pvl::Traverse); 00503 } 00504 catch(iException &e) { 00505 e.Clear(); 00506 } 00507 00508 PvlGroup userMapping("Mapping"); 00509 00510 try { 00511 userMapping = userMap.FindGroup("Mapping", Pvl::Traverse); 00512 } 00513 catch(iException &e) { 00514 e.Clear(); 00515 } 00516 00517 // Do conversions on from map 00518 00519 // Longitude conversions first 00520 if(userMapping.HasKeyword("LongitudeDirection")) { 00521 if(((string)userMapping["LongitudeDirection"]).compare(fromMapping["LongitudeDirection"]) != 0) { 00522 double minLon = fromMapping["MinimumLongitude"]; 00523 double maxLon = fromMapping["MaximumLongitude"]; 00524 int domain = fromMapping["LongitudeDomain"]; 00525 00526 if(userMapping.HasKeyword("LongitudeDomain")) { 00527 domain = userMapping["LongitudeDomain"]; 00528 } 00529 00530 if((string)userMapping["LongitudeDirection"] == "PositiveEast") { 00531 fromMapping["MaximumLongitude"] = Projection::ToPositiveEast(minLon, domain); 00532 fromMapping["MinimumLongitude"] = Projection::ToPositiveEast(maxLon, domain); 00533 } 00534 else if((string)userMapping["LongitudeDirection"] == "PositiveWest") { 00535 fromMapping["MaximumLongitude"] = Projection::ToPositiveWest(minLon, domain); 00536 fromMapping["MinimumLongitude"] = Projection::ToPositiveWest(maxLon, domain); 00537 } 00538 } 00539 } 00540 00541 // Latitude conversions now 00542 if(userMapping.HasKeyword("LatitudeType")) { // user set a new domain? 00543 if(((string)userMapping["LatitudeType"]).compare(fromMapping["LatitudeType"]) != 0) { // new lat type different? 00544 if(((string)userMapping["LatitudeType"]).compare("Planetographic") == 0) { 00545 fromMapping["MinimumLatitude"] = Projection::ToPlanetographic( 00546 (double)fromMapping["MinimumLatitude"], 00547 (double)fromMapping["EquatorialRadius"], 00548 (double)fromMapping["PolarRadius"]); 00549 fromMapping["MaximumLatitude"] = Projection::ToPlanetographic( 00550 (double)fromMapping["MaximumLatitude"], 00551 (double)fromMapping["EquatorialRadius"], 00552 (double)fromMapping["PolarRadius"]); 00553 } 00554 else { 00555 fromMapping["MinimumLatitude"] = Projection::ToPlanetocentric( 00556 (double)fromMapping["MinimumLatitude"], 00557 (double)fromMapping["EquatorialRadius"], 00558 (double)fromMapping["PolarRadius"]); 00559 fromMapping["MaximumLatitude"] = Projection::ToPlanetocentric( 00560 (double)fromMapping["MaximumLatitude"], 00561 (double)fromMapping["EquatorialRadius"], 00562 (double)fromMapping["PolarRadius"]); 00563 } 00564 } 00565 } 00566 00567 // Failed at longitudes, use our originals! 00568 if((double)fromMapping["MinimumLongitude"] >= (double)fromMapping["MaximumLongitude"]) { 00569 try { 00570 fromMapping["MinimumLongitude"] = fromMap.FindGroup("Mapping", Pvl::Traverse)["MinimumLongitude"]; 00571 fromMapping["MaximumLongitude"] = fromMap.FindGroup("Mapping", Pvl::Traverse)["MaximumLongitude"]; 00572 } 00573 catch(iException &e) { 00574 e.Clear(); 00575 } 00576 } 00577 00578 // Overlay lat/lons in map file (if DEFAULTRANGE=MAP) 00579 if(ui.GetString("DEFAULTRANGE") == "MAP") { 00580 if(userMapping.HasKeyword("MinimumLatitude")) { 00581 fromMapping["MinimumLatitude"] = userMapping["MinimumLatitude"]; 00582 } 00583 00584 if(userMapping.HasKeyword("MaximumLatitude")) { 00585 fromMapping["MaximumLatitude"] = userMapping["MaximumLatitude"]; 00586 } 00587 00588 if(userMapping.HasKeyword("MinimumLongitude")) { 00589 fromMapping["MinimumLongitude"] = userMapping["MinimumLongitude"]; 00590 } 00591 00592 if(userMapping.HasKeyword("MaximumLongitude")) { 00593 fromMapping["MaximumLongitude"] = userMapping["MaximumLongitude"]; 00594 } 00595 } 00596 00597 if(ui.WasEntered("MINLAT")) { 00598 ui.Clear("MINLAT"); 00599 } 00600 00601 if(ui.WasEntered("MAXLAT")) { 00602 ui.Clear("MAXLAT"); 00603 } 00604 00605 if(ui.WasEntered("MINLON")) { 00606 ui.Clear("MINLON"); 00607 } 00608 00609 if(ui.WasEntered("MAXLON")) { 00610 ui.Clear("MAXLON"); 00611 } 00612 00613 ui.PutDouble("MINLAT", fromMapping["MinimumLatitude"]); 00614 ui.PutDouble("MAXLAT", fromMapping["MaximumLatitude"]); 00615 ui.PutDouble("MINLON", fromMapping["MinimumLongitude"]); 00616 ui.PutDouble("MAXLON", fromMapping["MaximumLongitude"]); 00617 }