1 //*******************************************************************
2 // Copyright (C) 2003 Storage Area Networks, Inc.
3 //
4 // License:  LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author:  Kenneth Melero (kmelero@sanz.com)
9 //
10 //*******************************************************************
11 //  $Id: ossimReadmeFileWriter.cpp 21631 2012-09-06 18:10:55Z dburken $
12 
13 #include <ossim/imaging/ossimReadmeFileWriter.h>
14 #include <ossim/base/ossimKeywordNames.h>
15 #include <ossim/base/ossimTrace.h>
16 #include <ossim/base/ossimKeywordlist.h>
17 #include <ossim/projection/ossimMapProjection.h>
18 #include <ossim/projection/ossimUtmProjection.h>
19 #include <ossim/projection/ossimMapProjectionInfo.h>
20 #include <ossim/imaging/ossimImageGeometry.h>
21 #include <ossim/imaging/ossimImageHandler.h>
22 #include <ossim/imaging/ossimImageData.h>
23 #include <ossim/imaging/ossimImageSource.h>
24 #include <iostream>
25 using namespace std;
26 
27 RTTI_DEF1(ossimReadmeFileWriter,
28           "ossimReadmeFileWriter",
29           ossimMetadataFileWriter)
30 
31 static const char DEFAULT_FILE_NAME[] = "output_readme.txt";
32 static ossimTrace traceDebug("ossimReadmeFileWriter:debug");
33 
34 //**************************************************************************************************
35 //
36 //**************************************************************************************************
ossimReadmeFileWriter()37 ossimReadmeFileWriter::ossimReadmeFileWriter()
38 :
39 ossimMetadataFileWriter()
40 {
41 }
42 
43 //**************************************************************************************************
44 //
45 //**************************************************************************************************
~ossimReadmeFileWriter()46 ossimReadmeFileWriter::~ossimReadmeFileWriter()
47 {
48 }
49 
50 //**************************************************************************************************
51 //
52 //**************************************************************************************************
writeFile()53 bool ossimReadmeFileWriter::writeFile()
54 {
55    static const char MODULE[] = "ossimReadmeFileWriter::writeFile";
56 
57    if(!theInputConnection)
58    {
59       if (traceDebug())
60       {
61          CLOG << "DEBUG:"
62               << "\nNo input connection!  Returning..."
63               << endl;
64       }
65 
66       return false;
67    }
68 
69    std::ofstream out(theFilename.c_str(), ios_base::out);
70    if (!out)
71       return false;
72 
73    // Fetch the map projection of the input image if it exists:
74    const ossimMapProjection* mapProj = 0;
75    ossimRefPtr<ossimImageGeometry> imgGeom = theInputConnection->getImageGeometry();
76    if ( imgGeom.valid() )
77    {
78       const ossimProjection* proj = imgGeom->getProjection();
79       mapProj = PTR_CAST(ossimMapProjection, proj);
80    }
81    if (!mapProj)
82    {
83       out.close();
84       return false;
85    }
86 
87    ossimMapProjectionInfo* projectionInfo = new ossimMapProjectionInfo(mapProj, theAreaOfInterest);
88    if(projectionInfo)
89    {
90       out << setiosflags(ios::fixed)
91           << setiosflags(ios::left)
92           << setw(16) << "Image: "
93           << projectionInfo->getImageInfoString();
94 
95       out << setw(17) << "\nLines:"
96           << projectionInfo->linesPerImage()
97           << setw(17) << "\nSamples:"
98           << projectionInfo->pixelsPerLine()
99           << setw(17) << "\nPixel Size x:"
100           << setprecision(8)
101           << projectionInfo->getMetersPerPixel().x
102           << " meters";
103 
104       out << ", "
105           << setprecision(8)
106           << projectionInfo->getUsSurveyFeetPerPixel().x
107           << " U.S. feet";
108 
109       out << setw(17) << "\nPixel Size y:"
110           << setprecision(8)
111           << projectionInfo->getMetersPerPixel().y
112           << " meters";
113 
114       out << ", "
115           << setprecision(8)
116           << projectionInfo->getUsSurveyFeetPerPixel().y
117           << " U.S. feet";
118 
119       const ossimString type  = TYPE_NAME(mapProj);
120       const ossimString datum = mapProj->getDatum()->code();
121       const ossimString ellipsoid = mapProj->getEllipsoid().code();
122 
123       if(type)
124          out << setw(17) << "\nProjection:" << type;
125 
126       const ossimUtmProjection* utmProj = PTR_CAST(ossimUtmProjection, mapProj);
127       if (utmProj)
128          out << setw(17) << "\nUTM map zone:" << utmProj->getZone();
129 
130       if(datum && ellipsoid)
131          out << setw(17) << "\nDatum:"      << datum
132              << setw(17) << "\nEllipsoid:"
133              << ellipsoid;
134 
135       out << resetiosflags(ios::left) << endl;
136 
137       const ossimString NORTH = "N";
138       const ossimString SOUTH = "S";
139       const ossimString EAST  = "E";
140       const ossimString WEST  = "W";
141 
142       ossimString tmpString;
143       double tmpDouble;
144 
145       // HACK: Easiest way to get projection info for optional params is via the old keywordlist:
146       ossimKeywordlist kwl;
147       mapProj->saveState(kwl);
148       const char* parallel1   = kwl.find(ossimKeywordNames::STD_PARALLEL_1_KW);
149       const char* parallel2   = kwl.find(ossimKeywordNames::STD_PARALLEL_2_KW);
150       const char* scaleFactor = kwl.find(ossimKeywordNames::SCALE_FACTOR_KW);
151 
152 
153       ossimString proj_name = mapProj->getClassName();
154       if ( ( proj_name.contains("Lambert")           ) ||
155            ( proj_name.contains("Albers")            ) ||
156            ( proj_name.contains("TransverseMercator" ) ) )
157       {
158          double falseEasting  =  mapProj->getFalseEasting();
159          double falseNorthing =  mapProj->getFalseNorthing();
160 
161          double origin_lat = mapProj->origin().latd();
162          tmpDouble = fabs(origin_lat);
163          tmpString = (origin_lat < 0.0) ? SOUTH : NORTH;
164          out << setiosflags(ios::left)
165              << "\n"
166              << setw(18) << "Origin Latitude:"
167              << resetiosflags(ios::left)
168              << setw(21) << setprecision(12) << tmpDouble
169              << tmpString << endl;
170 
171          double origin_lon = mapProj->origin().lond();
172          tmpDouble = fabs(origin_lon);
173          tmpString = (origin_lon < 0.0) ? WEST : EAST;
174          out << setiosflags(ios::left)
175              << setw(18) << "Origin Longitude:"
176              << resetiosflags(ios::left)
177              << setw(21) << tmpDouble << tmpString
178              << setiosflags(ios::left)
179              << "\n"
180              << setw(23) << "False Easting:"
181              << resetiosflags(ios::left)
182              << setw(17) << setprecision(4)
183              << falseEasting;
184 
185          out << " meters, " << setprecision(4)
186              << ossim::mtrs2usft(falseEasting)
187              << " U.S. feet";
188 
189          out << endl;
190 
191          out << setiosflags(ios::left)
192              << setw(23) << "False Northing:"
193              << resetiosflags(ios::left)
194              << setw(17) << setprecision(4)
195              << falseNorthing;
196 
197          out << " meters, " << setprecision(4)
198              << ossim::mtrs2usft(falseNorthing)
199              << " U.S. feet";
200 
201          out << endl;
202 
203       } // End of if "Alber Lambert or TM.
204 
205       if (proj_name.contains("TransverseMercator"))
206       {
207 
208          out << setiosflags(ios::left)
209              << "\n"
210              << setw(18) << "Scale Factor:"
211              << resetiosflags(ios::left)
212              << setw(21) << setprecision(10)
213              << ossimString(scaleFactor).toDouble()
214              << "\n" << endl;
215       }
216 
217       if ( (proj_name.contains("Lambert") ) ||
218            (proj_name.contains("Albers")  ) )
219       {
220          double stdpar1 = ossimString(parallel1).toDouble();
221          tmpDouble = fabs(stdpar1);
222          tmpString = (stdpar1 < 0.0) ? SOUTH : NORTH;
223          out << setiosflags(ios::left)
224              << setw(23) << "Standard Parallel #1:"
225              << resetiosflags(ios::left)
226              << setw(16) << setprecision(12) << tmpDouble
227              << tmpString << endl;
228 
229          double stdpar2 = ossimString(parallel2).toDouble();
230          tmpDouble = fabs(stdpar2);
231          tmpString = (stdpar2 < 0.0) ? SOUTH : NORTH;
232          out << setiosflags(ios::left)
233              << setw(23) << "Standard Parallel #2:"
234              << resetiosflags(ios::left)
235              << setw(16) << setprecision(12)
236              << tmpDouble << tmpString
237              << "\n" << endl;
238       }
239 
240       ossimString cornerString[4] = { "Upper Left",
241                                       "Upper Right",
242                                       "Lower Right",
243                                       "Lower Left" };
244 
245       //---
246       // Add a note to the readme file stating what the corner coordinates
247       // are relative to.
248       //---
249       if (projectionInfo->getPixelType() == OSSIM_PIXEL_IS_AREA)
250       {
251          out
252             << "\nCorner coordinates relative to outer edge of pixel.\n\n";
253       }
254       else
255       {
256          out
257             << "\nCorner coordinates relative to center of pixel.\n\n";
258       }
259 
260       out << "Corner Coordinates:\n\n";
261 
262       //---
263       // Upper Left Corner Points
264       //---
265       tmpDouble = fabs(projectionInfo->ulGroundPt().latd());
266       tmpString = (projectionInfo->ulGroundPt().latd() < 0.0) ? SOUTH : NORTH;
267       out << cornerString[0]  << endl;
268       out << setw(14) << "Latitude:  "
269           << setw(16) << setprecision(12) << tmpDouble
270           << tmpString << endl;
271       tmpDouble = fabs(projectionInfo->ulGroundPt().lond());
272       tmpString = (projectionInfo->ulGroundPt().lond() < 0.0) ? WEST : EAST;
273       out << setw(14) << "Longitude:  "
274           << setw(16) << tmpDouble << tmpString << endl;
275 
276       out << setw(14) << "Easting:  "
277           << setw(17) << setprecision(4)
278           << projectionInfo->ulEastingNorthingPt().x;
279 
280       out << " meters, " << setprecision(4)
281           << ossim::mtrs2usft(projectionInfo->ulEastingNorthingPt().x)
282           << " U.S. feet";
283 
284       out << endl
285           << setw(14) << "Northing:  "
286           << setw(17) << projectionInfo->ulEastingNorthingPt().y;
287 
288       out << " meters, " << setprecision(4)
289           << ossim::mtrs2usft(projectionInfo->ulEastingNorthingPt().y)
290           << " U.S. feet";
291 
292       out << endl << endl;
293 
294       //---
295       // Upper Right Corner Points
296       //---
297       tmpDouble = fabs(projectionInfo->urGroundPt().latd());
298       tmpString = (projectionInfo->urGroundPt().latd() < 0.0) ? SOUTH : NORTH;
299       out << cornerString[1]  << endl;
300       out << setw(14) << "Latitude:  "
301           << setw(16) << setprecision(12) << tmpDouble
302           << tmpString << endl;
303       tmpDouble = fabs(projectionInfo->urGroundPt().lond());
304       tmpString = (projectionInfo->urGroundPt().lond() < 0.0) ? WEST : EAST;
305       out << setw(14) << "Longitude:  "
306           << setw(16) << tmpDouble << tmpString << endl;
307 
308       out << setw(14) << "Easting:  "
309           << setw(17) << setprecision(4)
310           << projectionInfo->urEastingNorthingPt().x;
311 
312       out << " meters, " << setprecision(4)
313           << ossim::mtrs2usft(projectionInfo->urEastingNorthingPt().x)
314           << " U.S. feet";
315 
316       out << endl
317           << setw(14) << "Northing:  "
318           << setw(17) << projectionInfo->urEastingNorthingPt().y;
319 
320       out << " meters, " << setprecision(4)
321           << ossim::mtrs2usft(projectionInfo->urEastingNorthingPt().y)
322           << " U.S. feet";
323 
324       out << endl << endl;
325 
326       //---
327       // Lower Right Corner Points
328       //---
329       tmpDouble = fabs(projectionInfo->lrGroundPt().latd());
330       tmpString = (projectionInfo->lrGroundPt().latd() < 0.0) ? SOUTH : NORTH;
331       out << cornerString[2]  << endl;
332       out << setw(14) << "Latitude:  "
333           << setw(16) << setprecision(12) << tmpDouble
334           << tmpString << endl;
335       tmpDouble = fabs(projectionInfo->lrGroundPt().lond());
336       tmpString = (projectionInfo->lrGroundPt().lond() < 0.0) ? WEST : EAST;
337       out << setw(14) << "Longitude:  "
338           << setw(16) << tmpDouble << tmpString << endl;
339 
340       out << setw(14) << "Easting:  "
341           << setw(17) << setprecision(4)
342           << projectionInfo->lrEastingNorthingPt().x;
343 
344       out << " meters, " << setprecision(4)
345           << ossim::mtrs2usft(projectionInfo->lrEastingNorthingPt().x)
346           << " U.S. feet";
347 
348       out << endl
349           << setw(14) << "Northing:  "
350           << setw(17) << projectionInfo->lrEastingNorthingPt().y;
351 
352       out << " meters, " << setprecision(4)
353           << ossim::mtrs2usft(projectionInfo->lrEastingNorthingPt().y)
354           << " U.S. feet";
355 
356       out << endl << endl;
357 
358       //---
359       // Lower Left Corner Points
360       //---
361       tmpDouble = fabs(projectionInfo->llGroundPt().latd());
362       tmpString = (projectionInfo->llGroundPt().latd() < 0.0) ? SOUTH : NORTH;
363       out << cornerString[3]  << endl;
364       out << setw(14) << "Latitude:  "
365           << setw(16) << setprecision(12) << tmpDouble
366           << tmpString << endl;
367       tmpDouble = fabs(projectionInfo->llGroundPt().lond());
368       tmpString = (projectionInfo->llGroundPt().lond() < 0.0) ? WEST : EAST;
369       out << setw(14) << "Longitude:  "
370           << setw(16) << tmpDouble << tmpString << endl;
371 
372       out << setw(14) << "Easting:  "
373           << setw(17) << setprecision(4)
374           <<  projectionInfo->llEastingNorthingPt().x;
375 
376       out << " meters, " << setprecision(4)
377           << ossim::mtrs2usft(projectionInfo->llEastingNorthingPt().x)
378           << " U.S. feet";
379 
380       out << endl
381           << setw(14) << "Northing:  "
382           << setw(17) << projectionInfo->llEastingNorthingPt().y;
383 
384       out << " meters, " << setprecision(4)
385           << ossim::mtrs2usft(projectionInfo->llEastingNorthingPt().y)
386           << " U.S. feet";
387 
388       out << endl << endl;
389 
390       out << "Center Coordinates:\n\n";
391 
392       tmpDouble = fabs(projectionInfo->centerGroundPt().latd());
393 
394       tmpString = (projectionInfo->centerGroundPt().latd() < 0.0) ? SOUTH : NORTH;
395 
396       out << setw(14) << "Latitude:  "
397           << setw(16) << setprecision(12) << tmpDouble
398           << tmpString << endl;
399 
400       tmpDouble = fabs(projectionInfo->centerGroundPt().lond());
401 
402       tmpString = (projectionInfo->centerGroundPt().lond() < 0.0) ? WEST : EAST;
403 
404       out << setw(14) << "Longitude:  "
405           << setw(16) << tmpDouble << tmpString << endl;
406 
407       out << setw(14) << "Easting:  "
408           << setw(17) << setprecision(4)
409           << projectionInfo->centerEastingNorthingPt().x;
410 
411       out << " meters, " << setprecision(4)
412           << ossim::mtrs2usft(projectionInfo->centerEastingNorthingPt().x)
413           << " U.S. feet";
414 
415       out << endl
416           << setw(14) << "Northing:  "
417           << setw(17) << projectionInfo->centerEastingNorthingPt().y;
418 
419       out << " meters, " << setprecision(4)
420           << ossim::mtrs2usft(projectionInfo->centerEastingNorthingPt().y)
421           << " U.S. feet";
422 
423       out << endl << endl;
424 
425       out
426          << "\nNOTE:  Lat/Lon values are in decimal degrees.";
427 
428       out
429          << "\n       Eastings/Northings are in meters.";
430 
431       out << endl;
432 
433       delete projectionInfo;
434    }
435 
436    out.close();
437    return true;
438 }
439 
440 //**************************************************************************************************
441 //
442 //**************************************************************************************************
getMetadatatypeList(std::vector<ossimString> & metadatatypeList) const443 void ossimReadmeFileWriter::getMetadatatypeList(std::vector<ossimString>& metadatatypeList) const
444 {
445    metadatatypeList.push_back(ossimString("ossim_readme"));
446 }
447 
448 //**************************************************************************************************
449 //
450 //**************************************************************************************************
hasMetadataType(const ossimString & metadataType) const451 bool ossimReadmeFileWriter::hasMetadataType(const ossimString& metadataType) const
452 {
453    return (metadataType == "ossim_readme");
454 }
455