Isis 3.0 Application Source Code Reference |
Home |
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 }*/