/** * GetPointInfo builds the PvlGroup containing all the important * information derived from the Camera. * * @return PvlGroup* Data taken directly from the Camera and * drived from Camera information. Ownership passed. */ PvlGroup * CameraPointInfo::GetPointInfo() { CheckConditions(); Brick b(3,3,1,currentCube->PixelType()); int intSamp = (int)(camera->Sample() + 0.5); int intLine = (int)(camera->Line() + 0.5); b.SetBasePosition(intSamp, intLine, 1); currentCube->Read(b); double pB[3], spB[3], sB[3]; string utc; double ssplat, ssplon, sslat, sslon, pwlon, oglat; // Create group with ground position PvlGroup * gp = new PvlGroup("GroundPoint"); { gp->AddKeyword(PvlKeyword("Filename",currentCube->Filename())); gp->AddKeyword(PvlKeyword("Sample",camera->Sample())); gp->AddKeyword(PvlKeyword("Line",camera->Line())); gp->AddKeyword(PvlKeyword("PixelValue",PixelToString(b[0]))); gp->AddKeyword(PvlKeyword("RightAscension",camera->RightAscension())); gp->AddKeyword(PvlKeyword("Declination",camera->Declination())); gp->AddKeyword(PvlKeyword("PlanetocentricLatitude", camera->UniversalLatitude())); // Convert lat to planetographic double radii[3]; camera->Radii(radii); oglat = Isis::Projection::ToPlanetographic(camera->UniversalLatitude(), radii[0],radii[2]); gp->AddKeyword(PvlKeyword("PlanetographicLatitude",oglat)); gp->AddKeyword(PvlKeyword("PositiveEast360Longitude", camera->UniversalLongitude())); //Convert lon to -180 - 180 range gp->AddKeyword(PvlKeyword("PositiveEast180Longitude", Isis::Projection::To180Domain( camera->UniversalLongitude()))); //Convert lon to positive west pwlon = Isis::Projection::ToPositiveWest(camera->UniversalLongitude(), 360); gp->AddKeyword(PvlKeyword("PositiveWest360Longitude",pwlon)); //Convert pwlon to -180 - 180 range gp->AddKeyword(PvlKeyword("PositiveWest180Longitude", Isis::Projection::To180Domain(pwlon))); camera->Coordinate(pB); PvlKeyword coord("BodyFixedCoordinate"); coord.AddValue(pB[0],"km"); coord.AddValue(pB[1],"km"); coord.AddValue(pB[2],"km"); gp->AddKeyword(coord); gp->AddKeyword(PvlKeyword("LocalRadius",camera->LocalRadius(),"m")); gp->AddKeyword(PvlKeyword("SampleResolution",camera->SampleResolution(),"m")); gp->AddKeyword(PvlKeyword("LineResolution",camera->LineResolution(),"m")); camera->InstrumentPosition(spB); PvlKeyword spcoord("SpacecraftPosition"); spcoord.AddValue(spB[0],"km"); spcoord.AddValue(spB[1],"km"); spcoord.AddValue(spB[2],"km"); spcoord.AddComment("Spacecraft Information"); gp->AddKeyword(spcoord); gp->AddKeyword(PvlKeyword("SpacecraftAzimuth",camera->SpacecraftAzimuth())); gp->AddKeyword(PvlKeyword("SlantDistance",camera->SlantDistance(),"km")); gp->AddKeyword(PvlKeyword("TargetCenterDistance",camera->TargetCenterDistance(),"km")); camera->SubSpacecraftPoint(ssplat,ssplon); gp->AddKeyword(PvlKeyword("SubSpacecraftLatitude",ssplat)); gp->AddKeyword(PvlKeyword("SubSpacecraftLongitude",ssplon)); gp->AddKeyword(PvlKeyword("SpacecraftAltitude",camera->SpacecraftAltitude(),"km")); gp->AddKeyword(PvlKeyword("OffNadirAngle",camera->OffNadirAngle())); double subspcgrdaz; subspcgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(), ssplat,ssplon); gp->AddKeyword(PvlKeyword("SubSpacecraftGroundAzimuth",subspcgrdaz)); camera->SunPosition(sB); PvlKeyword scoord("SunPosition"); scoord.AddValue(sB[0],"km"); scoord.AddValue(sB[1],"km"); scoord.AddValue(sB[2],"km"); scoord.AddComment("Sun Information"); gp->AddKeyword(scoord); gp->AddKeyword(PvlKeyword("SubSolarAzimuth",camera->SunAzimuth())); gp->AddKeyword(PvlKeyword("SolarDistance",camera->SolarDistance(),"AU")); camera->SubSolarPoint(sslat,sslon); gp->AddKeyword(PvlKeyword("SubSolarLatitude",sslat)); gp->AddKeyword(PvlKeyword("SubSolarLongitude",sslon)); double subsolgrdaz; subsolgrdaz = camera->GroundAzimuth(camera->UniversalLatitude(),camera->UniversalLongitude(), sslat,sslon); gp->AddKeyword(PvlKeyword("SubSolarGroundAzimuth",subsolgrdaz)); PvlKeyword phase("Phase",camera->PhaseAngle()); phase.AddComment("Illumination and Other"); gp->AddKeyword(phase); gp->AddKeyword(PvlKeyword("Incidence",camera->IncidenceAngle())); gp->AddKeyword(PvlKeyword("Emission",camera->EmissionAngle())); gp->AddKeyword(PvlKeyword("NorthAzimuth",camera->NorthAzimuth())); PvlKeyword et("EphemerisTime",camera->EphemerisTime(),"seconds"); et.AddComment("Time"); gp->AddKeyword(et); iTime t(camera->EphemerisTime()); utc = t.UTC(); gp->AddKeyword(PvlKeyword("UTC",utc)); gp->AddKeyword(PvlKeyword("LocalSolarTime",camera->LocalSolarTime(),"hour")); gp->AddKeyword(PvlKeyword("SolarLongitude",camera->SolarLongitude())); } return gp; }
bool TryKernels(Cube *icube, Process &p, Kernel lk, Kernel pck, Kernel targetSpk, Kernel ck, Kernel fk, Kernel ik, Kernel sclk, Kernel spk, Kernel iak, Kernel dem, Kernel exk) { Pvl lab = *icube->Label(); // Add the new kernel files to the existing kernels group PvlKeyword lkKeyword("LeapSecond"); PvlKeyword pckKeyword("TargetAttitudeShape"); PvlKeyword targetSpkKeyword("TargetPosition"); PvlKeyword ckKeyword("InstrumentPointing"); PvlKeyword ikKeyword("Instrument"); PvlKeyword sclkKeyword("SpacecraftClock"); PvlKeyword spkKeyword("InstrumentPosition"); PvlKeyword iakKeyword("InstrumentAddendum"); PvlKeyword demKeyword("ShapeModel"); PvlKeyword exkKeyword("Extra"); for (int i=0; i<lk.size(); i++) { lkKeyword.AddValue(lk[i]); } for (int i=0; i<pck.size(); i++) { pckKeyword.AddValue(pck[i]); } for (int i=0; i<targetSpk.size(); i++) { targetSpkKeyword.AddValue(targetSpk[i]); } for (int i=0; i<ck.size(); i++) { ckKeyword.AddValue(ck[i]); } for (int i=0; i<ik.size(); i++) { ikKeyword.AddValue(ik[i]); } for (int i=0; i<sclk.size(); i++) { sclkKeyword.AddValue(sclk[i]); } for (int i=0; i<spk.size(); i++) { spkKeyword.AddValue(spk[i]); } for (int i=0; i<iak.size(); i++) { iakKeyword.AddValue(iak[i]); } for (int i=0; i<dem.size(); i++) { demKeyword.AddValue(dem[i]); } for (int i=0; i<exk.size(); i++) { exkKeyword.AddValue(exk[i]); } PvlGroup originalKernels = icube->GetGroup("Kernels"); PvlGroup currentKernels = originalKernels; currentKernels.AddKeyword(lkKeyword, Pvl::Replace); currentKernels.AddKeyword(pckKeyword, Pvl::Replace); currentKernels.AddKeyword(targetSpkKeyword, Pvl::Replace); currentKernels.AddKeyword(ckKeyword, Pvl::Replace); currentKernels.AddKeyword(ikKeyword, Pvl::Replace); currentKernels.AddKeyword(sclkKeyword, Pvl::Replace); currentKernels.AddKeyword(spkKeyword, Pvl::Replace); currentKernels.AddKeyword(iakKeyword, Pvl::Replace); currentKernels.AddKeyword(demKeyword, Pvl::Replace); // report qualities PvlKeyword spkQuality("InstrumentPositionQuality"); spkQuality.AddValue(spiceInit::kernelTypeEnum(spk.kernelType)); currentKernels.AddKeyword(spkQuality, Pvl::Replace); PvlKeyword ckQuality("InstrumentPointingQuality"); ckQuality.AddValue(spiceInit::kernelTypeEnum(ck.kernelType)); currentKernels.AddKeyword(ckQuality, Pvl::Replace); if (!exkKeyword.IsNull()) { currentKernels.AddKeyword(exkKeyword, Pvl::Replace); } else if( currentKernels.HasKeyword("EXTRA") ) { currentKernels.DeleteKeyword( "EXTRA" ); } // Get rid of old keywords from previously inited cubes if (currentKernels.HasKeyword("SpacecraftPointing")) { currentKernels.DeleteKeyword("SpacecraftPointing"); } if (currentKernels.HasKeyword("SpacecraftPosition")) { currentKernels.DeleteKeyword("SpacecraftPosition"); } if (currentKernels.HasKeyword("ElevationModel")) { currentKernels.DeleteKeyword("ElevationModel"); } if (currentKernels.HasKeyword("Frame")) { currentKernels.DeleteKeyword("Frame"); } if (currentKernels.HasKeyword("StartPadding")) { currentKernels.DeleteKeyword("StartPadding"); } if (currentKernels.HasKeyword("EndPadding")) { currentKernels.DeleteKeyword("EndPadding"); } UserInterface &ui = Application::GetUserInterface(); // Add any time padding the user specified to the spice group if(ui.GetDouble("STARTPAD") > DBL_EPSILON) { currentKernels.AddKeyword(PvlKeyword("StartPadding", ui.GetDouble("STARTPAD"), "seconds")); } if(ui.GetDouble("ENDPAD") > DBL_EPSILON) { currentKernels.AddKeyword(PvlKeyword("EndPadding", ui.GetDouble("ENDPAD"), "seconds")); } currentKernels.AddKeyword(PvlKeyword("CameraVersion",CameraFactory::CameraVersion(lab)), Pvl::Replace); // Add the modified Kernels group to the input cube labels icube->PutGroup(currentKernels); // Create the camera so we can get blobs if necessary try { Camera *cam; try { cam = icube->Camera(); Application::Log(currentKernels); } catch (iException &e) { Pvl errPvl = e.PvlErrors(); if(errPvl.Groups() > 0) { currentKernels += PvlKeyword("Error", errPvl.Group(errPvl.Groups()-1)["Message"][0]); } Application::Log(currentKernels); icube->PutGroup(originalKernels); throw e; } if (ui.GetBoolean("ATTACH")) { Table ckTable = cam->InstrumentRotation()->Cache("InstrumentPointing"); ckTable.Label() += PvlKeyword("Description", "Created by spiceinit"); ckTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<ckKeyword.Size(); i++) { ckTable.Label()["Kernels"].AddValue(ckKeyword[i]); } icube->Write(ckTable); Table spkTable = cam->InstrumentPosition()->Cache("InstrumentPosition"); spkTable.Label() += PvlKeyword("Description", "Created by spiceinit"); spkTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<spkKeyword.Size(); i++) { spkTable.Label()["Kernels"].AddValue(spkKeyword[i]); } icube->Write(spkTable); Table bodyTable = cam->BodyRotation()->Cache("BodyRotation"); bodyTable.Label() += PvlKeyword("Description", "Created by spiceinit"); bodyTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<targetSpkKeyword.Size(); i++) { bodyTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]); } for (int i=0; i<pckKeyword.Size(); i++) { bodyTable.Label()["Kernels"].AddValue(pckKeyword[i]); } bodyTable.Label() += PvlKeyword("SolarLongitude", cam->SolarLongitude()); icube->Write(bodyTable); Table sunTable = cam->SunPosition()->Cache("SunPosition"); sunTable.Label() += PvlKeyword("Description", "Created by spiceinit"); sunTable.Label() += PvlKeyword("Kernels"); for (int i=0; i<targetSpkKeyword.Size(); i++) { sunTable.Label()["Kernels"].AddValue(targetSpkKeyword[i]); } icube->Write(sunTable); // Save original kernels in keyword before changing to Table PvlKeyword origCk = currentKernels["InstrumentPointing"]; PvlKeyword origSpk = currentKernels["InstrumentPosition"]; PvlKeyword origTargPos = currentKernels["TargetPosition"]; currentKernels["InstrumentPointing"] = "Table"; for (int i=0; i<origCk.Size(); i++) { currentKernels["InstrumentPointing"].AddValue(origCk[i]); } currentKernels["InstrumentPosition"] = "Table"; for (int i=0; i<origSpk.Size(); i++) { currentKernels["InstrumentPosition"].AddValue(origSpk[i]); } currentKernels["TargetPosition"] = "Table"; for (int i=0; i<origTargPos.Size(); i++) { currentKernels["TargetPosition"].AddValue(origTargPos[i]); } icube->PutGroup(currentKernels); } //modify Kernels group only else { Pvl *label = icube->Label(); int i=0; while (i < label->Objects()) { PvlObject currObj = label->Object(i); if (currObj.IsNamed("Table")) { if (currObj["Name"][0] == iString("InstrumentPointing")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("InstrumentPosition")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("BodyRotation")) { label->DeleteObject(i); } else if (currObj["Name"][0] == iString("SunPosition")) { label->DeleteObject(i); } else { i++; } } else { i++; } } } p.WriteHistory(*icube); } catch (iException &e) { e.Clear(); icube->PutGroup(originalKernels); return false; } return true; }
void IsisMain() { // We will be warping a cube ProcessRubberSheet p; // Get the map projection file provided by the user UserInterface &ui = Application::GetUserInterface(); Pvl userPvl(ui.GetFilename("MAP")); PvlGroup &userMappingGrp = userPvl.FindGroup("Mapping",Pvl::Traverse); // Open the input cube and get the projection Cube *icube = p.SetInputCube ("FROM"); // Get the mapping group PvlGroup fromMappingGrp = icube->GetGroup("Mapping"); Projection *inproj = icube->Projection(); PvlGroup outMappingGrp = fromMappingGrp; // If the default range is FROM, then wipe out any range data in user mapping file if(ui.GetString("DEFAULTRANGE").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { if(userMappingGrp.HasKeyword("MinimumLatitude")) { userMappingGrp.DeleteKeyword("MinimumLatitude"); } if(userMappingGrp.HasKeyword("MaximumLatitude")) { userMappingGrp.DeleteKeyword("MaximumLatitude"); } if(userMappingGrp.HasKeyword("MinimumLongitude")) { userMappingGrp.DeleteKeyword("MinimumLongitude"); } if(userMappingGrp.HasKeyword("MaximumLongitude")) { userMappingGrp.DeleteKeyword("MaximumLongitude"); } } // Deal with user overrides entered in the GUI. Do this by changing the user's mapping group, which // will then overlay anything in the output mapping group. if(ui.WasEntered("MINLAT") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MinimumLatitude", ui.GetDouble("MINLAT")), Pvl::Replace ); } if(ui.WasEntered("MAXLAT") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MaximumLatitude", ui.GetDouble("MAXLAT")), Pvl::Replace ); } if(ui.WasEntered("MINLON") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MinimumLongitude", ui.GetDouble("MINLON")), Pvl::Replace ); } if(ui.WasEntered("MAXLON") && !ui.GetBoolean("MATCHMAP")) { userMappingGrp.AddKeyword( PvlKeyword("MaximumLongitude", ui.GetDouble("MAXLON")), Pvl::Replace ); } /** * If the user is changing from positive east to positive west, or vice-versa, the output minimum is really * the input maximum. However, the user mapping group must be left unaffected (an input minimum must be the * output minimum). To accomplish this, we swap the minimums/maximums in the output group ahead of time. This * causes the minimums and maximums to correlate to the output minimums and maximums. That way when we copy * the user mapping group into the output group a mimimum overrides a minimum and a maximum overrides a maximum. */ bool sameDirection = true; if(userMappingGrp.HasKeyword("LongitudeDirection")) { if(((string)userMappingGrp["LongitudeDirection"]).compare(fromMappingGrp["LongitudeDirection"]) != 0) { sameDirection = false; } } // Since the out mapping group came from the from mapping group, which came from a valid cube, // we can assume both min/max lon exists if min longitude exists. if(!sameDirection && outMappingGrp.HasKeyword("MinimumLongitude")) { double minLon = outMappingGrp["MinimumLongitude"]; double maxLon = outMappingGrp["MaximumLongitude"]; outMappingGrp["MaximumLongitude"] = minLon; outMappingGrp["MinimumLongitude"] = maxLon; } if(ui.GetString("PIXRES").compare("FROM") == 0 && !ui.GetBoolean("MATCHMAP")) { // Resolution will be in fromMappingGrp and outMappingGrp at this time // delete from user mapping grp if(userMappingGrp.HasKeyword("Scale")) { userMappingGrp.DeleteKeyword("Scale"); } if(userMappingGrp.HasKeyword("PixelResolution")) { userMappingGrp.DeleteKeyword("PixelResolution"); } } else if(ui.GetString("PIXRES").compare("MAP") == 0 || ui.GetBoolean("MATCHMAP")) { // Resolution will be in userMappingGrp - delete all others if(outMappingGrp.HasKeyword("Scale")) { outMappingGrp.DeleteKeyword("Scale"); } if(outMappingGrp.HasKeyword("PixelResolution")) { outMappingGrp.DeleteKeyword("PixelResolution"); } if(fromMappingGrp.HasKeyword("Scale")); { fromMappingGrp.DeleteKeyword("Scale"); } if(fromMappingGrp.HasKeyword("PixelResolution")) { fromMappingGrp.DeleteKeyword("PixelResolution"); } } else if(ui.GetString("PIXRES").compare("MPP") == 0) { // Resolution specified - delete all and add to outMappingGrp if(outMappingGrp.HasKeyword("Scale")) { outMappingGrp.DeleteKeyword("Scale"); } if(outMappingGrp.HasKeyword("PixelResolution")) { outMappingGrp.DeleteKeyword("PixelResolution"); } if(fromMappingGrp.HasKeyword("Scale")) { fromMappingGrp.DeleteKeyword("Scale"); } if(fromMappingGrp.HasKeyword("PixelResolution")) { fromMappingGrp.DeleteKeyword("PixelResolution"); } if(userMappingGrp.HasKeyword("Scale")) { userMappingGrp.DeleteKeyword("Scale"); } if(userMappingGrp.HasKeyword("PixelResolution")) { userMappingGrp.DeleteKeyword("PixelResolution"); } outMappingGrp.AddKeyword(PvlKeyword("PixelResolution", ui.GetDouble("RESOLUTION"), "meters/pixel"), Pvl::Replace); } else if(ui.GetString("PIXRES").compare("PPD") == 0) { // Resolution specified - delete all and add to outMappingGrp if(outMappingGrp.HasKeyword("Scale")) { outMappingGrp.DeleteKeyword("Scale"); } if(outMappingGrp.HasKeyword("PixelResolution")) { outMappingGrp.DeleteKeyword("PixelResolution"); } if(fromMappingGrp.HasKeyword("Scale")) { fromMappingGrp.DeleteKeyword("Scale"); } if(fromMappingGrp.HasKeyword("PixelResolution")) { fromMappingGrp.DeleteKeyword("PixelResolution"); } if(userMappingGrp.HasKeyword("Scale")) { userMappingGrp.DeleteKeyword("Scale"); } if(userMappingGrp.HasKeyword("PixelResolution")) { userMappingGrp.DeleteKeyword("PixelResolution"); } outMappingGrp.AddKeyword(PvlKeyword("Scale", ui.GetDouble("RESOLUTION"), "pixels/degree"), Pvl::Replace); } // Rotation will NOT Propagate if(outMappingGrp.HasKeyword("Rotation")) { outMappingGrp.DeleteKeyword("Rotation"); } /** * The user specified map template file overrides what ever is in the * cube's mapping group. */ for(int keyword = 0; keyword < userMappingGrp.Keywords(); keyword ++) { outMappingGrp.AddKeyword(userMappingGrp[keyword], Pvl::Replace); } /** * Now, we have to deal with unit conversions. We convert only if the following are true: * 1) We used values from the input cube * 2) The values are longitudes or latitudes * 3) The map file or user-specified information uses a different measurement system than * the input cube for said values. * * The data is corrected for: * 1) Positive east/positive west * 2) Longitude domain * 3) planetographic/planetocentric. */ // First, the longitude direction if(!sameDirection) { PvlGroup longitudes = inproj->MappingLongitudes(); for(int index = 0; index < longitudes.Keywords(); index ++) { if(!userMappingGrp.HasKeyword(longitudes[index].Name())) { // use the from domain because that's where our values are coming from if(((string)userMappingGrp["LongitudeDirection"]).compare("PositiveEast") == 0) { outMappingGrp[longitudes[index].Name()] = Projection::ToPositiveEast(outMappingGrp[longitudes[index].Name()], outMappingGrp["LongitudeDomain"]); } else { outMappingGrp[longitudes[index].Name()] = Projection::ToPositiveWest(outMappingGrp[longitudes[index].Name()], outMappingGrp["LongitudeDomain"]); } } } } // The minimum/maximum longitudes should be in order now. However, if the user entered a // maximum that was lower than the minimum, or a minimum that was higher than the maximum this // may still fail. Let it throw an error when we instantiate the projection. // Second, longitude domain if(userMappingGrp.HasKeyword("LongitudeDomain")) { // user set a new domain? if((int)userMappingGrp["LongitudeDomain"] != (int)fromMappingGrp["LongitudeDomain"]) { // new domain different? PvlGroup longitudes = inproj->MappingLongitudes(); for(int index = 0; index < longitudes.Keywords(); index ++) { if(!userMappingGrp.HasKeyword(longitudes[index].Name())) { if((int)userMappingGrp["LongitudeDomain"] == 180) { outMappingGrp[longitudes[index].Name()] = Projection::To180Domain(outMappingGrp[longitudes[index].Name()]); } else { outMappingGrp[longitudes[index].Name()] = Projection::To360Domain(outMappingGrp[longitudes[index].Name()]); } } } } } // Third, planetographic/planetocentric if(userMappingGrp.HasKeyword("LatitudeType")) { // user set a new domain? if(((string)userMappingGrp["LatitudeType"]).compare(fromMappingGrp["LatitudeType"]) != 0) { // new lat type different? PvlGroup latitudes = inproj->MappingLatitudes(); for(int index = 0; index < latitudes.Keywords(); index ++) { if(!userMappingGrp.HasKeyword(latitudes[index].Name())) { if(((string)userMappingGrp["LatitudeType"]).compare("Planetographic") == 0) { outMappingGrp[latitudes[index].Name()] = Projection::ToPlanetographic( (double)fromMappingGrp[latitudes[index].Name()], (double)fromMappingGrp["EquatorialRadius"], (double)fromMappingGrp["PolarRadius"]); } else { outMappingGrp[latitudes[index].Name()] = Projection::ToPlanetocentric( (double)fromMappingGrp[latitudes[index].Name()], (double)fromMappingGrp["EquatorialRadius"], (double)fromMappingGrp["PolarRadius"]); } } } } } // If MinLon/MaxLon out of order, we weren't able to calculate the correct values if((double)outMappingGrp["MinimumLongitude"] >= (double)outMappingGrp["MaximumLongitude"]) { if(!ui.WasEntered("MINLON") || !ui.WasEntered("MAXLON")) { string msg = "Unable to determine the correct [MinimumLongitude,MaximumLongitude]."; msg += " Please specify these values in the [MINLON,MAXLON] parameters"; throw iException::Message(iException::Pvl,msg,_FILEINFO_); } } int samples,lines; Pvl mapData; // Copy to preserve cube labels so we can match cube size if (userPvl.HasObject("IsisCube")) { mapData = userPvl; mapData.FindObject("IsisCube").DeleteGroup("Mapping"); mapData.FindObject("IsisCube").AddGroup(outMappingGrp); } else { mapData.AddGroup(outMappingGrp); } // *NOTE: The UpperLeftX,UpperLeftY keywords will not be used in the CreateForCube // method, and they will instead be recalculated. This is correct. Projection *outproj = ProjectionFactory::CreateForCube(mapData,samples,lines, ui.GetBoolean("MATCHMAP")); // Set up the transform object which will simply map // output line/samps -> output lat/lons -> input line/samps Transform *transform = new map2map (icube->Samples(), icube->Lines(), icube->Projection(), samples, lines, outproj, ui.GetBoolean("TRIM")); // Allocate the output cube and add the mapping labels Cube *ocube = p.SetOutputCube ("TO", transform->OutputSamples(), transform->OutputLines(), icube->Bands()); PvlGroup cleanOutGrp = outproj->Mapping(); // ProjectionFactory::CreateForCube updated mapData to have the correct // upperleftcornerx, upperleftcornery, scale and resolution. Use these // updated numbers. cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["UpperLeftCornerX"], Pvl::Replace); cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["UpperLeftCornerY"], Pvl::Replace); cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["Scale"], Pvl::Replace); cleanOutGrp.AddKeyword(mapData.FindGroup("Mapping",Pvl::Traverse)["PixelResolution"], Pvl::Replace); ocube->PutGroup(cleanOutGrp); // Set up the interpolator Interpolator *interp; if (ui.GetString("INTERP") == "NEARESTNEIGHBOR") { interp = new Interpolator(Interpolator::NearestNeighborType); } else if (ui.GetString("INTERP") == "BILINEAR") { interp = new Interpolator(Interpolator::BiLinearType); } else if (ui.GetString("INTERP") == "CUBICCONVOLUTION") { interp = new Interpolator(Interpolator::CubicConvolutionType); } else { string msg = "Unknow value for INTERP [" + ui.GetString("INTERP") + "]"; throw iException::Message(iException::Programmer,msg,_FILEINFO_); } // Warp the cube p.StartProcess(*transform, *interp); p.EndProcess(); Application::Log(cleanOutGrp); // Cleanup delete transform; delete interp; }