|
Isis 3.0 Application Source Code Reference |
Home |
00001 #define GUIHELPERS 00002 00003 #include "Isis.h" 00004 #include "Camera.h" 00005 #include "ProjectionFactory.h" 00006 #include "ProcessRubberSheet.h" 00007 #include "iException.h" 00008 #include "cam2map.h" 00009 00010 using namespace std; 00011 using namespace Isis; 00012 00013 void PrintMap (); 00014 void LoadMapRes (); 00015 void LoadCameraRes (); 00016 void LoadMapRange (); 00017 void LoadCameraRange (); 00018 00019 map <string,void*> GuiHelpers(){ 00020 map <string,void*> helper; 00021 helper ["PrintMap"] = (void*) PrintMap; 00022 helper ["LoadMapRes"] = (void*) LoadMapRes; 00023 helper ["LoadCameraRes"] = (void*) LoadCameraRes; 00024 helper ["LoadMapRange"] = (void*) LoadMapRange; 00025 helper ["LoadCameraRange"] = (void*) LoadCameraRange; 00026 return helper; 00027 } 00028 00029 00030 // Global variables 00031 void BandChange (const int band); 00032 Cube *icube; 00033 Camera *incam; 00034 00035 void IsisMain() { 00036 // We will be warping a cube 00037 ProcessRubberSheet p; 00038 00039 // Get the map projection file provided by the user 00040 UserInterface &ui = Application::GetUserInterface(); 00041 Pvl userMap; 00042 userMap.Read(ui.GetFilename("MAP")); 00043 PvlGroup &userGrp = userMap.FindGroup("Mapping",Pvl::Traverse); 00044 00045 // Open the input cube and get the camera 00046 icube = p.SetInputCube ("FROM"); 00047 incam = icube->Camera(); 00048 00049 // Make sure it is not the sky 00050 if (incam->IsSky()) { 00051 string msg = "The image [" + ui.GetFilename("FROM") + 00052 "] is targeting the sky, use skymap instead."; 00053 throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_); 00054 } 00055 00056 // Get the mapping grop 00057 Pvl camMap; 00058 incam->BasicMapping(camMap); 00059 PvlGroup &camGrp = camMap.FindGroup("Mapping"); 00060 00061 00062 // Make the target info match the user mapfile 00063 double minlat,maxlat,minlon,maxlon; 00064 incam->GroundRange(minlat,maxlat,minlon,maxlon,userMap); 00065 camGrp.AddKeyword(PvlKeyword("MinimumLatitude",minlat),Pvl::Replace); 00066 camGrp.AddKeyword(PvlKeyword("MaximumLatitude",maxlat),Pvl::Replace); 00067 camGrp.AddKeyword(PvlKeyword("MinimumLongitude",minlon),Pvl::Replace); 00068 camGrp.AddKeyword(PvlKeyword("MaximumLongitude",maxlon),Pvl::Replace); 00069 00070 00071 // We want to delete the keywords we just added if the user wants the range 00072 // out of the mapfile, otherwise they will replace any keywords not in the 00073 // mapfile 00074 if (ui.GetString("DEFAULTRANGE") == "MAP" || ui.GetBoolean("MATCHMAP")) { 00075 camGrp.DeleteKeyword("MinimumLatitude"); 00076 camGrp.DeleteKeyword("MaximumLatitude"); 00077 camGrp.DeleteKeyword("MinimumLongitude"); 00078 camGrp.DeleteKeyword("MaximumLongitude"); 00079 } 00080 // Otherwise, remove the keywords from the map file so the camera keywords 00081 // will be propogated correctly 00082 else { 00083 while (userGrp.HasKeyword("MinimumLatitude")) { 00084 userGrp.DeleteKeyword("MinimumLatitude"); 00085 } 00086 while (userGrp.HasKeyword("MinimumLongitude")) { 00087 userGrp.DeleteKeyword("MinimumLongitude"); 00088 } 00089 while (userGrp.HasKeyword("MaximumLatitude")) { 00090 userGrp.DeleteKeyword("MaximumLatitude"); 00091 } 00092 while (userGrp.HasKeyword("MaximumLongitude")) { 00093 userGrp.DeleteKeyword("MaximumLongitude"); 00094 } 00095 } 00096 00097 // If the user decided to enter a ground range then override 00098 if (ui.WasEntered("MINLON") && !ui.GetBoolean("MATCHMAP")) { 00099 userGrp.AddKeyword(PvlKeyword("MinimumLongitude", 00100 ui.GetDouble("MINLON")),Pvl::Replace); 00101 } 00102 00103 if (ui.WasEntered("MAXLON") && !ui.GetBoolean("MATCHMAP")) { 00104 userGrp.AddKeyword(PvlKeyword("MaximumLongitude", 00105 ui.GetDouble("MAXLON")),Pvl::Replace); 00106 } 00107 00108 if (ui.WasEntered("MINLAT") && !ui.GetBoolean("MATCHMAP")) { 00109 userGrp.AddKeyword(PvlKeyword("MinimumLatitude", 00110 ui.GetDouble("MINLAT")),Pvl::Replace); 00111 } 00112 00113 if (ui.WasEntered("MAXLAT") && !ui.GetBoolean("MATCHMAP")) { 00114 userGrp.AddKeyword(PvlKeyword("MaximumLatitude", 00115 ui.GetDouble("MAXLAT")),Pvl::Replace); 00116 } 00117 00118 // If they want the res. from the mapfile, delete it from the camera so 00119 // nothing gets overriden 00120 if (ui.GetString("PIXRES") == "MAP" || ui.GetBoolean("MATCHMAP")) { 00121 camGrp.DeleteKeyword("PixelResolution"); 00122 } 00123 // Otherwise, delete any resolution keywords from the mapfile so the camera 00124 // info is propogated over 00125 else if (ui.GetString("PIXRES") == "CAMERA") { 00126 if (userGrp.HasKeyword("Scale")) { 00127 userGrp.DeleteKeyword("Scale"); 00128 } 00129 if (userGrp.HasKeyword("PixelResolution")) { 00130 userGrp.DeleteKeyword("PixelResolution"); 00131 } 00132 } 00133 00134 // Copy any defaults that are not in the user map from the camera map file 00135 for (int k=0; k<camGrp.Keywords(); k++) { 00136 if (!userGrp.HasKeyword(camGrp[k].Name())) { 00137 userGrp += camGrp[k]; 00138 } 00139 } 00140 00141 // If the user decided to enter a resolution then override 00142 if (ui.GetString("PIXRES") == "MPP" && !ui.GetBoolean("MATCHMAP")) { 00143 userGrp.AddKeyword(PvlKeyword("PixelResolution", 00144 ui.GetDouble("RESOLUTION")), 00145 Pvl::Replace); 00146 if (userGrp.HasKeyword("Scale")) { 00147 userGrp.DeleteKeyword("Scale"); 00148 } 00149 } 00150 else if (ui.GetString("PIXRES") == "PPD" && !ui.GetBoolean("MATCHMAP")) { 00151 userGrp.AddKeyword(PvlKeyword("Scale", 00152 ui.GetDouble("RESOLUTION")), 00153 Pvl::Replace); 00154 if (userGrp.HasKeyword("PixelResolution")) { 00155 userGrp.DeleteKeyword("PixelResolution"); 00156 } 00157 } 00158 00159 // See if the user want us to handle the longitude seam 00160 if ((ui.GetString("DEFAULTRANGE") == "CAMERA" || ui.GetString("DEFAULTRANGE") == "MINIMIZE") && 00161 !ui.GetBoolean("MATCHMAP")) { 00162 if (incam->IntersectsLongitudeDomain(userMap)) { 00163 if (ui.GetString("LONSEAM") == "AUTO") { 00164 if ((int) userGrp["LongitudeDomain"] == 360) { 00165 userGrp.AddKeyword(PvlKeyword("LongitudeDomain",180), 00166 Pvl::Replace); 00167 if (incam->IntersectsLongitudeDomain(userMap)) { 00168 // Its looks like a global image so switch back to the 00169 // users preference 00170 userGrp.AddKeyword(PvlKeyword("LongitudeDomain",360), 00171 Pvl::Replace); 00172 } 00173 } 00174 else { 00175 userGrp.AddKeyword(PvlKeyword("LongitudeDomain",360), 00176 Pvl::Replace); 00177 if (incam->IntersectsLongitudeDomain(userMap)) { 00178 // Its looks like a global image so switch back to the 00179 // users preference 00180 userGrp.AddKeyword(PvlKeyword("LongitudeDomain",180), 00181 Pvl::Replace); 00182 } 00183 } 00184 // Make the target info match the new longitude domain 00185 double minlat,maxlat,minlon,maxlon; 00186 incam->GroundRange(minlat,maxlat,minlon,maxlon,userMap); 00187 if( !ui.WasEntered("MINLAT") ) { 00188 userGrp.AddKeyword(PvlKeyword("MinimumLatitude",minlat),Pvl::Replace); 00189 } 00190 if( !ui.WasEntered("MAXLAT") ) { 00191 userGrp.AddKeyword(PvlKeyword("MaximumLatitude",maxlat),Pvl::Replace); 00192 } 00193 if( !ui.WasEntered("MINLON") ) { 00194 userGrp.AddKeyword(PvlKeyword("MinimumLongitude",minlon),Pvl::Replace); 00195 } 00196 if( !ui.WasEntered("MAXLON") ) { 00197 userGrp.AddKeyword(PvlKeyword("MaximumLongitude",maxlon),Pvl::Replace); 00198 } 00199 } 00200 00201 else if (ui.GetString("LONSEAM") == "ERROR") { 00202 string msg = "The image [" + ui.GetFilename("FROM") + "] crosses the " + 00203 "longitude seam"; 00204 throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_); 00205 } 00206 } 00207 } 00208 00209 // Use the updated label to create the output projection 00210 int samples,lines; 00211 Projection *outmap; 00212 bool trim; 00213 00214 // Determine the image size 00215 if (ui.GetString("DEFAULTRANGE") == "MINIMIZE" && !ui.GetBoolean("MATCHMAP")) { 00216 outmap = ProjectionFactory::CreateForCube(userMap,samples,lines,*incam); 00217 trim = false; 00218 } 00219 else if (ui.GetString("DEFAULTRANGE") == "CAMERA" && !ui.GetBoolean("MATCHMAP")) { 00220 outmap = ProjectionFactory::CreateForCube(userMap,samples,lines,false); 00221 trim = ui.GetBoolean("TRIM"); 00222 } 00223 else { // DEFAULTRANGE = MAP 00224 outmap = ProjectionFactory::CreateForCube(userMap,samples,lines, 00225 ui.GetBoolean("MATCHMAP")); 00226 trim = ui.GetBoolean("TRIM"); 00227 } 00228 00229 int tileStart, tileEnd; 00230 incam->GetGeometricTilingHint(tileStart, tileEnd); 00231 p.SetTiling(tileStart, tileEnd); 00232 00233 // Output the mapping group used to the Gui session log 00234 Application::GuiLog(userMap); 00235 00236 // Set up the transform object which will simply map 00237 // output line/samps -> output lat/lons -> input line/samps 00238 Transform *transform = new cam2map (icube->Samples(), 00239 icube->Lines(), 00240 incam, 00241 samples, 00242 lines, 00243 outmap, 00244 trim); 00245 00246 // Allocate the output cube and add the mapping labels 00247 Cube *ocube = p.SetOutputCube ("TO", transform->OutputSamples(), 00248 transform->OutputLines(), 00249 icube->Bands()); 00250 ocube->PutGroup(userGrp); 00251 00252 // Set up the interpolator 00253 Interpolator *interp = NULL; 00254 if (ui.GetString("INTERP") == "NEARESTNEIGHBOR") { 00255 interp = new Interpolator(Interpolator::NearestNeighborType); 00256 } 00257 else if (ui.GetString("INTERP") == "BILINEAR") { 00258 interp = new Interpolator(Interpolator::BiLinearType); 00259 } 00260 else if (ui.GetString("INTERP") == "CUBICCONVOLUTION") { 00261 interp = new Interpolator(Interpolator::CubicConvolutionType); 00262 } 00263 00264 // See if we need to deal with band dependent camera models 00265 if (!incam->IsBandIndependent()) { 00266 p.BandChange(BandChange); 00267 } 00268 00269 // See if center of input image projects. If it does, force tile 00270 // containing this center to be processed in ProcessRubberSheet. 00271 double centerSamp = icube->Samples () / 2.; 00272 double centerLine = icube->Lines () / 2.; 00273 if (incam->SetImage(centerSamp,centerLine)) { 00274 if (outmap->SetUniversalGround(incam->UniversalLatitude(), 00275 incam->UniversalLongitude())) { 00276 p.ForceTile (outmap->WorldX(),outmap->WorldY ()); 00277 } 00278 } 00279 // Create an alpha cube group for the output cube 00280 if (!ocube->HasGroup("AlphaCube")) { 00281 PvlGroup alpha("AlphaCube"); 00282 alpha += PvlKeyword("AlphaSamples",icube->Samples()); 00283 alpha += PvlKeyword("AlphaLines",icube->Lines()); 00284 alpha += PvlKeyword("AlphaStartingSample",0.5); 00285 alpha += PvlKeyword("AlphaStartingLine",0.5); 00286 alpha += PvlKeyword("AlphaEndingSample",icube->Samples()+0.5); 00287 alpha += PvlKeyword("AlphaEndingLine",icube->Lines()+0.5); 00288 alpha += PvlKeyword("BetaSamples",icube->Samples()); 00289 alpha += PvlKeyword("BetaLines",icube->Lines()); 00290 ocube->PutGroup(alpha); 00291 } 00292 00293 // Warp the cube 00294 p.StartProcess(*transform, *interp); 00295 p.EndProcess(); 00296 00297 // add mapping to print.prt 00298 PvlGroup mapping = outmap->Mapping(); 00299 Application::Log(mapping); 00300 00301 // Cleanup 00302 delete outmap; 00303 delete transform; 00304 delete interp; 00305 } 00306 00307 // Transform object constructor 00308 cam2map::cam2map (const int inputSamples, const int inputLines, 00309 Camera *incam, const int outputSamples, 00310 const int outputLines, Projection *outmap, 00311 bool trim) { 00312 p_inputSamples = inputSamples; 00313 p_inputLines = inputLines; 00314 p_incam = incam; 00315 00316 p_outputSamples = outputSamples; 00317 p_outputLines = outputLines; 00318 p_outmap = outmap; 00319 00320 p_trim = trim; 00321 } 00322 00323 // Transform method mapping output line/samps to lat/lons to input line/samps 00324 bool cam2map::Xform (double &inSample, double &inLine, 00325 const double outSample, const double outLine) { 00326 // See if the output image coordinate converts to lat/lon 00327 if (!p_outmap->SetWorld(outSample,outLine)) return false; 00328 00329 // See if we should trim 00330 if ((p_trim) && (p_outmap->HasGroundRange())) { 00331 if (p_outmap->Latitude() < p_outmap->MinimumLatitude()) return false; 00332 if (p_outmap->Latitude() > p_outmap->MaximumLatitude()) return false; 00333 if (p_outmap->Longitude() < p_outmap->MinimumLongitude()) return false; 00334 if (p_outmap->Longitude() > p_outmap->MaximumLongitude()) return false; 00335 } 00336 00337 // Get the universal lat/lon and see if it can be converted to input line/samp 00338 double lat = p_outmap->UniversalLatitude(); 00339 double lon = p_outmap->UniversalLongitude(); 00340 00341 if (!p_incam->SetUniversalGround(lat,lon)) return false; 00342 00343 // Make sure the point is inside the input image 00344 if (p_incam->Sample() < 0.5) return false; 00345 if (p_incam->Line() < 0.5) return false; 00346 if (p_incam->Sample() > p_inputSamples + 0.5) return false; 00347 if (p_incam->Line() > p_inputLines + 0.5) return false; 00348 00349 // Everything is good 00350 inSample = p_incam->Sample(); 00351 inLine = p_incam->Line(); 00352 00353 return true; 00354 } 00355 00356 int cam2map::OutputSamples () const { 00357 return p_outputSamples; 00358 } 00359 00360 int cam2map::OutputLines () const { 00361 return p_outputLines; 00362 } 00363 00364 void BandChange (const int band) { 00365 incam->SetBand(band); 00366 } 00367 00368 // Helper function to print out mapfile to session log 00369 void PrintMap() { 00370 UserInterface &ui = Application::GetUserInterface(); 00371 00372 // Get mapping group from map file 00373 Pvl userMap; 00374 userMap.Read(ui.GetFilename("MAP")); 00375 PvlGroup &userGrp = userMap.FindGroup("Mapping",Pvl::Traverse); 00376 00377 //Write map file out to the log 00378 Isis::Application::GuiLog(userGrp); 00379 } 00380 00381 // Helper function to get mapping resolution. 00382 void LoadMapRes () { 00383 UserInterface &ui = Application::GetUserInterface(); 00384 00385 // Get mapping group from map file 00386 Pvl userMap; 00387 userMap.Read(ui.GetFilename("MAP")); 00388 PvlGroup &userGrp = userMap.FindGroup("Mapping",Pvl::Traverse); 00389 00390 // Set resolution 00391 if (userGrp.HasKeyword("Scale")) { 00392 ui.Clear("RESOLUTION"); 00393 ui.PutDouble("RESOLUTION",userGrp["Scale"]); 00394 ui.Clear("PIXRES"); 00395 ui.PutAsString("PIXRES","PPD"); 00396 } 00397 else if (userGrp.HasKeyword("PixelResolution")) { 00398 ui.Clear("RESOLUTION"); 00399 ui.PutDouble("RESOLUTION",userGrp["PixelResolution"]); 00400 ui.Clear("PIXRES"); 00401 ui.PutAsString("PIXRES","MPP"); 00402 } 00403 else { 00404 string msg = "No resolution value found in [" + ui.GetFilename("MAP") + "]"; 00405 throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_); 00406 } 00407 } 00408 00409 //Helper function to get camera resolution. 00410 void LoadCameraRes () { 00411 UserInterface &ui = Application::GetUserInterface(); 00412 string file = ui.GetFilename("FROM"); 00413 00414 // Open the input cube, get the camera object, and the cam map projection 00415 Cube c; 00416 c.Open(file); 00417 Camera *cam = c.Camera(); 00418 Pvl camMap; 00419 cam->BasicMapping(camMap); 00420 PvlGroup &camGrp = camMap.FindGroup("Mapping"); 00421 00422 ui.Clear("RESOLUTION"); 00423 ui.PutDouble("RESOLUTION",camGrp["PixelResolution"]); 00424 00425 ui.Clear("PIXRES"); 00426 ui.PutAsString("PIXRES","MPP"); 00427 } 00428 00429 //Helper function to get ground range from map file. 00430 void LoadMapRange() { 00431 UserInterface &ui = Application::GetUserInterface(); 00432 00433 // Get map file 00434 Pvl userMap; 00435 userMap.Read(ui.GetFilename("MAP")); 00436 PvlGroup &userGrp = userMap.FindGroup("Mapping",Pvl::Traverse); 00437 00438 // Set ground range keywords that are found in mapfile 00439 int count = 0; 00440 ui.Clear("MINLAT"); 00441 ui.Clear("MAXLAT"); 00442 ui.Clear("MINLON"); 00443 ui.Clear("MAXLON"); 00444 if (userGrp.HasKeyword("MinimumLatitude")) { 00445 ui.PutDouble("MINLAT",userGrp["MinimumLatitude"]); 00446 count++; 00447 } 00448 if (userGrp.HasKeyword("MaximumLatitude")) { 00449 ui.PutDouble("MAXLAT",userGrp["MaximumLatitude"]); 00450 count++; 00451 } 00452 if (userGrp.HasKeyword("MinimumLongitude")) { 00453 ui.PutDouble("MINLON",userGrp["MinimumLongitude"]); 00454 count++; 00455 } 00456 if (userGrp.HasKeyword("MaximumLongitude")) { 00457 ui.PutDouble("MAXLON",userGrp["MaximumLongitude"]); 00458 count++; 00459 } 00460 00461 // Set default ground range param to map 00462 ui.Clear("DEFAULTRANGE"); 00463 ui.PutAsString("DEFAULTRANGE","MAP"); 00464 00465 if (count < 4) { 00466 string msg = "One or more of the values for the ground range was not found"; 00467 msg += " in [" + ui.GetFilename("MAP") + "]"; 00468 throw Isis::iException::Message(Isis::iException::User,msg,_FILEINFO_); 00469 } 00470 } 00471 00472 //Helper function to load camera range. 00473 void LoadCameraRange () { 00474 UserInterface &ui = Application::GetUserInterface(); 00475 string file = ui.GetFilename("FROM"); 00476 00477 // Get the map projection file provided by the user 00478 Pvl userMap; 00479 userMap.Read(ui.GetFilename("MAP")); 00480 00481 // Open the input cube, get the camera object, and the cam map projection 00482 Cube c; 00483 c.Open(file); 00484 Camera *cam = c.Camera(); 00485 00486 // Make the target info match the user mapfile 00487 double minlat,maxlat,minlon,maxlon; 00488 cam->GroundRange(minlat,maxlat,minlon,maxlon,userMap); 00489 00490 // Set ground range parameters in UI 00491 ui.Clear("MINLAT"); 00492 ui.PutDouble("MINLAT",minlat); 00493 ui.Clear("MAXLAT"); 00494 ui.PutDouble("MAXLAT",maxlat); 00495 ui.Clear("MINLON"); 00496 ui.PutDouble("MINLON",minlon); 00497 ui.Clear("MAXLON"); 00498 ui.PutDouble("MAXLON",maxlon); 00499 00500 // Set default ground range param to camera 00501 ui.Clear("DEFAULTRANGE"); 00502 ui.PutAsString("DEFAULTRANGE","CAMERA"); 00503 } 00504