USGS

Isis 3.0 Application Source Code Reference

Home

cropspecial.cpp

Go to the documentation of this file.
00001 #include "Isis.h"
00002 #include "ProcessByLine.h"
00003 #include "Pixel.h"
00004 #include "LineManager.h"
00005 #include "SpecialPixel.h"
00006 #include "Cube.h"
00007 #include "Table.h"
00008 #include "AlphaCube.h"
00009 #include "Projection.h"
00010 #include "Pvl.h"
00011 #include "PvlKeyword.h"
00012 
00013 using namespace std; 
00014 using namespace Isis;
00015 
00016 int minSample, maxSample, numSamples;
00017 int minLine, maxLine, numLines;
00018 int curBand, numBands;
00019 bool cropNulls, cropHrs, cropLrs, cropHis, cropLis;
00020 LineManager *in;
00021 Cube cube;
00022 
00023 void FindPerimeter (Buffer &in);
00024 void SpecialRemoval (Buffer &out);
00025 
00026 
00027 void IsisMain() {
00028   maxSample = 0;
00029   maxLine = 0;
00030   curBand = 1;  
00031   
00032   // Open the input cube
00033   UserInterface &ui = Application::GetUserInterface();
00034   string from = ui.GetAsString("FROM");
00035   CubeAttributeInput inAtt(from);
00036   cube.SetVirtualBands(inAtt.Bands());
00037   from = ui.GetFilename("FROM");
00038   cube.Open(from);
00039 
00040   cropNulls = ui.GetBoolean("NULL");
00041   cropHrs = ui.GetBoolean("HRS");
00042   cropLrs = ui.GetBoolean("LRS");
00043   cropHis = ui.GetBoolean("HIS");
00044   cropLis = ui.GetBoolean("LIS");
00045 
00046   minSample = cube.Samples() + 1;
00047   minLine = cube.Lines() + 1;
00048   numBands = cube.Bands();
00049   
00050   // Setup the input cube
00051   ProcessByLine p1;
00052   p1.SetInputCube("FROM");
00053       
00054   // Start the first pass
00055   p1.StartProcess(FindPerimeter);
00056   p1.EndProcess();
00057 
00058   if (minSample == cube.Samples() + 1) {
00059     cube.Close();
00060     string msg = "There are no valid pixels in the [FROM] cube";
00061     throw iException::Message(iException::User,msg,_FILEINFO_);
00062   }
00063 
00064   numSamples = maxSample - (minSample - 1);
00065   numLines = maxLine - (minLine - 1);
00066   
00067   // Setup the output cube
00068   ProcessByLine p2;
00069   p2.SetInputCube("FROM");
00070   p2.PropagateTables(false);
00071   Cube *ocube = p2.SetOutputCube("TO", numSamples, numLines, numBands);
00072   p2.ClearInputCubes();  
00073   
00074   // propagate tables manually
00075   Pvl &inLabels = *cube.Label();
00076   
00077   // Loop through the labels looking for object = Table
00078   for(int labelObj = 0; labelObj < inLabels.Objects(); labelObj++) {
00079     PvlObject &obj = inLabels.Object(labelObj);
00080   
00081     if(obj.Name() != "Table") continue;
00082   
00083     // Read the table into a table object
00084     Table table(obj["Name"], from);
00085   
00086     ocube->Write(table);
00087   }
00088 
00089   // Construct a label with the results
00090   PvlGroup results("Results");
00091   results += PvlKeyword ("InputLines", cube.Lines());
00092   results += PvlKeyword ("InputSamples", cube.Samples());
00093   results += PvlKeyword ("StartingLine", minLine);
00094   results += PvlKeyword ("StartingSample", minSample);
00095   results += PvlKeyword ("EndingLine", maxLine);
00096   results += PvlKeyword ("EndingSample", maxSample);
00097   results += PvlKeyword ("OutputLines", numLines);
00098   results += PvlKeyword ("OutputSamples", numSamples); 
00099   
00100   // Create a buffer for reading the input cube
00101   in = new LineManager(cube);
00102   
00103   // Start the second pass
00104   p2.StartProcess(SpecialRemoval);
00105 
00106   // Adjust the upper corner x,y values if the cube is projected
00107   try {
00108     // Try to create a projection & set the x,y position
00109     Projection *proj = cube.Projection();
00110     proj->SetWorld(minSample-0.5,minLine-0.5);
00111 
00112     // Set the new x,y coords in the cube label
00113     PvlGroup &mapgrp = cube.Label()->FindGroup("Mapping",Pvl::Traverse);
00114     mapgrp.AddKeyword(PvlKeyword("UpperLeftCornerX",proj->XCoord()), 
00115                        Pvl::Replace);
00116     mapgrp.AddKeyword(PvlKeyword("UpperLeftCornerY",proj->YCoord()),
00117                                       Pvl::Replace);
00118     ocube->PutGroup(mapgrp);
00119   }
00120   // Only write the alpha group if the cube is not projected
00121   catch (iException &e) {
00122     // Clear the exception
00123     e.Clear();
00124 
00125     // Add and/or update the alpha group
00126     AlphaCube aCube(cube.Samples(),cube.Lines(),
00127                         ocube->Samples(),ocube->Lines(),
00128                         minSample-0.5,minLine-0.5,numSamples+0.5,numLines+0.5);
00129     aCube.UpdateGroup(*ocube->Label());
00130   }
00131 
00132   p2.EndProcess(); 
00133   cube.Close();  
00134 
00135   delete in;
00136   in = NULL;
00137 
00138   // Write the results to the log
00139   Application::Log(results);
00140 }
00141 
00142 // Process each line to find the min and max lines and samples
00143 void FindPerimeter (Buffer &in) {
00144   for (int i = 0; i < in.size(); i++) {    
00145     // Do nothing until we find a valid pixel, or a pixel we do not want to crop off
00146     if ((Pixel::IsValid(in[i])) || (Pixel::IsNull(in[i]) && !cropNulls) || 
00147         (Pixel::IsHrs(in[i]) && !cropHrs) || (Pixel::IsLrs(in[i]) && !cropLrs) || 
00148         (Pixel::IsHis(in[i]) && !cropHis) || (Pixel::IsLis(in[i]) && !cropLis)) {
00149       // The current line has a valid pixel and is greater than max, so make it the new max line
00150       if (in.Line() > maxLine) maxLine = in.Line();
00151 
00152       // This is the first line to contain a valid pixel, so it's the min line
00153       if (in.Line() < minLine) minLine = in.Line();      
00154 
00155       int cur_sample = i + 1;
00156 
00157       // We process by line, so the min sample is the valid pixel with the lowest index in all line arrays
00158       if (cur_sample < minSample) minSample = cur_sample;
00159 
00160       // Conversely, the max sample is the valid pixel with the highest index
00161       if (cur_sample > maxSample) maxSample = cur_sample;
00162     }   
00163   }
00164 }
00165 
00166 // Using the min and max values, create a new cube without the extra specials
00167 void SpecialRemoval (Buffer &out) {
00168   int iline = minLine + (out.Line() - 1);
00169   in->SetLine(iline, curBand);
00170   cube.Read(*in);
00171 
00172   // Loop and move appropriate samples
00173   for (int i = 0; i < out.size(); i++) {
00174     out[i] = (*in)[(minSample - 1) + i];
00175   }
00176 
00177   if (out.Line() == numLines) curBand++;
00178 }