OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimDoqq.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: LGPL
5 //
6 // See LICENSE.txt file in the top level directory for more details.
7 //
8 // Author: Ken Melero
9 //
10 // Description: This class parses a Digital Ortho Quarter Quad (DOQQ)
11 // header.
12 //
13 //********************************************************************
14 // $Id: ossimDoqq.cpp 22855 2014-08-05 14:46:38Z gpotts $
15 
16 #include <string.h>
18 #include <ossim/base/ossimTrace.h>
20 
21 static ossimTrace traceDebug("ossimDoqq:debug");
22 
23 //**************************************************************************
24 // CONSTRUCTOR
25 //**************************************************************************
27  : theErrorStatus(OSSIM_ERROR)
28 {
29 }
30 
31 //**************************************************************************
32 // CONSTRUCTOR
33 //**************************************************************************
35  : theErrorStatus(OSSIM_ERROR)
36 {
37  ossimInfoBase::open(file);
38  //theDoqFile.close();
39 }
40 
41 
42 bool ossimDoqq::open(std::shared_ptr<ossim::istream>& str,
43  const std::string& connectionString)
44 {
46  if(!str) return false;
47  char header[23];
48  str->clear();
49  str->seekg(0);
50  str->get(header, 22);
51 
52  header[22] = '\0';
53  if(strcmp((const char*)header, "BEGIN_USGS_DOQ_HEADER") == 0)
54  {
55  if(traceDebug())
56  {
58  << "ossimDoqq::ossimDoqq Loading DOQ version 2 header..."
59  << std::endl;
60  }
61 
62  ldstr_v2(*str);
63  }
64  else
65  {
66  if(traceDebug())
67  {
69  << "ossimDoqq::ossimDoqq Loading DOQ version 1 header..."
70  << std::endl;
71  }
72 
73  ldstr_v1(*str);
74  }
75 
76  // Check for error.
77  if(theErrorStatus)
78  return false;
79 
80  m_connectionString = connectionString;
81  m_doqqFileStr = str;
82  return true;
83 }
84 
85 
87 {
88  m_doqqFileStr.reset();
89 }
90 
92 {
93  static const char MODULE[] = "ossimDoqq::ldstr_v2(istream& in)";
94 
95  if (!in)
96  {
98  return;
99  }
100 
101  char line[100];
102  char dum1[30];
103  char dum2[30];
104  char dum3[30];
105  char dum4[30];
106 
107  while((strncmp(line, "END_USGS_HEADER", 15) != 0)&&
108  (in.good()))
109  {
110  // Read in one line of header at a time.
111  in.getline(line, 100);
112 
113  if(strncmp(line, "SAMPLES_AND_LINES", 17) == 0)
114  {
115  sscanf(line, "%s %s %s", dum1, dum2, dum3);
116  theLine = atoi(dum3);
117  theSample = atoi(dum2);
118  }
119 
120  else if(strncmp(line, "HORIZONTAL_COORDINATE_SYSTEM", 28) == 0)
121  {
122  sscanf(line, "%s %s", dum1, dum2);
123  theProjection = dum2;
124  }
125 
126  else if(strncmp(line, "NW_QUAD_CORNER_XY", 17) == 0)
127  {
128  sscanf(line, "%s %s %s", dum1, dum2, dum3);
129 
130  theUE = atof(dum2);
131  theUN = atof(dum3);
132  }
133 
134  else if(strncmp(line, "NE_QUAD_CORNER_XY", 17) == 0)
135  {
136  sscanf(line, "%s %s %s", dum1, dum2, dum3);
137  theLE = atof(dum2);
138  theLN = atof(dum3);
139  }
140 
141  else if(strncmp(line, "COORDINATE_ZONE", 15) == 0)
142  {
143  sscanf(line, "%s %s", dum1, dum2);
144  theUtmZone = atoi(dum2);
145  }
146 
147  else if(strncmp(line, "SOURCE_IMAGE_DATE", 17) == 0)
148  {
149  sscanf(line, "%s %s %s %s", dum1, dum2, dum3, dum4);
150  theAcqYear = ossimString(dum2);
151  theAcqMonth = ossimString(dum3);
152  theAcqDay = ossimString(dum4);
153  }
154 
155  else if((strncmp(line, "XY_ORIGIN", 9) == 0))
156  {
157  sscanf(line, "%s %s %s", dum1, dum2, dum3);
158  theEasting = atof(dum2);
159  theNorthing = atof(dum3);
160  }
161 
162  else if((strncmp(line, "HORIZONTAL_DATUM", 16) == 0) && theDatum.empty())
163  {
164  ossimString datum;
165  sscanf(line, "%s %s", dum1, dum2);
166  datum = dum2;
167 
168  if(datum.contains("NAD27"))
169  theDatum = "NAD";
170  else
171  theDatum = "NAR";
172  }
173 
174  else if(strncmp(line, "BYTE_COUNT", 10) == 0)
175  {
176  ossimString header;
177  sscanf(line, "%s %s", dum1, dum2);
178  header = dum2;
179 
180  theHeaderSize = atoi(header.chars());
181  }
182 
183  else if(strncmp(line, "BAND_CONTENT", 12) == 0)
184  {
185  ossimString rgbType;
186  sscanf(line, "%s %s", dum1, dum2);
187  rgbType = dum2;
188 
189  if(rgbType.contains("BLACK&WHITE"))
190  theRgb = 1;
191  else
192  theRgb = 3;
193  }
194 
195  else if(strncmp(line, "HORIZONTAL_RESOLUTION", 21) == 0)
196  {
197  ossimString gsd;
198  sscanf(line, "%s %s", dum1, dum2);
199  gsd = dum2;
200 
201  theGsd.x = gsd.toDouble();
202  theGsd.y = gsd.toDouble();
203  }
204 
205  else if(strncmp(line, "QUADRANGLE_NAME", 15) == 0)
206  {
207  sscanf(line, "%s %29c", dum1, dum2);
208  dum2[29] = 0;
209  theQuadName = dum2;
210  }
211 
212  else if(strncmp(line, "QUADRANT", 8) == 0)
213  {
214  sscanf(line, "%s %s", dum1, dum2);
215  theQuad = dum2;
216  }
217 
218  else if(strncmp(line, "NATION", 6) == 0)
219  {
220  sscanf(line, "%s %s", dum1, dum2);
221  theNation = dum2;
222  }
223 
224  else if(strncmp(line, "STATE", 5) == 0)
225  {
226  sscanf(line, "%s %s", dum1, dum2);
227  theState = dum2;
228  }
229 
230  else if(strncmp(line, "RMSE_XY", 7) == 0)
231  {
232  sscanf(line, "%s %s", dum1, dum2);
233  theRMSE = ossimString(dum2).toDouble();
234  }
235 
236  else if(strncmp(line, "IMAGE_SOURCE", 12) == 0)
237  {
238  sscanf(line, "%s %29c", dum1, dum2);
239  dum2[29] = 0;
240  theImageSource = dum2;
241  }
242 
243  else if(strncmp(line, "SOURCE_IMAGE_ID", 15) == 0)
244  {
245  sscanf(line, "%s %29c", dum1, dum2);
246  dum2[29] = 0;
247  theSourceImageID = dum2;
248  }
249  }
250 
251  if (!in.good())
252  {
254  if(traceDebug())
255  {
257  << MODULE << " ERROR:\n"
258  << "\tHeader stream is bad."
259  << std::endl;
260  }
261  return;
262  }
263 
264  // Check for valid lines and samples and header size.
265  if(theLine <= 0 || theSample <= 0 || theHeaderSize <= 0)
266  {
268  if(traceDebug())
269  {
271  << MODULE << " ERROR:\n"
272  << "\tInvalid lines or samples or header size."
273  << std::endl;
274  }
275  return;
276  }
277 
278  // Assign concatenated acquisition date:
280  theAcqYearMonthDay += "-";
282  theAcqYearMonthDay += "-";
284 
285 }
286 
288 {
289  static const char MODULE[] = "ossimDoqq::ldstr_v1(istream& in)";
290 
291  if (!in)
292  {
294  return;
295  }
296 
297  char tmp1[DATA_ORDER_SIZE+1];
298  in.seekg(DATA_ORDER_OFFSET, std::ios::beg);
299  in.get(tmp1, DATA_ORDER_SIZE+1);
300  theDataOrder = tmp1;
301 
302  //***
303  // Perform a sanity check on the data order just in case this isn't a
304  // ossimDoqq file.
305  //***
306  tmp1[DATA_ORDER_SIZE] = '\0';
307  int data_order = atoi(tmp1);
308  if ( (data_order != 1) && (data_order != 2) )
309  {
311 
312  if(traceDebug())
313  {
315  << MODULE << " NOTICE:\n"
316  << "Invalid data ordering. Not a doq?" << std::endl;
317  }
318  }
319 
320  char tmp2[LINE_SIZE+1];
321  in.seekg(LINE_OFFSET, std::ios::beg);
322  in.get(tmp2, LINE_SIZE+1);
323  theLine = atoi(tmp2);
324 
325  char tmp3[SAMPLE_SIZE+1];
326  in.seekg(SAMPLE_OFFSET,std::ios::beg);
327  in.get(tmp3, SAMPLE_SIZE+1);
328  theSample = atoi(tmp3);
329 
330  // Check for valid lines and samples.
331  if (theLine <= 0 || theSample <= 0)
332  {
334 
335  if(traceDebug())
336  {
338  << MODULE << " ERROR:\n"
339  << "\tInvalid lines or samples."
340  << std::endl;
341  }
342 
343  return;
344  }
345 
346  char tmp4[PROJECTION_SIZE+1];
347  in.seekg(PROJECTION_OFFSET, std::ios::beg);
348  in.get(tmp4, PROJECTION_SIZE+1);
349  theProjection = tmp4;
350 
351  char tmp5[UTM_ZONE_SIZE+1];
352  in.seekg(UTM_ZONE_OFFSET, std::ios::beg);
353  in.get(tmp5, UTM_ZONE_SIZE+1);
354  theUtmZone = atoi(tmp5);
355 
356  char tmp8[DATUM_SIZE+1];
357  in.seekg(DATUM_OFFSET, std::ios::beg);
358  in.get(tmp8, DATUM_SIZE+1);
359  theDatum = tmp8;
360 
361  char rgbType[RGB_SIZE+1];
362  in.seekg(RGB_OFFSET, std::ios::beg);
363  in.get(rgbType, RGB_SIZE+1);
364 
365 
366  if(atoi(rgbType) == 5)
367  {
368  theRgb = 3;
369  }
370  else
371  {
372  theRgb = 1;
373  }
374 
375  theHeaderSize = (theSample * theRgb * 4);
376 
377  // Calculate the size of each record.
379 
380  char tmp6[UL_EASTING_SIZE+1];
381  in.seekg( (theRecordSize * 2) + UL_EASTING_OFFSET, std::ios::beg);
382  in.get(tmp6, UL_EASTING_SIZE+1);
383 
384  char tmp7[UL_NORTHING_SIZE+1];
385  in.seekg( (theRecordSize * 2) + UL_NORTHING_OFFSET, std::ios::beg);
386  in.get(tmp7, UL_NORTHING_SIZE+1);
387 
388  // Get Easting and Northing.
389  theEasting = convertStr(tmp6);
390  theNorthing = convertStr(tmp7);
391 
392  char tmp10[GSD_SIZE+1];
393  in.seekg( (theRecordSize*3) + GSD_X_OFFSET, std::ios::beg);
394  in.get(tmp10, GSD_SIZE+1);
395  theGsd.x = std::abs(ossimString(tmp10, tmp10+GSD_SIZE).toDouble());
396  in.seekg( (theRecordSize*3) + GSD_Y_OFFSET, std::ios::beg);
397  in.get(tmp10, GSD_SIZE+1);
398  theGsd.y = std::abs(ossimString(tmp10, tmp10+GSD_SIZE).toDouble());
399 
400 }
401 
402 ossim_float64 ossimDoqq::convertStr(const char* str) const
403 {
404  //***
405  // The USGS Projection Parameters in a OssimDoqq header have a "D" to
406  // denote the exponent. This simply substitutes the "D" with an
407  // "E" so that atof works properly.
408  //***
409  ossimString tmp = str;
410  tmp.gsub("D", "E");
411  return tmp.toFloat64();
412 }
413 
415 {
416  const char* prefix = "doqq.";
417  out << prefix << "Quadrangle_Name: " << theQuadName << std::endl;
418  out << prefix << "Quadrant: " << theQuad << std::endl;
419  out << prefix << "Image_Source: " << theImageSource << std::endl;
420  out << prefix << "Source_Image_ID: " << theSourceImageID << std::endl;
421  out << prefix << "RMSE_XY: " << theRMSE << std::endl;
422  out << prefix << "Line: " << theLine << std::endl;
423  out << prefix << "Sample: " << theSample << std::endl;
424  out << prefix << "Projection: " << theProjection << std::endl;
425  out << prefix << "Datum: " << theDatum << std::endl;
426  out << prefix << "Easting: " << theEasting << std::endl;
427  out << prefix << "Northing: " << theNorthing << std::endl;
428  out << prefix << "UN: " << theUN << std::endl;
429  out << prefix << "UE: " << theUE << std::endl;
430  out << prefix << "LN: " << theLN << std::endl;
431  out << prefix << "LE: " << theLE << std::endl;
432  out << prefix << "GSD: " << theGsd << std::endl;
433  out << prefix << "Band: " << theRgb << std::endl;
434  out << prefix << "Utm_Zone: " << theUtmZone << std::endl;
435 
436  return out;
437 }
virtual bool open(const ossimFilename &file)
open method.
ossimString theQuad
Definition: ossimDoqq.h:90
ossimString theSourceImageID
Definition: ossimDoqq.h:97
ossim_float64 theEasting
Definition: ossimDoqq.h:111
ossimString theQuadName
Definition: ossimDoqq.h:89
virtual bool open(std::shared_ptr< ossim::istream > &str, const std::string &connectionString)
open method.
Definition: ossimDoqq.cpp:42
ossimString theNation
Definition: ossimDoqq.h:91
ossimString theImageSource
Definition: ossimDoqq.h:96
double y
Definition: ossimDpt.h:165
ossimString theAcqYearMonthDay
Definition: ossimDoqq.h:107
bool contains(char aChar) const
Definition: ossimString.h:58
ossim_int32 theUtmZone
Definition: ossimDoqq.h:99
ossimString theDatum
Definition: ossimDoqq.h:88
ossimString theState
Definition: ossimDoqq.h:92
std::shared_ptr< ossim::istream > m_doqqFileStr
Definition: ossimDoqq.h:125
ossim_int32 theRecordSize
Definition: ossimDoqq.h:119
#define abs(a)
Definition: auxiliary.h:74
void ldstr_v1(std::istream &in)
Definition: ossimDoqq.cpp:287
ossimDpt theGsd
Definition: ossimDoqq.h:117
ossim_float64 theRMSE
Definition: ossimDoqq.h:109
ossim_int32 theLine
Definition: ossimDoqq.h:100
double ossim_float64
void ldstr_v2(std::istream &in)
Definition: ossimDoqq.cpp:91
std::string m_connectionString
Definition: ossimDoqq.h:126
ossimString theProjection
Definition: ossimDoqq.h:87
const char * chars() const
For backward compatibility.
Definition: ossimString.h:77
double toDouble() const
ossim_float64 toFloat64() const
virtual std::ostream & print(std::ostream &out) const
Implementation of ossimInfoBase class pure virtual.
Definition: ossimDoqq.cpp:414
ossim_float64 theUN
Definition: ossimDoqq.h:113
ossim_int32 theHeaderSize
Definition: ossimDoqq.h:118
ossimString theDataOrder
Definition: ossimDoqq.h:93
ossim_float64 theNorthing
Definition: ossimDoqq.h:112
std::basic_istream< char > istream
Base class for char input streams.
Definition: ossimIosFwd.h:20
ossim_float64 theUE
Definition: ossimDoqq.h:114
ossim_int32 theSample
Definition: ossimDoqq.h:101
double x
Definition: ossimDpt.h:164
bool empty() const
Definition: ossimString.h:411
ossim_float64 theLN
Definition: ossimDoqq.h:115
ossimString theAcqMonth
Definition: ossimDoqq.h:105
ossimString & gsub(const ossimString &searchKey, const ossimString &replacementValue, bool replaceAll=false)
Substitutes searchKey string with replacementValue and returns a reference to *this.
ossimErrorStatus theErrorStatus
Definition: ossimDoqq.h:127
ossimString theAcqYear
Definition: ossimDoqq.h:104
ossim_float64 convertStr(const char *str) const
Definition: ossimDoqq.cpp:402
ossim_float64 theLE
Definition: ossimDoqq.h:116
ossim_int32 theRgb
Definition: ossimDoqq.h:102
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
ossimString theAcqDay
Definition: ossimDoqq.h:106