OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimUsgsQuad.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts
6 // Description:
7 //
8 //*************************************************************************
9 // $Id: ossimUsgsQuad.cpp 12953 2008-06-01 16:24:05Z dburken $
10 
11 #include <cstdlib>
12 #include <sstream>
13 #include <iomanip>
14 
16 #include <ossim/base/ossimDatum.h>
17 #include <ossim/base/ossimTrace.h>
18 #include <ossim/base/ossimNotify.h>
19 
20 using namespace std;
21 
22 static const
23 double QUARTER_QUAD_SEG_SIZE_IN_DEGREES = 0.03125; // 3.75 minutes/60.0/2.0
24 static const double QUARTER_QUAD_SIZE_IN_DEGREES = 0.0625; // 3.75 minutes/60.0
25 static const double QUAD_SIZE_IN_DEGREES = 0.125; // 7.5 minutes/60
26 
27 
28 //***
29 // Static trace for debugging
30 //***
31 static ossimTrace traceDebug("USGS_quad::debug");
32 
33 
35  :
36  theQuadLowerRightCorner(0.0, 0.0, 0.0, lrGpt.datum()),
37  theQuarterQuadLowerRightCorner(0.0, 0.0, 0.0, lrGpt.datum())
38 // thePaddingInDegrees(0.0, 0.0),
39 
40 {
41  const char* MODULE = "ImgOutput::quadBasename";
42 
43  //***
44  // NOTE:
45  // This method computes a file name from the lower right corner of the
46  // image. The format is derived from USGS Digital Raster Graphic(DRG)
47  // program for standardized data set names for DRG products. Due to
48  // customer requirements there is one deviation: The first digit of the
49  // name is converted to a letter with 1 being = A, 2 being = B,
50  // 3 being = C, ....
51  // This was done to allow the name to be used on a pc.
52  //***
53 
54  const double QUAD_SIZE_IN_DEGREES = 0.125;
55 
56  ossimString baseString;
57  int tmpInt;
58  double tmpDbl;
59  char quadChar = 'A';
60  char quadNum = '1';
61 
62  ostringstream os;
63  os << setiosflags(ios::right)
64  << setiosflags(ios::fixed)
65  << setfill('0');
66 
67  tmpInt = static_cast<int>(abs(lrGpt.lat)); // Cast away the fractional part.
68  os << tmpInt; // latitude
69 
70  //***
71  // Get the quadrant charactor in the latitude direction. (A - H)
72  //***
73  tmpDbl = fabs(lrGpt.lat) - (double)tmpInt;
74  quadChar += static_cast<int>(tmpDbl / QUAD_SIZE_IN_DEGREES);
75 
76  tmpInt = static_cast<int>(abs(lrGpt.lon)); // longitude
77  os << setw(3) << tmpInt;
78 
79  tmpDbl = fabs(lrGpt.lon) - (double)tmpInt;
80 
81  quadNum += static_cast<char>(tmpDbl / QUAD_SIZE_IN_DEGREES);
82 
83  os << quadChar << quadNum;
84 
85  double latFraction = (lrGpt.lat / QUAD_SIZE_IN_DEGREES) -
86  ossim::round<int>((lrGpt.lat) / QUAD_SIZE_IN_DEGREES);
87  double lonFraction = (lrGpt.lon / QUAD_SIZE_IN_DEGREES) -
88  ossim::round<int>((lrGpt.lon) / QUAD_SIZE_IN_DEGREES);
89 
90  // Black & White
91 // if(theRectsStandardFlag &&
92 // theChipSource->radiometry().numberOfBands() == 1)
93 // {
94 // char quarterQuadChar = '4';
95 // if (latFraction && lonFraction)
96 // {
97 // quarterQuadChar = '1';
98 // }
99 // else if (latFraction && !lonFraction)
100 // {
101 // quarterQuadChar = '2';
102 // }
103 // else if (!latFraction && lonFraction)
104 // {
105 // quarterQuadChar = '3';
106 // }
107 // os << quarterQuadChar << ends;
108 // }
109 // // Color
110 // else if(theRectsStandardFlag &&
111 // theChipSource->radiometry().numberOfBands() > 1)
112 // {
113 // char quarterQuadChar = '8';
114 // if (latFraction && lonFraction)
115 // {
116 // quarterQuadChar = '5';
117 // }
118 // else if (latFraction && !lonFraction)
119 // {
120 // quarterQuadChar = '6';
121 // }
122 // else if (!latFraction && lonFraction)
123 // {
124 // quarterQuadChar = '7';
125 // }
126 // os << quarterQuadChar << ends;
127 // }
128 // else
129 // {
130  char quarterQuadChar = 'D';
131  if (latFraction && lonFraction)
132  {
133  quarterQuadChar = 'A';
134  }
135  else if (latFraction && !lonFraction)
136  {
137  quarterQuadChar = 'B';
138  }
139  else if (!latFraction && lonFraction)
140  {
141  quarterQuadChar = 'C';
142  }
143  os << quarterQuadChar << ends;
144 // }
145 
146 
147  baseString = os.str().c_str();
148 
149  if (traceDebug())
150  {
152  << " DEBUG: " << MODULE
153  << "\nbaseString: " << baseString << std::endl;
154  }
155 
156  setQuadName(baseString);
157 }
158 
159 
160 //***************************************************************************
161 // USGS_quad::USGS_quad(const String& name)
162 //***************************************************************************
164  const ossimDatum* datum)
165 // double paddingInMeters)
166  :
167  theQuadLowerRightCorner(0.0, 0.0, 0.0, datum),
168  theQuarterQuadLowerRightCorner(0.0, 0.0, 0.0, datum)
169 // thePaddingInDegrees(0.0, 0.0),
170 {
171  static const char MODULE[] = "ossimUsgsQuad::ossimUsgsQuad";
172 
173  setQuadName(name);
174  if (!datum)
175  {
176  if (traceDebug())
177  {
179  << "FATAL: " << MODULE << "\n"
180  << "ossimDatum pointer passed in is null. Returning...\n";
181  }
182  return;
183  }
184 
185 
186  //***
187  // Initialize the padding.
188  //***
189 // ossimGpt metersPerDegree = theQuadLowerRightCorner.metersPerDegree();
190 
191 // thePaddingInDegrees.u = paddingInMeters / metersPerDegree.u;
192 // thePaddingInDegrees.v = paddingInMeters / metersPerDegree.v;
193 
194 }
195 
197 {
198  const char* MODULE = "ossimUsgsQuad::setQuadName";
199  ossimString qqName = name;
200 
201  //***
202  // Check the length of "name" to see if it's correct.
203  //***
204  if (name.length() < 7)
205  {
206  if (traceDebug())
207  {
209  << "FATAL: " << MODULE << "\n"
210  << "Quarder quad name length incorrect.\n"
211  << "Name: " << name << "\n"
212  << "Expected length: 7 or 8 Name length: " << name.length()
213  << "\nExample of valid quad: 30089C6B\n"
214  << "Represents lower right corner of "
215  << "30 deg. 15 min. N., 89 deg. 37.5 min. W.\n"
216  << "Breakdown:\n"
217  << "30 = latitude on even degree boundary "
218  << "(Northern Hemisphere implied)\n"
219  << "089 = longitude on even degree boundary "
220  << "(Western Hemisphere implied)\n"
221  << "C = Third quad section in latitude direction\n"
222  << "6 = Sixth quad section in longitude direction\n"
223  << "B = Quarter quad segment within the quad\n"
224  << " (A=upper left, B=upper right, C=lower left, D=lower right)\n"
225  << "Quad size 7.5 minute square, quarter quad size 3.75 "
226  << "minute square.\n";
227  }
228 
229  return;
230  }
231 
232  qqName.upcase();
233 
234  char latChars[3];
235  char lonChars[4];
236  char latQuad;
237  char lonQuad;
238 // char segment;
239 
240  //***
241  // Get the latitude.
242  //***
243  latChars[0] = qqName.c_str()[0];
244  latChars[1] = qqName.c_str()[1];
245  latChars[2] = '\0';
246 
247  //***
248  // Get the longitude.
249  //***
250  lonChars[0] = qqName.c_str()[2];
251  lonChars[1] = qqName.c_str()[3];
252  lonChars[2] = qqName.c_str()[4];
253  lonChars[3] = '\0';
254 
255  //***
256  // Get the latitude quad.
257  //***
258  latQuad = qqName.c_str()[5];
259 
260  //***
261  // Get the longitude quad.
262  //***
263  lonQuad = qqName.c_str()[6];
264 
265  //***
266  // Get the segment within the quad.
267  //***
268  if (name.length() == 8)
269  {
270  theQuarterQuadSegment = qqName.c_str()[7];
271  }
272  else
273  {
274  theQuarterQuadSegment = 'D';
275  if (traceDebug())
276  {
278  << MODULE << ":\n"
279  << "No quarter quad segment entered. Defaulting to D segment."
280  << std::endl;
281  }
282  }
283 
284  //***
285  // Build up the lower right corner from the extracted parts.
286  //***
287 
288  //***
289  // Get the latitude and check the range.
290  //***
291  double lat = atof(latChars);
292  if ( (lat < 0.0) || (lat > 90.0) )
293  {
294  if (traceDebug())
295  {
297  << "FATAL: " << MODULE << "\n"
298  << "Latitude range error. Latitude extracted: " << lat
299  << "\nRange: 0 to 90\n";
300  }
301  return;
302  }
303 
304  //***
305  // Get the longitude and check the range.
306  //***
307  double lon = atof(lonChars);
308  if ( (lon < 0.0) || (lon > 180) )
309  {
310  if (traceDebug())
311  {
313  << "FATAL: " << MODULE << "\n"
314  << "Longitud range error. Longitude extracted: " << lon
315  << "\nRange: 0 to 180\n";
316  }
317  return;
318  }
319 
320  //***
321  // Get the latitude quad and add this to "lat". The quad are letters from
322  // A - H with A being on an even degree boundary, B being 7.5 minute up
323  // and so on.
324  //***
325  double tmp = latQuad - 65; // Ascii decimal value for A = 65.
326 
327  if (tmp)
328  {
329  //***
330  // Check the range. The are eight quads within one degree.
331  //***
332  if (tmp > 7.0)
333  {
334  if (traceDebug())
335  {
337  << "FATAL:" << MODULE << "\n"
338  << "Latitude quad range error. Quad extracted: " << latQuad
339  << "\nRange: A to H\n";
340  }
341  return;
342  }
343 
344  tmp *= 7.5; // Convert the quad to minutes.
345 
346  lat += tmp/60.0; // Conver minutes to degrees and add to "lat".
347  }
348 
349  //***
350  // Get the longitude quad and add this to "lat". The quad are letters from
351  // A - H with A being on an even degree boundary, B being 7.5 minute up
352  // and so on.
353  //***
354  tmp = lonQuad - 49; // Ascii decimal value for 1 = 49.
355 
356  if (tmp)
357  {
358  //***
359  // Check the range. The are eight quads within one degree.
360  //***
361  if (tmp > 7.0)
362  {
363  if (traceDebug())
364  {
366  << "FATAL:" << MODULE << "\n"
367  << "Longitude quad range error. Quad extracted: " << latQuad
368  << "\nRange: 1 to 8\n";
369  }
370  return;
371  }
372 
373  tmp *= 7.5; // Convert the quad to minutes.
374 
375  lon += tmp/60.0; // Conver minutes to degrees and add to "lon".
376  }
377 
378  //***
379  // Currently this naming convention assumes Northern and Western hemisphere.
380  //***
381  lon = -lon; // Make negative for Western hemisphere.
382 
383  //***
384  // Initialize "theQuadLowerRightCorner".
385  //***
388 
389  //***
390  // Get the segment and add to "lat" and "lon".
391  //***
392  switch (theQuarterQuadSegment)
393  {
394  case 'A':
395  lat += QUARTER_QUAD_SIZE_IN_DEGREES;
396  lon -= QUARTER_QUAD_SIZE_IN_DEGREES;
397  break;
398 
399  case 'B':
400  lat += QUARTER_QUAD_SIZE_IN_DEGREES;
401  break;
402 
403  case 'C':
404  lon -= QUARTER_QUAD_SIZE_IN_DEGREES;
405  break;
406 
407  case 'D':
408  break; // At the corner of a quad so nothing to do here.
409 
410  default:
411  if (traceDebug())
412  {
414  << "FATAL:" << MODULE << "\n"
415  << "Quarter quad segment range error.\n"
416  << "Quarter quad segment extracted: " << theQuarterQuadSegment
417  << "Range: A to D\n";
418  }
419  return;
420  }
421 
422  //***
423  // Initialize "theQuarterQuadLowerRightCorner".
424  //***
427 
428  if (traceDebug())
429  {
431  << "DEBUG: " << MODULE << ", "
432  << qqName << " lower right quad corner: "
433  << theQuadLowerRightCorner << "\n"
434  << "Quarter quad segment: " << theQuarterQuadSegment << "\n"
435  << qqName << " lower right quarter quad corner: "
437  }
438  theName = qqName;
439 }
440 
441 void ossimUsgsQuad::getQuadList(vector<ossimUsgsQuad>& result,
442  const ossimGrect& rect)
443 {
444  result.clear();
445 // QUAD_SIZE_IN_DEGREES;
446 
447  ossimGpt point = rect.ul();
448 
449  while(rect.pointWithin(point))
450  {
451  while(rect.pointWithin(point))
452  {
453  result.push_back(ossimUsgsQuad(point));
454 
455  point.lond(point.lond()+QUAD_SIZE_IN_DEGREES);
456  }
457  point.lond(rect.ul().lond());
458  point.latd(point.latd()-QUAD_SIZE_IN_DEGREES);
459  }
460 }
461 
462 
463 //***************************************************************************
464 // ossimUsgsQuad::quarterQuadSegRect()
465 //***************************************************************************
467 {
468  static const char MODULE[] = "ossimUsgsQuad::quarterQuadSegRect";
469 
470  double startLat=0.0;
471  double startLon=0.0;
472  double stopLat=0.0;
473  double stopLon=0.0;
474 
475  //***
476  // Get the segment and add to "lat" and "lon".
477  //***
478  switch (seg)
479  {
480  case 'A': // Upper left segment of quarter quad.
482  QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// -
483 // thePaddingInDegrees.u;
484 
486  QUARTER_QUAD_SIZE_IN_DEGREES;// -
487  //thePaddingInDegrees.v;
488 
490  QUARTER_QUAD_SIZE_IN_DEGREES;// +
491  //thePaddingInDegrees.u;
492 
494  QUARTER_QUAD_SEG_SIZE_IN_DEGREES; // +
495  //thePaddingInDegrees.v;
496  break;
497 
498  case 'B': // Upper right segment of the quarter quad.
500  QUARTER_QUAD_SEG_SIZE_IN_DEGREES; //-
501 // thePaddingInDegrees.u;
502 
504  QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// -
505 // thePaddingInDegrees.v;
506 
508  QUARTER_QUAD_SIZE_IN_DEGREES;// +
509 // thePaddingInDegrees.u;
510 
511  stopLon = theQuarterQuadLowerRightCorner.lon;// +
512 // thePaddingInDegrees.v;
513  break;
514 
515  case 'C': // Lower left segment of the quarter quad.
516  startLat = theQuarterQuadLowerRightCorner.lat;// -
517 // thePaddingInDegrees.u;
518 
520  QUARTER_QUAD_SIZE_IN_DEGREES;// -
521 // thePaddingInDegrees.v;
522 
524  QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// +
525 // thePaddingInDegrees.u;
526 
528  QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// +
529 // thePaddingInDegrees.v;
530 
531  break;
532 
533  case 'D':
534  startLat = theQuarterQuadLowerRightCorner.lat;// -
535 // thePaddingInDegrees.u;
536 
538  QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// -
539 // thePaddingInDegrees.v;
540 
542  QUARTER_QUAD_SEG_SIZE_IN_DEGREES;// +
543 // thePaddingInDegrees.u;
544 
545  stopLon = theQuarterQuadLowerRightCorner.lon;// +
546 // thePaddingInDegrees.v;
547  break; // At the corner of a quad so nothing to do here.
548 
549  default:
550  if (traceDebug())
551  {
553  << "FATAL:" << MODULE << "\n"
554  << "Quarter quad segment range error.\n"
555  << "Quarter quad segment extracted: " << seg
556  << "Range: A to D\n";
557  }
558  break;
559  }
560 
561  ossimGrect
562  rect(ossimGpt(startLat,
563  startLon,
566  ossimGpt(stopLat,
567  stopLon,
570 
571  if (traceDebug())
572  {
574  << "DEBUG: " << MODULE
575  << "\nQuarter quad segment " << seg << " rect: " << rect << "\n";
576  }
577 
578  return rect;
579 }
580 
581 //***************************************************************************
582 // ossimUsgsQuad::quarterQuadRect()
583 //***************************************************************************
585 {
586  static const char MODULE[] = "ossimUsgsQuad::quarterQuadRect";
587 
588  double startLat = theQuarterQuadLowerRightCorner.lat;// -
589 // thePaddingInDegrees.u; // SouthWest corner lat.
590 
591  double startLon = theQuarterQuadLowerRightCorner.lon -
592  QUARTER_QUAD_SIZE_IN_DEGREES;// -
593 // thePaddingInDegrees.v; // SouthWest corner lon.
594 
595  double stopLat = theQuarterQuadLowerRightCorner.lat +
596  QUARTER_QUAD_SIZE_IN_DEGREES;// +
597 // thePaddingInDegrees.u; // NorthEast corner lat.
598 
599  double stopLon = theQuarterQuadLowerRightCorner.lon;// +
600 // thePaddingInDegrees.v; // NorthEast corner lon.
601 
602  ossimGrect
603  rect(ossimGpt(startLat,
604  startLon,
607  ossimGpt(stopLat,
608  stopLon,
611 
612  if (traceDebug())
613  {
615  << "DEBUG: " << MODULE
616  << "\nQuarter quad rect: " << rect <<"\n";
617  }
618 
619 
620  return rect;
621 }
622 
623 //***************************************************************************
624 // ossimUsgsQuad::quadRect()
625 //***************************************************************************
627 {
628  static const char MODULE[] = "ossimUsgsQuad::quadRect";
629 
630  double startLat = theQuadLowerRightCorner.lat;// -
631 // thePaddingInDegrees.u; // SouthWest corner lat.
632 
633  double startLon = theQuadLowerRightCorner.lon -
634  QUAD_SIZE_IN_DEGREES;// -
635 // thePaddingInDegrees.v; // SouthWest corner lon.
636 
637  double stopLat = theQuadLowerRightCorner.lat +
638  QUAD_SIZE_IN_DEGREES;// +
639 // thePaddingInDegrees.u; // NorthEast corner lat.
640 
641  double stopLon = theQuadLowerRightCorner.lon;// +
642 // thePaddingInDegrees.v; // NorthEast corner lon.
643 
644  ossimGrect
645  rect(ossimGpt(startLat,
646  startLon,
649  ossimGpt(stopLat,
650  stopLon,
653 
654  if (traceDebug())
655  {
657  << "DEBUG: " << MODULE
658  << "\nQuarter quad rect: " << rect << "\n";
659  }
660 
661  return rect;
662 }
663 
664 //***************************************************************************
665 // ossimUsgsQuad::quarterQuadSegKwRect(char seg)
666 //***************************************************************************
668 {
669  static const char MODULE[] = "ossimUsgsQuad::quarterQuadSegKwRect";
670 
671  ossimString tmp;
672 
673  //***
674  // Check the range of the segment, must be A, B, C or D.
675  //***
676  if ( (seg < 65) || (seg > 68) )
677  {
678  if (traceDebug())
679  {
681  << "FATAL:" << MODULE << "\n"
682  << seg << " out of range!\n"
683  << "Possible values: A, B, C, or D\n";
684  }
685  return tmp;
686  }
687 
688  ossimGrect rect = quarterQuadSegRect(seg);
689 
690  ostringstream os;
691 
692  os << setprecision(12)
693  << rect.ll().lat << " "
694  << rect.ul().lon << " "
695  << rect.ul().lat << " "
696  << rect.ur().lon << ends;
697 // << rect.stop.lat << " "
698 // << rect.start.lon << " "
699 // << rect.start.lat << " "
700 // << rect.stop.lon << ends;
701 
702  tmp = os.str().c_str();
703 
704  return tmp;
705 }
706 
707 //***************************************************************************
708 // ossimUsgsQuad::quarterQuadKwRect()
709 //***************************************************************************
711 {
712 // static const char MODULE[] = "ossimUsgsQuad::quarterQuadKwRect";
713 
714  ossimGrect rect = quarterQuadRect();
715 
716  ostringstream os;
717 
718  os << setprecision(12)
719  << rect.ll().lat << " "
720  << rect.ul().lon << " "
721  << rect.ul().lat << " "
722  << rect.ur().lon << ends;
723 // os << setprecision(12)
724 // << rect.stop.lat << " "
725 // << rect.start.lon << " "
726 // << rect.start.lat << " "
727 // << rect.stop.lon << ends;
728 
729  ossimString tmp = os.str().c_str();
730 
731 
732 
733  return tmp;
734 }
735 
736 //***************************************************************************
737 // ossimUsgsQuad::quadKwRect()
738 //***************************************************************************
740 {
741 // static const char MODULE[] = "ossimUsgsQuad::quadKwRect";
742 
743  ossimGrect rect = quadRect();
744 
745  ostringstream os;
746 
747  os << setprecision(12)
748  << rect.ll().lat << " "
749  << rect.ul().lon << " "
750  << rect.ul().lat << " "
751  << rect.ur().lon << ends;
752 // os << setprecision(12)
753 // << rect.stop.lat << " "
754 // << rect.start.lon << " "
755 // << rect.start.lat << " "
756 // << rect.stop.lon << ends;
757 
758  ossimString tmp = os.str().c_str();
759 
760  return tmp;
761 }
ossimGrect quarterQuadSegRect(char seg)
char theQuarterQuadSegment
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
void setQuadName(const ossimString &name)
ossimGpt theQuadLowerRightCorner
Definition: ossimUsgsQuad.h:98
#define abs(a)
Definition: auxiliary.h:74
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
ossimString theName
Definition: ossimUsgsQuad.h:97
const ossimDatum * datum() const
datum().
Definition: ossimGpt.h:196
bool pointWithin(const ossimGpt &gpt, bool considerHgt=false) const
METHOD: pointWithin(ossimGpt)
Definition: ossimGrect.h:232
ossim_float64 lon
Definition: ossimGpt.h:266
std::string::size_type length() const
Definition: ossimString.h:408
double height() const
Definition: ossimGpt.h:107
const ossimGpt & ul() const
Definition: ossimGrect.h:252
ossimString quarterQuadKwRect() const
ossimGpt ur() const
Definition: ossimGrect.h:257
ossimString quadKwRect() const
ossimGpt theQuarterQuadLowerRightCorner
Definition: ossimUsgsQuad.h:99
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
ossimString quarterQuadSegKwRect(char seg)
ossim_float64 lat
Definition: ossimGpt.h:265
static void getQuadList(std::vector< ossimUsgsQuad > &result, const ossimGrect &rect)
ossimGrect quadRect() const
ossimGpt ll() const
Definition: ossimGrect.h:263
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
ossimGrect quarterQuadRect() const
ossimUsgsQuad(const ossimGpt &lrGpt)