OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimRpfUtil.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // License: LGPL
4 //
5 // See LICENSE.txt file in the top level directory for more details.
6 //
7 // Author: David Burken
8 //
9 // Description: ossimRpfUtil.cpp
10 //
11 // Utility class to stuff with rpf files.
12 //
13 //----------------------------------------------------------------------------
14 // $Id$
15 
17 #include <ossim/base/ossimDrect.h>
19 #include <ossim/base/ossimGpt.h>
20 #include <ossim/base/ossimIrect.h>
21 #include <ossim/base/ossimTrace.h>
24 #include <ctime>
25 #include <iomanip>
26 
27 static ossimTrace traceDebug = ossimTrace("ossimRpfUtil:debug");
28 
30 {
31 }
32 
34 {
35 }
36 
37 
38 // Note: throws ossimException on error.
40  const ossimFilename& outputDir )
41 {
42  static const char MODULE[] = "ossimRpfUtil::writeDotRpfFiles";
43 
44  if ( traceDebug() )
45  {
47  << MODULE << " entered..."
48  << "\na.toc file: " << aDotTocFile
49  << "\noutput directory: " << outputDir
50  << "\n";
51  }
52 
53  // Parse the a.toc file:
55 
56  if ( toc->parseFile(aDotTocFile) != ossimErrorCodes::OSSIM_OK )
57  {
58  std::string e = MODULE;
59  e += " ERROR:\nCould not open: ";
60  e+= aDotTocFile.string();
61  throw ossimException(e);
62  }
63 
64  if ( outputDir.expand().exists() == false )
65  {
66  if ( !outputDir.createDirectory(true, 0775) )
67  {
68  std::string e = MODULE;
69  e += " ERROR:\nCould not create directory: ";
70  e+= outputDir.c_str();
71  throw ossimException(e);
72  }
73  }
74 
75  //---
76  // Go through the entries...
77  //---
78  ossim_uint32 entries = toc->getNumberOfEntries();
79  for (ossim_uint32 entry = 0; entry < entries; ++entry)
80  {
81  const ossimRpfTocEntry* tocEntry = toc->getTocEntry(entry);
82  if (tocEntry)
83  {
84  if ( tocEntry->isEmpty() == false )
85  {
86  writeDotRpfFile(toc.get(), tocEntry, outputDir, entry);
87  }
88  }
89  else
90  {
91  std::string e = MODULE;
92  e += " ERROR: Null entry: ";
93  e += ossimString::toString(entry).string();
94  throw ossimException(e);
95  }
96  }
97 
98 } // End: ossimRpfUtil::writeDotRpfFiles
99 
100 //---
101 // Writer a dot rpf file for entry to output directory.
102 //
103 // NOTES:
104 //
105 // 1) All coordinate written out in AREA or edge to edge format.
106 // 2) Throws ossimException on error.
107 //---
109  const ossimRpfTocEntry* tocEntry,
110  const ossimFilename& outputDir,
111  ossim_uint32 entry)
112 {
113  static const char MODULE[] = "ossimRpfUtil::writeDotRpfFile";
114 
115  if ( traceDebug() )
116  {
118  << MODULE << " entered..."
119  << "\noutput directory: " << outputDir
120  << "\nentry: " << entry << "\n";
121  }
122 
123  if ( !toc )
124  {
125  std::string errMsg = MODULE;
126  errMsg += " ERROR toc pointer null!";
127  throw ossimException(errMsg);
128  }
129  if ( !tocEntry )
130  {
131  std::string errMsg = MODULE;
132  errMsg += " ERROR toc entry pointer null!";
133  throw ossimException(errMsg);
134  }
135 
136  // Get the file name.
137  ossimFilename outFile;
138  if ( outputDir.expand().isDir() )
139  {
140  getDotRfpFilenameForEntry(outputDir, entry, outFile);
141  }
142  else
143  {
144  outFile = outputDir;
145  }
146 
147  // Open the file to write.
148  std::ofstream os;
149  os.open(outFile.c_str(), ios::out);
150  if ( os.good() == false )
151  {
152  std::string errMsg = MODULE;
153  errMsg += "ERROR could not open: ";
154  errMsg += outFile.string();
155  throw ossimException(errMsg);
156  }
157 
158  // Set up the output stream fix with full precision for ground points.
159  os << setiosflags(std::ios_base::fixed) << setprecision(15);
160 
161  //---
162  // Overall TOC entry bounds:
163  //
164  // Write the first line which is the bounding box of the entry in the form of:
165  // "89.9850464205332, 23.9892538162654|90.5085823882692, 24.5002602501599|1"
166  // lr-lon lr-lat ul-lon ul-lat
167  //---
169  if( geom.valid() == false)
170  {
171  std::string errMsg = "ERROR could not get geometry.";
172  errMsg += outFile.string();
173  throw ossimException(errMsg);
174  }
175 
176  // Rectangle in image space.
177  ossimIrect outputRect;
178  tocEntry->getBoundingRect(outputRect);
179 
180  // bands:
181  ossim_uint32 bands = tocEntry->getNumberOfBands();
182 
183  // scale:
184  ossimDpt scale;
185  tocEntry->getDecimalDegreesPerPixel(scale);
186  ossimDpt halfPix = scale / 2.0;
187 
188  ossimGpt llg;
189  ossimGpt urg;
190  geom->localToWorld(outputRect.ur(), urg);
191  geom->localToWorld(outputRect.ll(), llg);
192 
193  if ( traceDebug() )
194  {
196  << "outputRect: " << outputRect
197  << "\nbands: " << bands
198  << "\nscale: " << scale
199  << "\nllg: " << llg
200  << "\nurg: " << urg
201  << std::endl;
202  }
203 
204  // Expand coordinates to edge:
205  llg.lon -= halfPix.x;
206  llg.lat -= halfPix.y;
207  urg.lon += halfPix.x;
208  urg.lat += halfPix.y;
209 
210  // Test for 360 degrees apart.
211  checkLongitude(llg, urg);
212 
213  os << llg.lon << "," // lower left longitude
214  << llg.lat << "|" // lower left latitude
215  << urg.lon << "," // upper right longitude
216  << urg.lat << "|" // upper right latitude
217  << bands << "\n";
218 
219  // Frame loop:
220  const ossim_int32 FRAMESIZE = 1536;
221  const ossim_int32 ROWS = static_cast<ossim_int32>(tocEntry->getNumberOfFramesVertical());
222  if( ROWS == 0 )
223  {
224  std::string errMsg = MODULE;
225  errMsg += " ERROR no rows!";
226  throw ossimException(errMsg);
227  }
228  const ossim_int32 COLS = static_cast<ossim_int32>(tocEntry->getNumberOfFramesHorizontal());
229  if( COLS == 0 )
230  {
231  std::string errMsg = MODULE;
232  errMsg += " ERROR no columns!";
233  throw ossimException(errMsg);
234  }
235 
236  // Set the initial lower left and upper right image points for localToWorld call.
237  //ossimDpt urd( ( (ROWS-1)*FRAMESIZE) -1, 0.0);
238  //ossimDpt lld(0.0, (ROWS*FRAMESIZE)-1);
239  ossimDpt urd( FRAMESIZE-1, 0.0);
240  ossimDpt lld(0.0, FRAMESIZE-1);
241 
242  for (ossim_int32 row = ROWS-1; row > -1; --row)
243  {
244  for (ossim_int32 col = 0; col < COLS; ++col)
245  {
246  //---
247  // Example format (only with 15 digit precision):
248  // /data/spadac/rpf/world/cb01/ng467a1/0xslpk1a.i41|90.0448,24.3621|90.0598,24.3750
249  //---
250 
251  // Get the path to the frame.
252  ossimFilename path;
253  toc->getRootDirectory(path);
254 
255  path = path.dirCat( toc->getRelativeFramePath(entry, row, col) );
256 
257  // Not sure if this is backwards:
258  geom->localToWorld(urd, urg);
259  geom->localToWorld(lld, llg);
260 
261  // Expand coordinates to edge:
262  llg.lon -= halfPix.x;
263  llg.lat -= halfPix.y;
264  urg.lon += halfPix.x;
265  urg.lat += halfPix.y;
266 
267  // Test for 360 degrees apart.
268  checkLongitude(llg, urg);
269 
270  os << path.c_str() << "|"
271  << llg.lon << "," // lower left longitude
272  << llg.lat << "|" // lower left latitude
273  << urg.lon << "," // upper right longitude
274  << urg.lat // upper right latitude
275  << "\n";
276 
277  if ( traceDebug() )
278  {
280  << "row[" << row << "]col[" << col << "]path: " << path
281  << "\nlld: " << lld
282  << "\nllg: " << llg
283  << "\nurd: " << urd
284  << "\nurg: " << urg
285  << std::endl;
286  }
287 
288  // Go to next col.
289  urd.x += FRAMESIZE;
290  lld.x += FRAMESIZE;
291 
292  } // End column loop.
293 
294  // Go to nex row.
295  urd.y += FRAMESIZE;
296  urd.x = FRAMESIZE-1;
297  lld.y += FRAMESIZE;
298  lld.x = 0;
299 
300  } // End row loop.
301 
302  // Close the file.
303  os.close();
304 
305  ossimNotify(ossimNotifyLevel_DEBUG) << "wrote file: " << outFile << std::endl;
306 
307 } // End: ossimRpfUtil::writeDotRpfFile
308 
310 {
311  //---
312  // Test for scene coordinates being 180 to 180 (360 degree spread) and
313  // adjust leftLon to -180 if so.
314  //
315  // NOTE:
316  // Setting tolerance to 1/7200 about 15 meters.
317  // Not sure if this is too loose or not. (drb)
318  //---
319  const ossim_float64 TOLERANCE = 0.000138889; // 1/7200 about 15 meters.
320 
321  if ( ossim::almostEqual(left.lon, 180.0, TOLERANCE) )
322  {
323  if ( ossim::almostEqual(right.lon, 180.0, TOLERANCE) )
324  {
325  left.lon = -180.0;
326  right.lon = 180.0;
327  }
328  }
329 }
330 
332  ossim_uint32 entry,
333  ossimFilename& outFile) const
334 {
335  // Get the build date in the format of (yyyymmddhhmmss).
336  char s[15];
337  s[14] = '\0';
338  time_t t;
339  time(&t);
340  tm* lt = localtime(&t);
341  strftime(s, 15, "%Y%m%d%H%M%S", lt);
342  std::string date = s;
343 
344  outFile = outputDir.dirCat(s);
345  outFile += "_e";
346  outFile += ossimString::toString(entry);
347  outFile += ".rpf";
348 }
ossim_uint32 getNumberOfEntries() const
void writeDotRpfFile(const ossimRpfToc *toc, const ossimRpfTocEntry *tocEntry, const ossimFilename &outputDir, ossim_uint32 entry)
static const ossimErrorCode OSSIM_OK
void getDotRfpFilenameForEntry(const ossimFilename &outputDir, ossim_uint32 entry, ossimFilename &outFile) const
Method to get the file for entry.
bool valid() const
Definition: ossimRefPtr.h:75
ossimFilename expand() const
Method to do file name expansion.
bool almostEqual(T x, T y, T tolerance=FLT_EPSILON)
Definition: ossimCommon.h:53
ossim_uint32 getNumberOfFramesVertical() const
double y
Definition: ossimDpt.h:165
const ossimString getRelativeFramePath(ossim_uint32 entryIdx, ossim_uint32 row, ossim_uint32 col) const
For the given entry index, frame row, and frame column, this routine returns the corresponding name o...
static ossimString toString(bool aValue)
Numeric to string methods.
ossimRefPtr< ossimImageGeometry > getImageGeometry() const
Returns the image geometry object associated with this tile source or NULL if non defined...
virtual ~ossimRpfUtil()
protected virtual destructor
bool isDir() const
const ossimIpt & ll() const
Definition: ossimIrect.h:277
double ossim_float64
bool exists() const
ossim_float64 lon
Definition: ossimGpt.h:266
bool localToWorld(const ossimDpt &local_pt, ossimGpt &world_pt) const
Exposes the 3D projection from image to world coordinates.
unsigned int ossim_uint32
const ossimRpfTocEntry * getTocEntry(ossim_uint32 index) const
void getBoundingRect(ossimIrect &rect) const
Get the bounding rect of entry.
ossimErrorCode parseFile(const ossimFilename &fileName, bool keepFileHeader=false)
Parses a.toc file.
Definition: ossimRpfToc.cpp:55
const ossimIpt & ur() const
Definition: ossimIrect.h:275
void writeDotRpfFiles(const ossimFilename &aDotTocFile, const ossimFilename &outputDir)
Write dot rpf file(s) to output directory from a.toc file.
ossimRpfUtil()
default constructor
ossim_uint32 getNumberOfFramesHorizontal() const
void getRootDirectory(ossimFilename &dir) const
Method to get the root directory from the a.toc file name.
double x
Definition: ossimDpt.h:164
ossimFilename dirCat(const ossimFilename &file) const
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
ossim_uint32 getNumberOfBands() const
ossim_float64 lat
Definition: ossimGpt.h:265
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
void getDecimalDegreesPerPixel(ossimDpt &scale) const
Get the scale in decimal degrees per pixel.
bool createDirectory(bool recurseFlag=true, int perm=0775) const
void checkLongitude(ossimGpt &left, ossimGpt &right) const
Method to test for 360 spread, 180.0 <–> 180.00 and set leftLon to -180 if both left and right are 1...
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
int ossim_int32
const std::string & string() const
Definition: ossimString.h:414