USGS

Isis 3.0 Application Source Code Reference

Home

mapgrid.cpp

Go to the documentation of this file.
00001 #include "Isis.h"
00002 
00003 #include <cmath>
00004 
00005 #include "iException.h"
00006 #include "ProjectionFactory.h"
00007 #include "Progress.h"
00008 #include "Projection.h"
00009 #include "Pvl.h"
00010 #include "UserInterface.h"
00011 
00012 using namespace std;
00013 using namespace Isis;
00014 
00015 void StartNewLine(std::ofstream &);
00016 void AddPointToLine(std::ofstream &, double, double);
00017 void EndLine(std::ofstream &);
00018 void CheckContinuous(double latlon, double latlon_start, double X, double Y, double lastX, double lastY, double maxChange, std::ofstream &os);
00019 
00020 void IsisMain() {
00021   // Get user interface
00022   UserInterface &ui = Application::GetUserInterface();
00023 
00024   // Get necessary variables from the user
00025   double latStart = ui.GetDouble("STARTLAT");
00026   double lonStart = ui.GetDouble("STARTLON");
00027   double latEnd = ui.GetDouble("ENDLAT");
00028   double lonEnd = ui.GetDouble("ENDLON");
00029   double latSpacing = ui.GetDouble("LATSPACING");
00030   double lonSpacing = ui.GetDouble("LONSPACING");
00031   double latInc = ui.GetDouble("LATINCREMENT");
00032   double lonInc = ui.GetDouble("LONINCREMENT");
00033 
00034   // Get mapfile, add values for range and create projection
00035   string mapFile = ui.GetFilename("MAPFILE");
00036   Pvl p(mapFile);
00037   PvlGroup &mapping = p.FindGroup("Mapping", Pvl::Traverse);
00038 
00039   if(mapping.HasKeyword("MinimumLatitude")) {
00040     mapping.DeleteKeyword("MinimumLatitude");
00041   }
00042 
00043   if(mapping.HasKeyword("MaximumLatitude")) {
00044     mapping.DeleteKeyword("MaximumLatitude");
00045   }
00046 
00047   if(mapping.HasKeyword("MinimumLongitude")) {
00048     mapping.DeleteKeyword("MinimumLongitude");
00049   }
00050 
00051   if(mapping.HasKeyword("MaximumLongitude")) {
00052     mapping.DeleteKeyword("MaximumLongitude");
00053   }
00054 
00055   mapping += PvlKeyword("MinimumLatitude", latStart);
00056   mapping += PvlKeyword("MaximumLatitude", latEnd);
00057   mapping += PvlKeyword("MinimumLongitude", lonStart);
00058   mapping += PvlKeyword("MaximumLongitude", lonEnd);
00059 
00060   Projection *proj;
00061   try {
00062     proj = ProjectionFactory::Create(p);
00063   }
00064   catch(iException &e) {
00065     string msg = "Cannot create grid - MapFile [" + mapFile +
00066                  "] does not contain necessary information to create a projection";
00067     throw Isis::iException::Message(Isis::iException::User, msg, _FILEINFO_);
00068   }
00069 
00070 
00071   // Write grid to well known text output
00072   string out = Filename(ui.GetFilename("TO")).Expanded();
00073   std::ofstream os;
00074   os.open(out.c_str(), std::ios::out);
00075 
00076   // Display the progress...10% 20% etc.
00077   Progress prog;
00078   int steps = (int)(abs((latEnd - latStart) / latSpacing) +
00079                     abs((lonEnd - lonStart) / lonSpacing) + 0.5) + 3;
00080   prog.SetMaximumSteps(steps);
00081   prog.CheckStatus();
00082 
00083   /**
00084    * Initialize document. GML is XML-based, so we need the necessary XML headers. These
00085    * are necessary for the GML file to be recognized.
00086    */
00087   os << "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" << endl;
00088   os << "<ogr:FeatureCollection " << endl <<
00089      "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" << endl <<
00090      "xsi:schemaLocation=\"http://org.maptools.org/\"" << endl <<
00091      "xmlns:ogr=\"http://org.maptools.org/\"" << endl <<
00092      "xmlns:gml=\"http://www.opengis.net/gml\">" << endl;
00093 
00094   /**
00095    * Draw the interior longitude lines by looping through the longitude
00096    * range and drawing across each latitude line using the longitude increment. The first
00097    * and last line will be skipped for now.
00098    */
00099   for(double j = lonStart + lonSpacing; j < lonEnd; j += lonSpacing) {
00100     StartNewLine(os);
00101     for(double k = latStart; k <= latEnd; k += lonInc) {
00102       proj->SetGround(k, j);
00103       AddPointToLine(os, proj->XCoord(), proj->YCoord());
00104     }
00105 
00106     EndLine(os);
00107     prog.CheckStatus();
00108   }
00109 
00110   /**
00111    * Draw the exterior longitude boundary lines. This happens by drawing just the first and
00112    * last longitude lines.
00113    */
00114   for(double r = lonStart; r <= lonEnd; r += (lonEnd - lonStart)) {
00115     StartNewLine(os);
00116     for(double s = latStart; s <= latEnd; s += lonInc) {
00117       proj->SetGround(s, r);
00118       AddPointToLine(os, proj->XCoord(), proj->YCoord());
00119     }
00120     EndLine(os);
00121     prog.CheckStatus();
00122   }
00123 
00124   /**
00125    * Draw the interior latitude lines by looping through the latitude
00126    * range and drawing across each longitude line using the latitude increment. The first
00127    * and last line will be skipped for now.
00128    */
00129   for(double i = latStart + latSpacing; i < latEnd; i += latSpacing) {
00130 
00131     // Get Latitude Line
00132     StartNewLine(os);
00133     for(double l = lonStart; l <= lonEnd; l += latInc) {
00134       proj->SetGround(i, l);
00135       AddPointToLine(os, proj->XCoord(), proj->YCoord());
00136     }
00137     EndLine(os);
00138     prog.CheckStatus();
00139   }
00140 
00141   /**
00142    * Draw the exterior latitude boundary lines. This happens by drawing just the first and
00143    * last longitude lines.
00144    */
00145   for(double m = latStart; m <= latEnd; m += (latEnd - latStart)) {
00146     StartNewLine(os);
00147 
00148     for(double n = lonStart; n <= lonEnd; n += latInc) {
00149       proj->SetGround(m, n);
00150       AddPointToLine(os, proj->XCoord(), proj->YCoord());
00151     }
00152 
00153     EndLine(os);
00154     prog.CheckStatus();
00155   }
00156 
00157   /**
00158    * Draw the bounding box using a series of lines.
00159    */
00160   if(ui.GetBoolean("BOUNDED")) {
00161     double minX, maxX, minY, maxY;
00162     proj->XYRange(minX, maxX, minY, maxY);
00163 
00164     StartNewLine(os);
00165     AddPointToLine(os, minX, minY);
00166     AddPointToLine(os, minX, maxY);
00167     EndLine(os);
00168 
00169     StartNewLine(os);
00170     AddPointToLine(os, minX, maxY);
00171     AddPointToLine(os, maxX, maxY);
00172     EndLine(os);
00173 
00174     StartNewLine(os);
00175     AddPointToLine(os, maxX, minY);
00176     AddPointToLine(os, maxX, maxY);
00177     EndLine(os);
00178 
00179     StartNewLine(os);
00180     AddPointToLine(os, minX, minY);
00181     AddPointToLine(os, maxX, minY);
00182     EndLine(os);
00183   }
00184 
00185   os << "</ogr:FeatureCollection>" << endl;
00186 
00187   // add mapping to print.prt
00188   PvlGroup projMapping = proj->Mapping();
00189   Application::Log(projMapping);
00190 }
00191 
00192 /**
00193  * This will prepare a new line start in GML. This should be called every time a new line is
00194  * started and generates unique IDs for each line.
00195  *
00196  * @param os output file stream
00197  */
00198 void StartNewLine(std::ofstream &os) {
00199   static int lineID = 0;
00200 
00201   os << "<gml:featureMember>" << endl;
00202   os << "  <ogr:mapLine fid=\"F" << lineID << "\">" << endl;
00203   os << "    <ogr:ID>" << lineID << "</ogr:ID>" << endl;
00204   os << "    <ogr:geometryProperty>" << "<gml:LineString>" << "<gml:coordinates>";
00205 
00206   lineID ++;
00207 }
00208 
00209 /**
00210  * This will add a point to a line started with StartNewLine. StartNewLine must be
00211  * called before using this method, and EndLine after all of the points in the line have
00212  * been added.
00213  *
00214  * @param os output file stream
00215  * @param x x coordinate
00216  * @param y y coordinate
00217  */
00218 void AddPointToLine(std::ofstream &os, const double x, const double y) {
00219   os << x << "," << y << " ";
00220 }
00221 
00222 /**
00223  * This will end a line in GML. This should be called after each line has the necessary points
00224  * added using AddPointToLine.
00225  *
00226  * @param os output file stream
00227  */
00228 void EndLine(std::ofstream &os) {
00229   os << "</gml:coordinates>" << "</gml:LineString>" << "</ogr:geometryProperty>" << endl;
00230   os << "  </ogr:mapLine>" << endl;
00231   os << "</gml:featureMember>" << endl;
00232 }
00233 
00234 /**
00235  * This function was created to deal with potential discontinuities in mapping patterns in order to not
00236  * connect them. It will create a new line if there is more than a maxChange difference in the points.
00237  * This was coded for ObliqueCylindrical.
00238  *
00239  * @param latlon Current latitude or longitude value
00240  * @param latlon_start Initial latitude or longitude value of this line
00241  * @param X X coordinate of this point
00242  * @param Y Y coordinate of this point
00243  * @param lastX Previous X coordinate of this point
00244  * @param lastY Previous Y coordinate of this point
00245  * @param maxChange Maximum distance between these two points
00246  * @param os Output file stream
00247  */
00248 /*void CheckContinuous(double latlon, double latlon_start, double X, double Y, double lastX, double lastY, double maxChange, std::ofstream &os) {
00249   if(latlon != latlon_start) {
00250     if(sqrt(pow(lastX - X,2) + (pow(lastX - X,2))) > maxChange) {
00251       EndLine(os);
00252       StartNewLine(os);
00253     }
00254   }
00255 }*/