OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimFormosatDimapSupportData.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------
2 //
3 // "Copyright Centre National d'Etudes Spatiales"
4 //
5 // License: LGPL
6 //
7 // See LICENSE.txt file in the top level directory for more details.
8 //
9 //----------------------------------------------------------------------------
10 // $Id$
11 
12 
13 #include <iostream>
14 #include <cstdlib>
15 #include <iterator>
22 #include <ossim/base/ossimDatum.h>
24 #include <ossim/base/ossimTrace.h>
26 #include <sstream>
27 
28 // Define Trace flags for use within this file:
29 static ossimTrace traceDebug ("ossimFormosatDimapSupportData:debug");
30 
31 static const ossim_uint32 LAGRANGE_FILTER_SIZE = 8; // num samples considered
32 
34  :
36  theMetadataVersion(OSSIM_FORMOSAT_METADATA_VERSION_UNKNOWN),
37  theImageID(),
38  theMetadataFile(),
39  theProductionDate(),
40  theSoftwareVersion(),
41  theInstrument(),
42  theInstrumentIndex(0),
43  theSunAzimuth(0.0),
44  theSunElevation(0.0),
45  theSatAzimuth(0.0),
46  theIncidenceAngle(0.0),
47  theViewingAngle(0.0),
48  theViewingAngleAlongTrack(0.0),
49  theViewingAngleAcrossTrack(0.0),
50  theSceneOrientation(0.0),
51  theImageSize(0.0, 0.0),
52  theRefGroundPoint(0.0, 0.0, 0.0),
53  theRefImagePoint(0.0, 0.0),
54  theSubImageOffset(0.0, 0.0),
55  theRefLineTime(0.0),
56  theRefLineTimeLine(0.0),
57  theLineSamplingPeriod(0.0),
58  thePolynomialLookAngleX(),
59  thePolynomialLookAngleY(),
60  theAttitudeSamples(),
61  theAttSampTimes(),
62  thePosEcfSamples(),
63  theVelEcfSamples(),
64  theEphSampTimes(),
65  theStarTrackerUsed(false),
66  theNumBands(0),
67  theAcquisitionDate(),
68  theFrameVertexPosImagePoints(),
69  theFrameVertexPosGroundPoints(),
70  theGeoPosImagePoints(),
71  theGeoPosGroundPoints()
72 {
73 }
76  theMetadataVersion(rhs.theMetadataVersion),
77  theImageID(rhs.theImageID),
78  theMetadataFile (rhs.theMetadataFile),
79  theProductionDate(rhs.theProductionDate),
80  theSoftwareVersion(rhs.theSoftwareVersion),
81  theInstrument(rhs.theInstrument),
82  theInstrumentIndex(rhs.theInstrumentIndex),
83  theSunAzimuth(rhs.theSunAzimuth),
84  theSunElevation(rhs.theSunElevation),
85  theSatAzimuth(rhs.theSatAzimuth),
86  theIncidenceAngle(rhs.theIncidenceAngle),
87  theViewingAngle(rhs.theViewingAngle),
88  theViewingAngleAlongTrack(rhs.theViewingAngle),
89  theViewingAngleAcrossTrack(rhs.theViewingAngle),
90  theSceneOrientation(rhs.theSceneOrientation),
91  theImageSize(rhs.theImageSize),
92  theRefGroundPoint(rhs.theRefGroundPoint),
93  theRefImagePoint(rhs.theRefImagePoint),
94  theSubImageOffset(rhs.theSubImageOffset),
95  theRefLineTime(rhs.theRefLineTime),
96  theRefLineTimeLine(rhs.theRefLineTimeLine),
97  theLineSamplingPeriod(rhs.theLineSamplingPeriod),
98  thePolynomialLookAngleX(rhs.thePolynomialLookAngleX),
99  thePolynomialLookAngleY(rhs.thePolynomialLookAngleY),
100  theAttitudeSamples(rhs.theAttitudeSamples),
101  theAttSampTimes(rhs.theAttSampTimes),
102  thePosEcfSamples(rhs.thePosEcfSamples),
103  theVelEcfSamples(rhs.theVelEcfSamples),
104  theEphSampTimes(rhs.theEphSampTimes),
105  theStarTrackerUsed(rhs.theStarTrackerUsed),
106  theNumBands(rhs.theNumBands),
107  theAcquisitionDate(rhs.theAcquisitionDate),
108  theFrameVertexPosImagePoints(rhs.theFrameVertexPosImagePoints),
109  theFrameVertexPosGroundPoints(rhs.theFrameVertexPosGroundPoints),
110  theGeoPosImagePoints(rhs.theGeoPosImagePoints),
111  theGeoPosGroundPoints(rhs.theGeoPosGroundPoints)
112 {
113 }
114 
116  :
118  theMetadataVersion(OSSIM_FORMOSAT_METADATA_VERSION_UNKNOWN),
119  theImageID(),
120  theMetadataFile (dimapFile),
121  theProductionDate(),
122  theSoftwareVersion(),
123  theInstrument(),
124  theInstrumentIndex(0),
125  theSunAzimuth(0.0),
126  theSunElevation(0.0),
127  theSatAzimuth(0.0),
128  theIncidenceAngle(0.0),
129  theViewingAngle(0.0),
130  theViewingAngleAlongTrack(0.0),
131  theViewingAngleAcrossTrack(0.0),
132  theSceneOrientation(0.0),
133  theImageSize(0.0, 0.0),
134  theRefGroundPoint(0.0, 0.0, 0.0),
135  theRefImagePoint(0.0, 0.0),
136  theSubImageOffset(0.0, 0.0),
137  theRefLineTime(0.0),
138  theRefLineTimeLine(0.0),
139  theLineSamplingPeriod(0.0),
140  thePolynomialLookAngleX(),
141  thePolynomialLookAngleY(),
142  theAttitudeSamples(),
143  theAttSampTimes(),
144  thePosEcfSamples(),
145  theVelEcfSamples(),
146  theEphSampTimes(),
147  theStarTrackerUsed(false),
148  theNumBands(0),
149  theAcquisitionDate(),
150  theFrameVertexPosImagePoints(),
151  theFrameVertexPosGroundPoints(),
152  theGeoPosImagePoints(),
153  theGeoPosGroundPoints()
154 {
155  if (traceDebug())
156  {
158  << "ossimFormosatDimapSupportData::ossimFormosatDimapSupportData: entering..."
159  << std::endl;
160  }
161 
162  loadXmlFile(dimapFile);
163 
164  // Finished successful parse:
165  if (traceDebug())
166  {
168  << "ossimFormosatDimapSupportData::ossimFormosatDimapSupportData: leaving..."
169  << std::endl;
170  }
171 }
172 
174 {
175 }
176 
178 {
179  return new ossimFormosatDimapSupportData(*this);
180 }
181 
183 {
185  theSensorID="";
187  theImageID = "";
188  theMetadataFile = "";
189  theProductionDate = "";
190  theSoftwareVersion = "";
191  theInstrument = "";
192  theInstrumentIndex = 0;
193  theSunAzimuth = 0.0;
194  theSunElevation = 0.0;
195  theSatAzimuth = 0.0;
196  theIncidenceAngle = 0.0;
197  theViewingAngle = 0.0;
200  theSceneOrientation = 0.0;
208  thePolynomialLookAngleX.clear();
209  thePolynomialLookAngleY.clear();
210  theAttitudeSamples.clear(); // x=pitch, y=roll, z=yaw
211  theAttSampTimes.clear();
212  thePosEcfSamples.clear();
213  theVelEcfSamples.clear();
214  theEphSampTimes.clear();
215  theStarTrackerUsed = false;
216  theNumBands = 0;
217  theAcquisitionDate = "";
218 
219  //---
220  // Corner points:
221  //---
224 
225 
226  //---
227  // Geoposition Points:
228  //---
229  theGeoPosImagePoints.clear();
230  theGeoPosGroundPoints.clear();
231 
232 }
233 
234 
235 
237 {
238  static const char MODULE[] = "ossimFormosatDimapSupportData::loadXmlFile";
239 
240  if(traceDebug())
241  {
243  << MODULE << " DEBUG:Entering ..."
244  << "\nFile: " << file << std::endl;
245  }
246  clearFields();
247  theMetadataFile = file;
248 
249  ossim_int64 fileSize = file.fileSize();
250  std::ifstream in(file.c_str(), std::ios::binary|std::ios::in);
251  std::vector<char> fullBuffer;
252  ossimString bufferedIo;
253  if(in.good()&&(fileSize > 0))
254  {
255  char buf[100];
256  fullBuffer.resize(fileSize);
257  in.read(buf, ossim::min((ossim_int64)100, fileSize));
258  if(!in.fail())
259  {
260  ossimString testString = ossimString(buf,
261  buf + in.gcount());
262  if(testString.contains("xml"))
263  {
264  in.seekg(0);
265  in.read(&fullBuffer.front(), (std::streamsize)fullBuffer.size());
266  if(!in.fail())
267  {
268  bufferedIo = ossimString(fullBuffer.begin(),
269  fullBuffer.begin()+in.gcount());
270  }
271  }
272  }
273  }
274  else
275  {
276  return false;
277  }
278  //---
279  // Instantiate the XML parser:
280  //---
281  ossimRefPtr<ossimXmlDocument> xmlDocument;
282 
283  if(bufferedIo.empty())
284  {
285  xmlDocument = new ossimXmlDocument(file);
286  }
287  else
288  {
289 
290  xmlDocument = new ossimXmlDocument;
291  std::istringstream inStringStream(bufferedIo);
292  if(!xmlDocument->read(inStringStream))
293  {
294  return false;
295  }
296  }
297 
298  if (xmlDocument->getErrorStatus())
299  {
300  if(traceDebug())
301  {
303  << MODULE << " DEBUG:"
304  << "ossimFormosatDimapSupportData::loadXmlFile:"
305  << "\nUnable to parse xml file" << std::endl;
306  }
307  setErrorStatus();
308  return false;
309  }
310 
311  //---
312  // Check that it is a FORMOSAT DIMAP file format
313  //---
314  vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
315  xml_nodes.clear();
316  ossimString xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/MISSION";
317  xmlDocument->findNodes(xpath, xml_nodes);
318  if (xml_nodes.size() == 0)
319  {
320  setErrorStatus();
321  if(traceDebug())
322  {
324  << "DEBUG:\n Not a FORMOSAT DIMAP file format."<< std::endl;
325  }
326  return false;
327  }
328 
329  if ( xml_nodes[0]->getText() != "FORMOSAT" && xml_nodes[0]->getText() != "Formosat" && xml_nodes[0]->getText() != "formosat" )
330  {
331  if(traceDebug())
332  {
334  << "DEBUG:\n Not a FORMOSAT DIMAP file format."<< std::endl;
335  }
336  return false;
337  }
338 
339  //---
340  // Get the version string. This must be performed first as it is used
341  // as a key for parsing different versions.
342  //---
343  if (initMetadataVersion(xmlDocument) == false)
344  {
345  if(traceDebug())
346  {
348  << MODULE << " DEBUG:"
349  << "ossimFormosatDimapSupportData::loadXmlFile:"
350  << "\nMetadata initialization failed. Returning false"
351  << std::endl;
352  }
353  return false;
354  }
355 
356  // Get the image id.
357  if (initImageId(xmlDocument) == false)
358  {
359  if(traceDebug())
360  {
362  << MODULE << " DEBUG:"
363  << "ossimFormosatDimapSupportData::loadXmlFile:"
364  << "\nImageId initialization failed. Returning false"
365  << std::endl;
366  }
367  return false;
368  }
369 
370  // Get data from "Scene_Source" section.
371  if (initSceneSource(xmlDocument) == false)
372  {
374  << MODULE << " DEBUG:"
375  << "ossimFormosatDimapSupportData::loadXmlFile:"
376  << "\nScene source initialization failed. Returning false"
377  << std::endl;
378 
379  return false;
380  }
381 
382  if (initFramePoints(xmlDocument) == false)
383  {
385  << MODULE << " DEBUG:"
386  << "ossimFormosatDimapSupportData::loadXmlFile:"
387  << "\nFrame point initialization failed. Returning false"
388  << std::endl;
389  return false;
390  }
391 
392  if (parsePart1(xmlDocument) == false)
393  {
395  << MODULE << " DEBUG:"
396  << "ossimFormosatDimapSupportData::loadXmlFile:"
397  << "\nPart 1 initialization failed. Returning false"
398  << std::endl;
399  return false;
400  }
401 
402  if (parsePart2(xmlDocument) == false)
403  {
405  << MODULE << " DEBUG:"
406  << "ossimFormosatDimapSupportData::loadXmlFile:"
407  << "\nPart 2 initialization failed. Returning false"
408  << std::endl;
409  return false;
410  }
411 
412  if (parsePart3(xmlDocument) == false)
413  {
415  << MODULE << " DEBUG:"
416  << "ossimFormosatDimapSupportData::loadXmlFile:"
417  << "\nPart 3 initialization failed. Returning false"
418  << std::endl;
419  return false;
420  }
421 
422  if (parsePart4(xmlDocument) == false)
423  {
425  << MODULE << " DEBUG:"
426  << "ossimFormosatDimapSupportData::loadXmlFile:"
427  << "\nPart 4 initialization failed. Returning false"
428  << std::endl;
429  return false;
430  }
431 
432  if (traceDebug())
433  {
435 
437  << MODULE << " DEBUG: leaving..."
438  << std::endl;
439  }
440 
441  return true;
442 }
443 
445  ossimEcefPoint& pe) const
446 {
447  pe.makeNan();
448  pe = ossimEcefPoint(thePosEcfSamples[sample].x,
449  thePosEcfSamples[sample].y,
450  thePosEcfSamples[sample].z);
451 
452 }
453 
455  ossimEcefPoint& pe) const
456 {
457  ossimDpt3d tempPt;
458 
459  if((thePosEcfSamples.size() < 8)||
460  (theEphSampTimes.size() < 8))
461  {
463  }
464  else
465  {
467  }
468 
469  pe = ossimEcefPoint(tempPt.x,
470  tempPt.y,
471  tempPt.z);
472 }
473 
475 {
476  ve.makeNan();
477  ve = ossimEcefPoint(theVelEcfSamples[sample].x,
478  theVelEcfSamples[sample].y,
479  theVelEcfSamples[sample].z);
480 }
481 
483  ossimEcefPoint& ve) const
484 {
485  ossimDpt3d tempPt;
486 
487  if((theVelEcfSamples.size() < 8) ||
488  (theEphSampTimes.size() < 8))
489  {
491  }
492  else
493  {
495  }
496 
497  ve = ossimEcefPoint(tempPt.x,
498  tempPt.y,
499  tempPt.z);
500 }
501 
503  ossim_float64& et) const
504 {
505  et = ossim::nan();
506  if(theEphSampTimes.size() < theImageSize.samp)
507  {
508  if(theImageSize.samp > 0)
509  {
510  double t = 0.0;
511  double tempIdx = 0.0;
512  double tempIdxFraction = 0.0;
513  t = (double)sample/(double)(theImageSize.samp-1);
514  tempIdx = (theEphSampTimes.size()-1)*t;
515  tempIdxFraction = tempIdx - (ossim_int32)tempIdx;
516  ossim_uint32 idxStart = (ossim_uint32)tempIdx;
517  ossim_uint32 idxEnd = (ossim_uint32)ceil(tempIdx);
518  if(idxEnd >= theEphSampTimes.size())
519  {
520  idxEnd = (ossim_uint32)theEphSampTimes.size()-1;
521  }
522  if(idxStart > idxEnd)
523  {
524  idxStart = idxEnd;
525  }
526  et = (theEphSampTimes[idxStart] +tempIdxFraction*(theEphSampTimes[idxEnd] -
527  theEphSampTimes[idxStart]));
528  }
529  }
530  else if(theEphSampTimes.size() == theImageSize.samp)
531  {
532  et = theEphSampTimes[sample];
533  }
534 }
535 
537  ossimDpt3d& at) const
538 {
539  if (sample >= theAttitudeSamples.size())
540  {
541  at.makeNan();
542  return;
543  }
544 
545  at = theAttitudeSamples[sample];
546 }
547 
549  ossimDpt3d& at) const
550 {
551  if (theAttSampTimes.empty())
552  {
553  at.makeNan();
554  return;
555  }
556 
557  if ((time < theAttSampTimes.front()) ||
558  (time >= theAttSampTimes.back() ))
559  {
560  at.makeNan();
561  return;
562  }
563 
564  //***
565  // Search the attitude sampling time array for surrounding samples:
566  //***
567  int i=0;
568  while ((i < (int)theAttSampTimes.size()) &&
569  (theAttSampTimes[i] < time)) ++i;
570  --i;
571 
572  //***
573  // Linearly interpolate attitudes angles:
574  //***
575  ossim_float64 dt1 = time - theAttSampTimes[i];
576  ossim_float64 dt0 = theAttSampTimes[i+1] - time;
578 
579  at = (theAttitudeSamples[i+1]*dt1 + theAttitudeSamples[i]*dt0)/dt;
580 }
581 
583 {
584  if (sample >= theAttSampTimes.size())
585  {
586  at = ossim::nan();
587  return;
588  }
589 
590  at = theAttSampTimes[sample];
591 }
592 
594  ossim_float64& pa) const
595 {
597 }
598 
600  ossim_float64& pa) const
601 {
602  ossim_uint32 s = static_cast<ossim_uint32>(sample);
604 }
605 
607  ossim_float64& pa) const
608 {
610 }
611 
613  ossim_float64& pa) const
614 {
615  ossim_uint32 s = static_cast<ossim_uint32>(sample);
617 }
618 
620  const ossim_float64& p,
621  const std::vector<ossim_float64>& angles,
622  ossim_float64& la) const
623 {
624  la = ossim::nan();
625 
626  if (angles.size() != 4 )
627  {
628  setErrorStatus();
629  return;
630  }
631 
632  la = angles[0] + angles[1] * p + angles[2] * p * p + angles[3] * p * p * p ;
633 }
634 
636  const ossim_float64& time,
637  const std::vector<ossimDpt3d>& V,
638  const std::vector<ossim_float64>& T,
639  ossimDpt3d& li) const
640 {
641  ossim_uint32 samp0 = 0;
642  while ((samp0 < T.size()) && (T[samp0] < time)) ++samp0;
643 
644  if(samp0==0)
645  {
646  li = V[0];
647  }
648  else if(samp0 == T.size())
649  {
650  li = V[1];
651  }
652  else
653  {
654  double t = (T[samp0-1]-time)/(T[samp0-1] - T[samp0]);
655 
656  li = V[samp0-1] + (V[samp0]-V[samp0-1])*t;
657  }
658 }
659 
661  const ossim_float64& time,
662  const std::vector<ossimDpt3d>& V,
663  const std::vector<ossim_float64>& T,
664  ossimDpt3d& li) const
665 
666 {
667 // std::cout << "V size = " << V.size() << std::endl
668 // << "T size = " << T.size() << std::endl;
669 
670  ossim_uint32 filter_size = 8;
671  //
672  // Verify that t is within allowable range:
673  //
674  ossim_uint32 lagrange_half_filter = 4;
675 
676  if(T.size() <= filter_size)
677  {
678  filter_size = (ossim_uint32)T.size()/2;
679  lagrange_half_filter = filter_size/2;
680  }
681  if ((time < T[lagrange_half_filter]) ||
682  (time >= T[T.size()-lagrange_half_filter] ))
683  {
684  setErrorStatus();
685  li.makeNan();
686 
687  return;
688  }
689 
690  //***
691  // Search the sampling time array for surrounding samples:
692  //***
693  ossim_uint32 samp0 = lagrange_half_filter;
694  while ((samp0 < T.size()) && (T[samp0] < time)) ++samp0;
695 
696  //***
697  // Do not use sample if it falls in neighborhood of desired time:
698  //***
699  ossim_uint32 bump = 0;
700  if (fabs(T[samp0] - time) < theLineSamplingPeriod/2.0)
701  bump = 1;
702 
703  samp0 -= lagrange_half_filter; // adjust to first sample in window
704 
705  //***
706  // Outer summation loop:
707  //***
708  ossimDpt3d S (0, 0, 0);
709  for (ossim_uint32 j=samp0; j<(samp0+filter_size+bump); ++j)
710  {
711  ossim_float64 numerator = 1.0;
712  ossim_float64 denominator = 1.0;
713 
714  //***
715  // Skip this sample if too close to desired time:
716  //***
717  if (bump && (j == (samp0+lagrange_half_filter) ))
718  ++j;
719 
720  //***
721  // Inner loop for product series:
722  //***
723  for (ossim_uint32 i=samp0; i<(samp0+filter_size+bump); ++i)
724  {
725  //***
726  // Skip this sample if too close to desired time:
727  //***
728  if (bump && (i == (samp0+lagrange_half_filter) ))
729  ++i;
730 
731  if (i != j)
732  {
733  numerator *= time - T[i];
734  denominator *= T[j] - T[i];
735  }
736  }
737 
738  ossimDpt3d p = V[j];
739  p = p * numerator;
740  p = p / denominator;
741  S += p;
742  }
743 
744  li = S;
745 }
746 
748 {
749  double ti;
750  convertTimeStamp(time_stamp, ti);
751  return ti;
752 }
753 
755  ossim_float64& ti) const
756 {
757  int year, month, day, hour, minute;
758  double second;
759 
760  //***
761  // Time stamps are in the format: "yyyy-mm-ddThh:mm:ss.ssssss"
762  //***
763  int converted = sscanf(time_stamp,
764  "%4d-%2d-%2d %2d:%2d:%9lf",
765  &year, &month, &day,
766  &hour, &minute, &second);
767 
768  if (converted != 6)
769  {
770  setErrorStatus();
771  ti = ossim::nan();
772  }
773  else
774  {
775  ti = (((((year-2002.0)*12.0 + month - 1.0)*365.0 + day - 1.0)*24.0
776  + hour)*60.0 + minute)*60.0 + second;
777  }
778 }
779 
781  ossimDpt& ip,
782  ossimGpt& gp) const
783 {
784  if (point < theGeoPosImagePoints.size())
785  {
786  ip = theGeoPosImagePoints [point];
787  gp = theGeoPosGroundPoints[point];
788  }
789 }
790 
792 {
793  ossimString corr_att = "NO";
794  if (theStarTrackerUsed)
795  corr_att = "YES";
796 
797  os << "\n----------------- Info on Formosat Image -------------------"
798  << "\n "
799  << "\n Job Number (ID): " << theImageID
800  << "\n Acquisition Date: " << theAcquisitionDate
801  << "\n Instrument: " << theInstrument
802  << "\n Instrument Index: " << theInstrumentIndex
803  << "\n Production Date: " << theProductionDate
804  << "\n Production Softwrae version: " << theSoftwareVersion
805  << "\n Number of Bands: " << theNumBands
806  << "\n Geo Center Point: " << theRefGroundPoint
807  << "\n Image Size: " << theImageSize
808  << "\n Incidence Angle: " << theIncidenceAngle
809  << "\n Viewing Angle: " << theViewingAngle
810  << "\n Viewing Angle Along Track: " << theViewingAngleAlongTrack
811  << "\n Viewing Angle Across Track: " << theViewingAngleAcrossTrack
812  << "\n Scene Orientation: " << theSceneOrientation
813  << "\n Corrected Attitude: " << corr_att
814  << "\n Sun Azimuth: " << theSunAzimuth
815  << "\n Sun Elevation: " << theSunElevation
816  << "\n Sat Azimuth: " << theSatAzimuth
817  << "\n Sub image offset: " << theSubImageOffset
818  << "\n PolynomialLookAngleX size: " << thePolynomialLookAngleX.size()
819  << "\n thePosEcfSamples size: " << thePosEcfSamples.size()
820  << "\n theFrameVertexPosImagePoints size : " << theFrameVertexPosImagePoints.size()
821  << "\n"
822  << "\n---------------------------------------------------------"
823  << "\n " << std::endl;
824 }
825 
827 {
828  return theSensorID;
829 }
830 
832 {
834  {
835  return ossimString("1.1");
836  }
838  {
839  return ossimString("1.0");
840  }
841  return ossimString("unknown");
842 }
843 
845 {
846  return theAcquisitionDate;
847 }
848 
850 {
851  return theProductionDate;
852 }
853 
855 {
856  return theSoftwareVersion;
857 }
858 
860 {
861  return theImageID;
862 }
863 
865 {
866  return theMetadataFile;
867 }
868 
870 {
871  return theInstrument;
872 }
873 
875 {
876  return theInstrumentIndex;
877 }
878 
880 {
881  az = theSunAzimuth;
882 }
883 
885 {
886  el = theSunElevation;
887 }
888 
890 {
891  az = theSatAzimuth;
892 }
893 
895 {
896  sz = theImageSize;
897 }
898 
900 {
902 }
903 
905 {
906  return theStarTrackerUsed;
907 }
908 
910 {
911  return theNumBands;
912 }
913 
914 
916 {
917  ia = theIncidenceAngle;
918 }
919 
921 {
922  va = theViewingAngle;
923 }
924 
926 {
928 }
929 
931 {
933 }
934 
936 {
937  so = theSceneOrientation;
938 }
939 
941 {
942  gp = theRefGroundPoint;
943 }
944 
946 {
947  rp = theRefImagePoint;
948 }
949 
951 {
952  rt = theRefLineTime;
953 }
954 
956 {
957  rtl = theRefLineTimeLine;
958 }
959 
961 {
962  return (ossim_uint32)theEphSampTimes.size();
963 }
964 
966 {
967  return (ossim_uint32)theAttSampTimes.size();
968 }
969 
971 {
972  return (ossim_uint32)theGeoPosImagePoints.size();
973 }
974 
976 {
977  rect = ossimDrect(0.0, 0.0, theImageSize.x-1.0, theImageSize.y-1.0);
978 }
979 
981 {
982  offset = theSubImageOffset;
983 }
984 
986  const char* prefix)const
987 {
988  kwl.add(prefix,
990  "ossimFormosatDimapSupportData",
991  true);
992 
993  kwl.add(prefix,
994  "metadata_file",
996  true);
997 
998  kwl.add(prefix,
1000  theSunAzimuth,
1001  true);
1002 
1003  kwl.add(prefix,
1006  true);
1007 
1008  kwl.add(prefix,
1009  "sat_azimuth_angle",
1010  theSatAzimuth,
1011  true);
1012 
1013  //---
1014  // Note: since this is a new keyword, use the point.toString as there is
1015  // no backwards compatibility issues.
1016  //---
1017 
1018  kwl.add(prefix,
1019  "image_size",
1022  true);
1023 
1024  kwl.add(prefix,
1025  "reference_ground_point",
1030  true);
1031 
1032  kwl.add(prefix,
1033  "reference_image_point",
1036  true);
1037 
1038  kwl.add(prefix,
1039  "sub_image_offset",
1042  true);
1043 
1044  kwl.add(prefix,
1045  "reference_line_time",
1047  true);
1048 
1049  kwl.add(prefix,
1050  "reference_line_time_line",
1052  true);
1053 
1054  kwl.add(prefix,
1055  "line_sampling_period",
1057  true);
1058 
1059  ossimString tempString;
1060  ossim_uint32 idx = 0;
1061 
1062  tempString = "";
1063  for(idx = 0; idx < thePolynomialLookAngleX.size(); ++idx)
1064  {
1065  tempString += (ossimString::toString(thePolynomialLookAngleX[idx]) + " ");
1066  }
1067 
1068  kwl.add(prefix,
1069  "pixel_lookat_angle_x",
1070  tempString,
1071  true);
1072 
1073  kwl.add(prefix,
1074  "number_of_pixel_lookat_angle_x",
1075  static_cast<ossim_uint32>(thePolynomialLookAngleX.size()),
1076  true);
1077 
1078  tempString = "";
1079  for(idx = 0; idx < thePolynomialLookAngleY.size(); ++idx)
1080  {
1081  tempString += (ossimString::toString(thePolynomialLookAngleY[idx]) + " ");
1082  }
1083  kwl.add(prefix,
1084  "pixel_lookat_angle_y",
1085  tempString,
1086  true);
1087  kwl.add(prefix,
1088  "number_of_pixel_lookat_angle_y",
1089  static_cast<ossim_uint32>(thePolynomialLookAngleY.size()),
1090  true);
1091 
1092 
1093  tempString = "";
1094  for(idx = 0; idx < theAttitudeSamples.size(); ++idx)
1095  {
1096  tempString += (ossimString::toString(theAttitudeSamples[idx].x) + " " +
1099  }
1100  kwl.add(prefix,
1101  "attitude_samples",
1102  tempString,
1103  true);
1104  kwl.add(prefix,
1105  "number_of_attitude_samples",
1106  static_cast<ossim_uint32>(theAttitudeSamples.size()),
1107  true);
1108 
1109  tempString = "";
1110  for(idx = 0; idx < theAttSampTimes.size(); ++idx)
1111  {
1112  tempString += (ossimString::toString(theAttSampTimes[idx]) + " ");
1113  }
1114  kwl.add(prefix,
1115  "attitude_sample_times",
1116  tempString,
1117  true);
1118  kwl.add(prefix,
1119  "number_of_attitude_sample_times",
1120  static_cast<ossim_uint32>(theAttSampTimes.size()),
1121  true);
1122 
1123  tempString = "";
1124  for(idx = 0; idx < thePosEcfSamples.size(); ++idx)
1125  {
1126  tempString += (ossimString::toString(thePosEcfSamples[idx].x) + " " +
1128  ossimString::toString(thePosEcfSamples[idx].z) + " ");
1129  }
1130  kwl.add(prefix,
1131  "position_ecf_samples",
1132  tempString,
1133  true);
1134  kwl.add(prefix,
1135  "number_of_position_ecf_samples",
1136  static_cast<ossim_uint32>(thePosEcfSamples.size()),
1137  true);
1138 
1139  tempString = "";
1140  for(idx = 0; idx < theVelEcfSamples.size(); ++idx)
1141  {
1142  tempString += (ossimString::toString(theVelEcfSamples[idx].x) + " " +
1144  ossimString::toString(theVelEcfSamples[idx].z) + " ");
1145  }
1146  kwl.add(prefix,
1147  "velocity_ecf_samples",
1148  tempString,
1149  true);
1150  kwl.add(prefix,
1151  "number_of_velocity_ecf_samples",
1152  static_cast<ossim_uint32>(thePosEcfSamples.size()),
1153  true);
1154 
1155  tempString = "";
1156  for(idx = 0; idx < theEphSampTimes.size(); ++idx)
1157  {
1158  tempString += (ossimString::toString(theEphSampTimes[idx]) + " ");
1159  }
1160 
1161  kwl.add(prefix,
1162  "ephemeris_sample_times",
1163  tempString,
1164  true);
1165  kwl.add(prefix,
1166  "number_of_ephemeris_sample_times",
1167  static_cast<ossim_uint32>(theEphSampTimes.size()),
1168  true);
1169 
1170  kwl.add(prefix,
1171  "star_tracker_used_flag",
1172  static_cast<ossim_uint32>(theStarTrackerUsed),
1173  true);
1174 
1175  kwl.add(prefix,
1177  theNumBands,
1178  true);
1179 
1180  kwl.add(prefix,
1181  "image_id",
1182  theImageID,
1183  true);
1184 
1185  kwl.add(prefix,
1186  "instrument",
1187  theInstrument,
1188  true);
1189 
1190  kwl.add(prefix,
1191  "instrument_index",
1193  true);
1194 
1195  kwl.add(prefix,
1198  true);
1199 
1200  kwl.add(prefix,
1201  "production_date",
1203  true);
1204 
1205  kwl.add(prefix,
1206  "software_version",
1208  true);
1209 
1210  kwl.add(prefix,
1211  "incident_angle",
1213  true);
1214 
1215  kwl.add(prefix,
1216  "viewing_angle",
1218  true);
1219 
1220  kwl.add(prefix,
1221  "viewing_angle_along_track",
1223  true);
1224 
1225  kwl.add(prefix,
1226  "viewing_angle_across_track",
1228  true);
1229 
1230  kwl.add(prefix,
1231  "scene_orientation",
1233  true);
1234 
1235  kwl.add(prefix,
1236  "sensorID",
1237  theSensorID,
1238  true);
1239 
1240 
1241  tempString = "";
1242  for(idx = 0; idx < thePhysicalBias.size(); ++idx)
1243  {
1244  tempString += (ossimString::toString(thePhysicalBias[idx]) + " ");
1245  }
1246  kwl.add(prefix,
1247  "physical_bias",
1248  tempString,
1249  true);
1250 
1251  tempString = "";
1252  for(idx = 0; idx < thePhysicalGain.size(); ++idx)
1253  {
1254  tempString += (ossimString::toString(thePhysicalGain[idx]) + " ");
1255  }
1256  kwl.add(prefix,
1257  "physical_gain",
1258  tempString,
1259  true);
1260 
1261  tempString = "";
1262  for(idx = 0; idx < theSolarIrradiance.size(); ++idx)
1263  {
1264  tempString += (ossimString::toString(theSolarIrradiance[idx]) + " ");
1265  }
1266 
1267  kwl.add(prefix,
1268  "solar_irradiance",
1269  tempString,
1270  true);
1271 
1272  return true;
1273 }
1274 
1276  const char* prefix)
1277 {
1278  clearFields();
1279 
1280  ossimString type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
1281 
1282  if(type != "ossimFormosatDimapSupportData")
1283  {
1284  return false;
1285  }
1286  theMetadataFile = kwl.find(prefix, "metadata_file");
1287 
1290  theSatAzimuth = ossimString(kwl.find(prefix, "sat_azimuth_angle")).toDouble();
1291 
1292  theImageSize = createDpt(kwl.find(prefix, "image_size"));
1293  theRefGroundPoint = createGround(kwl.find(prefix, "reference_ground_point"));
1294  theRefImagePoint = createDpt(kwl.find(prefix, "reference_image_point"));
1295  theSubImageOffset = createDpt(kwl.find(prefix, "sub_image_offset"));
1296 
1297  theRefLineTime = ossimString(kwl.find(prefix, "reference_line_time")).toDouble();
1298 
1299  const char* lookup = kwl.find(prefix, "reference_line_time_line");
1300  if (lookup)
1301  {
1303  }
1304 
1305  theLineSamplingPeriod = ossimString(kwl.find(prefix, "line_sampling_period")).toDouble();
1306 
1307 
1308  ossim_uint32 idx = 0;
1309  ossim_uint32 total = ossimString(kwl.find(prefix,"number_of_pixel_lookat_angle_x")).toUInt32();
1310  ossimString tempString;
1311 
1312  thePolynomialLookAngleX.resize(total);
1313  tempString = kwl.find(prefix,"pixel_lookat_angle_x");
1314  if(tempString != "")
1315  {
1316  std::istringstream in(tempString);
1317  ossimString tempValue;
1318  for(idx = 0; idx < thePolynomialLookAngleX.size();++idx)
1319  {
1320  in >> tempValue;
1321  thePolynomialLookAngleX[idx] = tempValue.toDouble();
1322  }
1323  }
1324 
1325  total = ossimString(kwl.find(prefix,"number_of_pixel_lookat_angle_y")).toUInt32();
1326  thePolynomialLookAngleY.resize(total);
1327  tempString = kwl.find(prefix,"pixel_lookat_angle_y");
1328  if(tempString != "")
1329  {
1330  std::istringstream in(tempString);
1331  ossimString tempValue;
1332  for(idx = 0; idx < thePolynomialLookAngleY.size();++idx)
1333  {
1334  in >> tempValue;
1335  thePolynomialLookAngleY[idx] = tempValue.toDouble();
1336  }
1337  }
1338 
1339 
1340  total = ossimString(kwl.find(prefix,"number_of_attitude_samples")).toUInt32();
1341  theAttitudeSamples.resize(total);
1342  tempString = kwl.find(prefix,"attitude_samples");
1343  if(tempString != "")
1344  {
1345  std::istringstream in(tempString);
1346  ossimString x, y, z;
1347  for(idx = 0; idx < theAttitudeSamples.size();++idx)
1348  {
1349  in >> x >> y >> z;
1350  theAttitudeSamples[idx] =ossimDpt3d(x.toDouble(), y.toDouble(), z.toDouble());
1351  }
1352  }
1353 
1354  total = ossimString(kwl.find(prefix,"number_of_attitude_sample_times")).toUInt32();
1355  theAttSampTimes.resize(total);
1356  tempString = kwl.find(prefix,"attitude_sample_times");
1357  if(tempString != "")
1358  {
1359  std::istringstream in(tempString);
1360  ossimString tempValue;
1361  for(idx = 0; idx < theAttSampTimes.size();++idx)
1362  {
1363  in >> tempValue;
1364  theAttSampTimes[idx] = tempValue.toDouble();
1365  }
1366  }
1367 
1368  total = ossimString(kwl.find(prefix,"number_of_position_ecf_samples")).toUInt32();
1369  thePosEcfSamples.resize(total);
1370  tempString = kwl.find(prefix,"position_ecf_samples");
1371  if(tempString != "")
1372  {
1373  std::istringstream in(tempString);
1374  ossimString x, y, z;
1375  for(idx = 0; idx < thePosEcfSamples.size();++idx)
1376  {
1377  in >> x >> y >> z;
1378  thePosEcfSamples[idx] = ossimDpt3d(x.toDouble(), y.toDouble(), z.toDouble());
1379  }
1380  }
1381 
1382  total = ossimString(kwl.find(prefix,"number_of_velocity_ecf_samples")).toUInt32();
1383  theVelEcfSamples.resize(total);
1384  tempString = kwl.find(prefix,"velocity_ecf_samples");
1385  if(tempString != "")
1386  {
1387  std::istringstream in(tempString);
1388  ossimString x, y, z;
1389  for(idx = 0; idx < theVelEcfSamples.size();++idx)
1390  {
1391  in >> x >> y >> z;
1392  theVelEcfSamples[idx] = ossimDpt3d(x.toDouble(), y.toDouble(), z.toDouble());
1393  }
1394  }
1395 
1396  total = ossimString(kwl.find(prefix,"number_of_ephemeris_sample_times")).toUInt32();
1397  theEphSampTimes.resize(total);
1398  tempString = kwl.find(prefix,"ephemeris_sample_times");
1399  if(tempString != "")
1400  {
1401  std::istringstream in(tempString);
1402  ossimString tempValue;
1403  for(idx = 0; idx < theEphSampTimes.size();++idx)
1404  {
1405  in >> tempValue;
1406  theEphSampTimes[idx] = tempValue.toDouble();
1407  }
1408  }
1409 
1410  tempString = "";
1411  for(idx = 0; idx < theEphSampTimes.size(); ++idx)
1412  {
1413  tempString += (ossimString::toString(theEphSampTimes[idx]) + " ");
1414  }
1415 
1416  theStarTrackerUsed = ossimString(kwl.find(prefix, "star_tracker_used_flag")).toBool();
1419  theProductionDate = kwl.find(prefix, "production_date");
1420  theSoftwareVersion = kwl.find(prefix, "software_version");
1421  theImageID = kwl.find(prefix, "image_id");
1422  theInstrument = kwl.find(prefix, "instrument");
1423  theInstrumentIndex = ossimString(kwl.find(prefix, "instrument_index")).toUInt32();
1424 
1425  theIncidenceAngle = ossimString(kwl.find(prefix, "incident_angle")).toDouble();
1426  theViewingAngle = ossimString(kwl.find(prefix, "viewing_angle")).toDouble();
1427  theViewingAngleAlongTrack = ossimString(kwl.find(prefix, "viewing_angle_along_track")).toDouble();
1428  theViewingAngleAcrossTrack = ossimString(kwl.find(prefix, "viewing_angle_across_track")).toDouble();
1429  theSceneOrientation = ossimString(kwl.find(prefix, "scene_orientation")).toDouble();
1430 
1431  /* TODO add reading FrameVertex point */
1432 
1433  theSensorID = ossimString(kwl.find(prefix, "sensorID"));
1434 
1435  thePhysicalBias.resize(theNumBands);
1436  tempString = kwl.find(prefix,"physical_bias");
1437  if(tempString != "")
1438  {
1439  std::istringstream in(tempString);
1440  ossimString tempValue;
1441  for(idx = 0; idx < thePhysicalBias.size();++idx)
1442  {
1443  in >> tempValue;
1444  thePhysicalBias[idx] = tempValue.toDouble();
1445  }
1446  }
1447 
1448  thePhysicalGain.resize(theNumBands);
1449  tempString = kwl.find(prefix,"physical_gain");
1450  if(tempString != "")
1451  {
1452  std::istringstream in(tempString);
1453  ossimString tempValue;
1454  for(idx = 0; idx < thePhysicalGain.size();++idx)
1455  {
1456  in >> tempValue;
1457  thePhysicalGain[idx] = tempValue.toDouble();
1458  }
1459  }
1460 
1462  tempString = kwl.find(prefix,"solar_irradiance");
1463  if(tempString != "")
1464  {
1465  std::istringstream in(tempString);
1466  ossimString tempValue;
1467  for(idx = 0; idx < theSolarIrradiance.size();++idx)
1468  {
1469  in >> tempValue;
1470  theSolarIrradiance[idx] = tempValue.toDouble();
1471  }
1472  }
1473 
1474  return true;
1475 }
1476 
1478 {
1479  std::istringstream in(s);
1480  ossimString lat, lon, height;
1481  ossimString code;
1482 
1483  in >> lat >> lon >> height >> code;
1484 
1485  return ossimGpt(lat.toDouble(),
1486  lon.toDouble(),
1487  height.toDouble(),
1489 
1490 }
1491 
1493 {
1494  std::istringstream in(s);
1495  ossimString x, y;
1496  ossimString code;
1497 
1498  in >> x >> y;
1499 
1500  return ossimDpt(x.toDouble(), y.toDouble());
1501 
1502 }
1503 
1505  ossimRefPtr<ossimXmlDocument> xmlDocument)
1506 {
1507  static const char MODULE[] = "ossimFormosatDimapSupportData::parsePart1";
1508 
1509  ossimString xpath;
1510  vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
1511 
1512  //---
1513  // Fetch the ImageSize:
1514  //---
1515  xml_nodes.clear();
1516  xpath = "/Dimap_Document/Raster_Dimensions/NCOLS";
1517  xmlDocument->findNodes(xpath, xml_nodes);
1518  if (xml_nodes.size() == 0)
1519  {
1520  setErrorStatus();
1521  if(traceDebug())
1522  {
1524  << MODULE << " DEBUG:"
1525  << "\nCould not find: " << xpath
1526  << std::endl;
1527  }
1528  return false;
1529  }
1530  theImageSize.samp = xml_nodes[0]->getText().toDouble();
1531 
1532  xml_nodes.clear();
1533  xpath = "/Dimap_Document/Raster_Dimensions/NROWS";
1534  xmlDocument->findNodes(xpath, xml_nodes);
1535  if (xml_nodes.size() == 0)
1536  {
1537  setErrorStatus();
1538  if(traceDebug())
1539  {
1541  << MODULE << " DEBUG:"
1542  << "\nCould not find: " << xpath
1543  << std::endl;
1544  }
1545  return false;
1546  }
1547  theImageSize.line = xml_nodes[0]->getText().toDouble();
1548 
1549 
1550  //---
1551  // We will make the RefImagePoint the zero base center of the image. This
1552  // is used by the ossimSensorModel::worldToLineSample iterative loop as
1553  // the starting point. Since the ossimSensorModel does not know of the
1554  // sub image we make it zero base.
1555  //---
1558 
1559  xml_nodes.clear();
1560  xpath = "/Dimap_Document/Data_Strip/Time_Stamp/REFERENCE_LINE";
1561  xmlDocument->findNodes(xpath, xml_nodes);
1562  if (xml_nodes.size() == 0)
1563  {
1564  setErrorStatus();
1565  if(traceDebug())
1566  {
1568  << MODULE << " DEBUG:"
1569  << "\nCould not find: " << xpath
1570  << std::endl;
1571  }
1572  return false;
1573  }
1574 
1575  // Relative to full image frame.
1576  theRefLineTimeLine = xml_nodes[0]->getText().toDouble() - 1.0;
1577 
1578  // See if there's a sub image offset...
1579  xml_nodes.clear();
1580  xpath = "/Dimap_Document/Data_Processing/Regions_Of_Interest/Region_Of_Interest/COL_MIN";
1581  xmlDocument->findNodes(xpath, xml_nodes);
1582  if (xml_nodes.size() == 0)
1583  {
1584  theSubImageOffset.samp = 0.0;
1585  }
1586  else
1587  {
1588  theSubImageOffset.samp = xml_nodes[0]->getText().toDouble() - 1.0;
1589  }
1590 
1591  xml_nodes.clear();
1592  xpath = "/Dimap_Document/Data_Processing/Regions_Of_Interest/Region_Of_Interest/ROW_MIN";
1593  xmlDocument->findNodes(xpath, xml_nodes);
1594  if (xml_nodes.size() == 0)
1595  {
1596  theSubImageOffset.line = 0.0;
1597  }
1598  else
1599  {
1600  theSubImageOffset.line = xml_nodes[0]->getText().toDouble() - 1.0;
1601  }
1602 
1603  //---
1604  // Fetch the RefLineTime:
1605  //---
1606  xml_nodes.clear();
1607  xpath = "/Dimap_Document/Data_Strip/Time_Stamp/REFERENCE_TIME";
1608  xmlDocument->findNodes(xpath, xml_nodes);
1609  if (xml_nodes.size() == 0)
1610  {
1611  setErrorStatus();
1612  if(traceDebug())
1613  {
1615  << MODULE << " DEBUG:"
1616  << "\nCould not find: " << xpath
1617  << std::endl;
1618  }
1619  return false;
1620  }
1621  theAcquisitionDate = xml_nodes[0]->getText();
1623 
1624  //---
1625  // Fetch the ProductionDate:
1626  //---
1627  xml_nodes.clear();
1628  xpath = "/Dimap_Document/Production/DATASET_PRODUCTION_DATE";
1629  xmlDocument->findNodes(xpath, xml_nodes);
1630  if (xml_nodes.size() == 0)
1631  {
1632  setErrorStatus();
1633  if(traceDebug())
1634  {
1636  << MODULE << " DEBUG:"
1637  << "\nCould not find: " << xpath
1638  << std::endl;
1639  }
1640  return false;
1641  }
1642  theProductionDate = xml_nodes[0]->getText();
1643 
1644  //---
1645  // Fetch the SoftwareVersion:
1646  //---
1647  xml_nodes.clear();
1648  xpath = "/Dimap_Document/Production/Production_Facility/SOFTWARE_VERSION";
1649  xmlDocument->findNodes(xpath, xml_nodes);
1650  if (xml_nodes.size() == 0)
1651  {
1652  setErrorStatus();
1653  if(traceDebug())
1654  {
1656  << MODULE << " DEBUG:"
1657  << "\nCould not find: " << xpath
1658  << std::endl;
1659  }
1660  return false;
1661  }
1662  theSoftwareVersion = xml_nodes[0]->getText();
1663  //---
1664  // Fetch the Instrument:
1665  //---
1666  xml_nodes.clear();
1667  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/INSTRUMENT";
1668  xmlDocument->findNodes(xpath, xml_nodes);
1669  if (xml_nodes.size() == 0)
1670  {
1671  setErrorStatus();
1672  if(traceDebug())
1673  {
1675  << MODULE << " DEBUG:"
1676  << "\nCould not find: " << xpath
1677  << std::endl;
1678  }
1679  return false;
1680  }
1681  theInstrument = xml_nodes[0]->getText();
1682 
1683  //---
1684  // Fetch the Instrument Index:
1685  //---
1686  xml_nodes.clear();
1687  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/INSTRUMENT_INDEX";
1688  xmlDocument->findNodes(xpath, xml_nodes);
1689  if (xml_nodes.size() == 0)
1690  {
1691  setErrorStatus();
1692  if(traceDebug())
1693  {
1695  << MODULE << " DEBUG:"
1696  << "\nCould not find: " << xpath
1697  << std::endl;
1698  }
1699  return false;
1700  }
1701  theInstrumentIndex = xml_nodes[0]->getText().toUInt32();
1702 
1703  return true;
1704 }
1705 
1707  ossimRefPtr<ossimXmlDocument> xmlDocument)
1708 {
1709  static const char MODULE[] = "ossimFormosatDimapSupportData::parsePart2";
1710 
1711  ossimString xpath;
1712  std::vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
1713  std::vector<ossimRefPtr<ossimXmlNode> > sub_nodes;
1714  std::vector<ossimRefPtr<ossimXmlNode> >::iterator node;
1715  ossim_int32 band_index;
1716 
1717  //---
1718  // Fetch the LineSamplingPeriod:
1719  //---
1720  xml_nodes.clear();
1721  xpath = "/Dimap_Document/Data_Strip/Time_Stamp/LINE_PERIOD";
1722 
1723  xmlDocument->findNodes(xpath, xml_nodes);
1724  if (xml_nodes.size() == 0)
1725  {
1726  setErrorStatus();
1727  if(traceDebug())
1728  {
1730  << MODULE << " DEBUG:"
1731  << "\nCould not find: " << xpath
1732  << std::endl;
1733  }
1734  return false;
1735  }
1736  theLineSamplingPeriod = xml_nodes[0]->getText().toDouble();
1737 
1738 
1739  //---
1740  // Fetch number of bands
1741  //---
1742  xml_nodes.clear();
1743  xpath = "/Dimap_Document/Raster_Dimensions/NBANDS";
1744  xmlDocument->findNodes(xpath, xml_nodes);
1745  if (xml_nodes.size() == 0)
1746  {
1747  setErrorStatus();
1748  if(traceDebug())
1749  {
1751  << MODULE << " DEBUG:"
1752  << "\nCould not find: " << xpath
1753  << std::endl;
1754  }
1755  return false;
1756  }
1757  theNumBands = atoi(xml_nodes[0]->getText());
1758 
1759 
1760  if (theNumBands == 1)
1761  {
1762  band_index = 0;
1763  }
1764  else if (theNumBands == 4)
1765  {
1766  band_index = 1; // using green band for Polynomial Look angles
1767  }
1768  else
1769  {
1770  setErrorStatus();
1771  if(traceDebug())
1772  {
1774  << MODULE << " DEBUG:"
1775  << "\nBand ERROR!"
1776  << std::endl;
1777  }
1778  return false;
1779  }
1780 
1781  //---
1782  // Fetch the PolynomialLookAngleX and PolynomialLookAngleY arrays.
1783  //---
1784 
1785  thePolynomialLookAngleX.clear();
1786  thePolynomialLookAngleY.clear();
1787 
1788  xml_nodes.clear();
1789  xpath = "/Dimap_Document/Data_Strip/Sensor_Configuration/"
1790  "Instrument_Look_Angles_List/Instrument_Look_Angles/";
1791  xmlDocument->findNodes(xpath, xml_nodes);
1792 // if (xml_nodes.size() != theNumBands)
1793 // {
1794  if(xml_nodes.size() == 0)
1795  {
1796  setErrorStatus();
1797  if(traceDebug())
1798  {
1800  << MODULE << " DEBUG:"
1801  << "\nCould not find: " << xpath
1802  << std::endl;
1803  }
1804  return false;
1805  }
1806 
1807  node = xml_nodes.begin();
1808  while (node != xml_nodes.end())
1809  {
1810  sub_nodes.clear();
1811  xpath = "BAND_INDEX";
1812  (*node)->findChildNodes(xpath, sub_nodes);
1813  if (sub_nodes.size() == 0)
1814  {
1815  setErrorStatus();
1816  if(traceDebug())
1817  {
1819  << MODULE << " DEBUG:"
1820  << "\nCould not find: " << xpath
1821  << std::endl;
1822  }
1823  return false;
1824  }
1825 
1826  ossim_int32 bandIndex = sub_nodes[0]->getText().toInt32() - 1;
1827 
1828  if( (bandIndex >= static_cast<int>(theNumBands) ) || (bandIndex<0) )
1829  {
1830  ossimNotify(ossimNotifyLevel_WARN) << "ossimFormosatDimapSupportData: ERROR: Band index outside of range\n";
1831  return false;
1832  }
1833 
1834  if(bandIndex == band_index)
1835  {
1836  sub_nodes.clear();
1837  xpath = "Polynomial_Look_Angles/XLOS_0";
1838  (*node)->findChildNodes(xpath, sub_nodes);
1839  if (sub_nodes.size() == 0)
1840  {
1841  setErrorStatus();
1842  return false;
1843  }
1844  thePolynomialLookAngleX.push_back(sub_nodes[0]->getText().toDouble());
1845 
1846  sub_nodes.clear();
1847  xpath = "Polynomial_Look_Angles/XLOS_1";
1848  (*node)->findChildNodes(xpath, sub_nodes);
1849  if (sub_nodes.size() == 0)
1850  {
1851  setErrorStatus();
1852  return false;
1853  }
1854  thePolynomialLookAngleX.push_back(sub_nodes[0]->getText().toDouble());
1855 
1856  sub_nodes.clear();
1857  xpath = "Polynomial_Look_Angles/XLOS_2";
1858  (*node)->findChildNodes(xpath, sub_nodes);
1859  if (sub_nodes.size() == 0)
1860  {
1861  setErrorStatus();
1862  return false;
1863  }
1864  thePolynomialLookAngleX.push_back(sub_nodes[0]->getText().toDouble());
1865 
1866  sub_nodes.clear();
1867  xpath = "Polynomial_Look_Angles/XLOS_3";
1868  (*node)->findChildNodes(xpath, sub_nodes);
1869  if (sub_nodes.size() == 0)
1870  {
1871  setErrorStatus();
1872  return false;
1873  }
1874  thePolynomialLookAngleX.push_back(sub_nodes[0]->getText().toDouble());
1875 
1876  sub_nodes.clear();
1877  xpath = "Polynomial_Look_Angles/YLOS_0";
1878  (*node)->findChildNodes(xpath, sub_nodes);
1879  if (sub_nodes.size() == 0)
1880  {
1881  setErrorStatus();
1882  return false;
1883  }
1884  thePolynomialLookAngleY.push_back(sub_nodes[0]->getText().toDouble());
1885 
1886  sub_nodes.clear();
1887  xpath = "Polynomial_Look_Angles/YLOS_1";
1888  (*node)->findChildNodes(xpath, sub_nodes);
1889  if (sub_nodes.size() == 0)
1890  {
1891  setErrorStatus();
1892  return false;
1893  }
1894  thePolynomialLookAngleY.push_back(sub_nodes[0]->getText().toDouble());
1895 
1896  sub_nodes.clear();
1897  xpath = "Polynomial_Look_Angles/YLOS_2";
1898  (*node)->findChildNodes(xpath, sub_nodes);
1899  if (sub_nodes.size() == 0)
1900  {
1901  setErrorStatus();
1902  return false;
1903  }
1904  thePolynomialLookAngleY.push_back(sub_nodes[0]->getText().toDouble());
1905 
1906  sub_nodes.clear();
1907  xpath = "Polynomial_Look_Angles/YLOS_3";
1908  (*node)->findChildNodes(xpath, sub_nodes);
1909  if (sub_nodes.size() == 0)
1910  {
1911  setErrorStatus();
1912  return false;
1913  }
1914  thePolynomialLookAngleY.push_back(sub_nodes[0]->getText().toDouble());
1915  }
1916  ++node;
1917  }
1918 
1919 
1920  //---
1921  // Fetch the Attitude Samples:
1922  //---
1923  theAttitudeSamples.clear();
1924  theAttSampTimes.clear();
1925  xml_nodes.clear();
1926  xpath = "/Dimap_Document/Data_Strip/Attitudes/Corrected_Attitudes/ECF_Attitude/Angle_List/Angle";
1927  xmlDocument->findNodes(xpath, xml_nodes);
1928  if (xml_nodes.size() == 0)
1929  {
1930  setErrorStatus();
1931  if(traceDebug())
1932  {
1934  << MODULE << " DEBUG:"
1935  << "\nCould not find: " << xpath
1936  << std::endl;
1937  }
1938  return false;
1939  }
1940 
1941  node = xml_nodes.begin();
1942  while (node != xml_nodes.end())
1943  {
1944  ossimDpt3d V;
1945 
1946  sub_nodes.clear();
1947  xpath = "PITCH";
1948  (*node)->findChildNodes(xpath, sub_nodes);
1949  if (sub_nodes.size() == 0)
1950  {
1951  setErrorStatus();
1952  return false;
1953  }
1954  V.x = sub_nodes[0]->getText().toDouble();
1955 
1956  sub_nodes.clear();
1957  xpath = "ROLL";
1958  (*node)->findChildNodes(xpath, sub_nodes);
1959  if (sub_nodes.size() == 0)
1960  {
1961  setErrorStatus();
1962  return false;
1963  }
1964  V.y = sub_nodes[0]->getText().toDouble();
1965 
1966  sub_nodes.clear();
1967  xpath = "YAW";
1968  (*node)->findChildNodes(xpath, sub_nodes);
1969  if (sub_nodes.size() == 0)
1970  {
1971  setErrorStatus();
1972  return false;
1973  }
1974  V.z = sub_nodes[0]->getText().toDouble();
1975 
1976  theAttitudeSamples.push_back(V);
1977 
1978  sub_nodes.clear();
1979  xpath = "TIME";
1980  (*node)->findChildNodes(xpath, sub_nodes);
1981  if (sub_nodes.size() == 0)
1982  {
1983  setErrorStatus();
1984  return false;
1985  }
1986  theAttSampTimes.push_back(convertTimeStamp(sub_nodes[0]->getText()));
1987 
1988  ++node;
1989  }
1990 
1991  return true;
1992 }
1993 
1995  ossimRefPtr<ossimXmlDocument> xmlDocument)
1996 {
1997  ossimString xpath;
1998  std::vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
1999  std::vector<ossimRefPtr<ossimXmlNode> > sub_nodes;
2000  std::vector<ossimRefPtr<ossimXmlNode> >::iterator node;
2001 
2002  static const char MODULE[] = "ossimFormosatDimapSupportData::parsePart3";
2003 
2004 
2005  //---
2006  // Fetch the ephemeris samples:
2007  //---
2008  thePosEcfSamples.clear();
2009  theVelEcfSamples.clear();
2010  theEphSampTimes.clear();
2011  xml_nodes.clear();
2012  xpath = "/Dimap_Document/Data_Strip/Ephemeris/Raw_Ephemeris/Point_List/Point";
2013  xmlDocument->findNodes(xpath, xml_nodes);
2014  if (xml_nodes.size() == 0)
2015  {
2016  setErrorStatus();
2017  if(traceDebug())
2018  {
2020  << MODULE << " DEBUG:"
2021  << "\nCould not find: " << xpath
2022  << std::endl;
2023  }
2024  return false;
2025  }
2026  node = xml_nodes.begin();
2027 
2028  while (node != xml_nodes.end())
2029  {
2030  ossimDpt3d VP;
2031  sub_nodes.clear();
2032  xpath = "Location/X";
2033  (*node)->findChildNodes(xpath, sub_nodes);
2034  if (sub_nodes.size() == 0)
2035  {
2036  setErrorStatus();
2037  return false;
2038  }
2039  VP.x = sub_nodes[0]->getText().toDouble();
2040 
2041  sub_nodes.clear();
2042  xpath = "Location/Y";
2043  (*node)->findChildNodes(xpath, sub_nodes);
2044  if (sub_nodes.size() == 0)
2045  {
2046  setErrorStatus();
2047  return false;
2048  }
2049  VP.y = sub_nodes[0]->getText().toDouble();
2050 
2051  sub_nodes.clear();
2052  xpath = "Location/Z";
2053  (*node)->findChildNodes(xpath, sub_nodes);
2054  if (sub_nodes.size() == 0)
2055  {
2056  setErrorStatus();
2057  return false;
2058  }
2059  VP.z = sub_nodes[0]->getText().toDouble();
2060 
2061  thePosEcfSamples.push_back(VP);
2062 
2063  ossimDpt3d VV;
2064  sub_nodes.clear();
2065  xpath = "Velocity/X";
2066  (*node)->findChildNodes(xpath, sub_nodes);
2067  if (sub_nodes.size() == 0)
2068  {
2069  setErrorStatus();
2070  return false;
2071  }
2072  VV.x = sub_nodes[0]->getText().toDouble();
2073 
2074  sub_nodes.clear();
2075  xpath = "Velocity/Y";
2076  (*node)->findChildNodes(xpath, sub_nodes);
2077  if (sub_nodes.size() == 0)
2078  {
2079  setErrorStatus();
2080  return false;
2081  }
2082  VV.y = sub_nodes[0]->getText().toDouble();
2083 
2084  sub_nodes.clear();
2085  xpath = "Velocity/Z";
2086  (*node)->findChildNodes(xpath, sub_nodes);
2087  if (sub_nodes.size() == 0)
2088  {
2089  setErrorStatus();
2090  return false;
2091  }
2092  VV.z = sub_nodes[0]->getText().toDouble();
2093 
2094  theVelEcfSamples.push_back(VV);
2095 
2096  sub_nodes.clear();
2097  xpath = "TIME";
2098  (*node)->findChildNodes(xpath, sub_nodes);
2099  if (sub_nodes.size() == 0)
2100  {
2101  setErrorStatus();
2102  return false;
2103  }
2104  theEphSampTimes.push_back(convertTimeStamp(sub_nodes[0]->getText()));
2105 
2106  ++node;
2107  }
2108 
2109  //---
2110  // Fetch the star tracker flag:
2111  //---
2112  xml_nodes.clear();
2113  xpath = "/Dimap_Document/Data_Strip/Satellite_Attitudes/Corrected_Attitudes/"
2114  "STAR_TRACKER_USED";
2115  xmlDocument->findNodes(xpath, xml_nodes);
2116  if (xml_nodes.size() == 0)
2117  {
2118  theStarTrackerUsed = false;
2119 // setErrorStatus();
2120 // return false;
2121  }
2122  else
2123  {
2124  if (xml_nodes[0]->getText() == "Y")
2125  theStarTrackerUsed = true;
2126  else
2127  theStarTrackerUsed = false;
2128  }
2129 
2130  //---
2131  // Geoposition points:
2132  //---
2133  xml_nodes.clear();
2134  xpath = "/Dimap_Document/Geoposition/Geoposition_Points/Tie_Point";
2135  xmlDocument->findNodes(xpath, xml_nodes);
2136  node = xml_nodes.begin();
2137  while (node != xml_nodes.end())
2138  {
2139  ossimGpt gpt;
2140  ossimDpt ipt;
2141 
2142  sub_nodes.clear();
2143  xpath = "TIE_POINT_DATA_Y";
2144  (*node)->findChildNodes(xpath, sub_nodes);
2145  if (sub_nodes.size() == 0)
2146  {
2147  setErrorStatus();
2148  return false;
2149  }
2150  ipt.line = sub_nodes[0]->getText().toDouble() - 1.0;
2151 
2152  sub_nodes.clear();
2153  xpath = "TIE_POINT_DATA_X";
2154  (*node)->findChildNodes(xpath, sub_nodes);
2155  if (sub_nodes.size() == 0)
2156  {
2157  setErrorStatus();
2158  return false;
2159  }
2160  ipt.samp = sub_nodes[0]->getText().toDouble() - 1.0;
2161 
2162  sub_nodes.clear();
2163  xpath = "TIE_POINT_CRS_Y";
2164  (*node)->findChildNodes(xpath, sub_nodes);
2165  if (sub_nodes.size() == 0)
2166  {
2167  setErrorStatus();
2168  return false;
2169  }
2170  gpt.lat = sub_nodes[0]->getText().toDouble();
2171 
2172  sub_nodes.clear();
2173  xpath = "TIE_POINT_CRS_X";
2174  (*node)->findChildNodes(xpath, sub_nodes);
2175  if (sub_nodes.size() == 0)
2176  {
2177  setErrorStatus();
2178  return false;
2179  }
2180  gpt.lon = sub_nodes[0]->getText().toDouble();
2181 
2182  sub_nodes.clear();
2183  xpath = "TIE_POINT_CRS_Z";
2184  (*node)->findChildNodes(xpath, sub_nodes);
2185  if (sub_nodes.size() != 0)
2186  {
2187  gpt.hgt = sub_nodes[0]->getText().toDouble();
2188  }
2189 
2190  theGeoPosImagePoints.push_back(ipt);
2191  theGeoPosGroundPoints.push_back(gpt);
2192 
2193  ++node;
2194  }
2195 
2196  return true;
2197 }
2199  ossimRefPtr<ossimXmlDocument> xmlDocument)
2200 {
2201  ossimString xpath;
2202  std::vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
2203  std::vector<ossimRefPtr<ossimXmlNode> > sub_nodes;
2204  std::vector<ossimRefPtr<ossimXmlNode> >::iterator node;
2205 
2206  static const char MODULE[] = "ossimFormosatDimapSupportData::parsePart4";
2207 
2208  //---
2209  // Fetch the gain and bias for each spectral band:
2210  //---
2211 
2212  thePhysicalGain.assign(theNumBands, 1.000);
2213  thePhysicalBias.assign(theNumBands, 0.000);
2214  xml_nodes.clear();
2215  xpath = "/Dimap_Document/Data_Strip/Sensor_Calibration/Calibration/Band_Parameters/";
2216 
2217  xmlDocument->findNodes(xpath, xml_nodes);
2218  if(xml_nodes.size() == 0)
2219  {
2220  setErrorStatus();
2221  if(traceDebug())
2222  {
2224  << MODULE << " DEBUG:"
2225  << "\nCould not find: " << xpath
2226  << std::endl;
2227  }
2228  return false;
2229  }
2230 
2231  node = xml_nodes.begin();
2232  while (node != xml_nodes.end())
2233  {
2234  sub_nodes.clear();
2235  xpath = "BAND_INDEX";
2236  (*node)->findChildNodes(xpath, sub_nodes);
2237  if (sub_nodes.size() == 0)
2238  {
2239  setErrorStatus();
2240  if(traceDebug())
2241  {
2243  << MODULE << " DEBUG:"
2244  << "\nCould not find: " << xpath
2245  << std::endl;
2246  }
2247  return false;
2248  }
2249 
2250  ossim_int32 bandIndex = sub_nodes[0]->getText().toInt32() - 1;
2251 
2252 
2253  if( (bandIndex >= static_cast<int>(theNumBands) ) || (bandIndex<0) )
2254  {
2255  ossimNotify(ossimNotifyLevel_WARN) << "ossimFormosatDimapSupportData: ERROR: Band index outside of range\n";
2256  return false;
2257  }
2258 
2259  sub_nodes.clear();
2260  xpath = "Gain_Section_List/Gain_Section/PHYSICAL_BIAS";
2261  (*node)->findChildNodes(xpath, sub_nodes);
2262  if (sub_nodes.size() == 0)
2263  {
2264  setErrorStatus();
2265  return false;
2266  }
2267  thePhysicalBias[bandIndex] = sub_nodes[0]->getText().toDouble();
2268 
2269  sub_nodes.clear();
2270  xpath = "Gain_Section_List/Gain_Section/PHYSICAL_GAIN";
2271  (*node)->findChildNodes(xpath, sub_nodes);
2272  if (sub_nodes.size() == 0)
2273  {
2274  setErrorStatus();
2275  return false;
2276  }
2277  thePhysicalGain[bandIndex] = sub_nodes[0]->getText().toDouble();
2278 
2279  ++node;
2280  }
2281 
2282  theSolarIrradiance.assign(theNumBands, 0.000);
2283  xml_nodes.clear();
2284  xpath = "/Dimap_Document/Data_Strip/Sensor_Calibration/Solar_Irradiance/Band_Solar_Irradiance";
2285  xmlDocument->findNodes(xpath, xml_nodes);
2286  node = xml_nodes.begin();
2287  while (node != xml_nodes.end())
2288  {
2289  sub_nodes.clear();
2290  xpath = "BAND_INDEX";
2291  (*node)->findChildNodes(xpath, sub_nodes);
2292  if (sub_nodes.size() == 0)
2293  {
2294  setErrorStatus();
2295  return false;
2296  }
2297 
2298  ossim_int32 bandIndex = sub_nodes[0]->getText().toInt32() - 1;
2299 
2300  if((bandIndex >= static_cast<ossim_int32>(theNumBands) ) || (bandIndex<0))
2301  {
2302  ossimNotify(ossimNotifyLevel_WARN) << "ossimFormosatDimapSupportData::parsePart4 ERROR: Band index outside of range\n";
2303  return false;
2304  }
2305 
2306  sub_nodes.clear();
2307  xpath = "SOLAR_IRRADIANCE_VALUE";
2308  (*node)->findChildNodes(xpath, sub_nodes);
2309  if (sub_nodes.size() == 0)
2310  {
2311  setErrorStatus();
2312  return false;
2313  }
2314  theSolarIrradiance[bandIndex] = sub_nodes[0]->getText().toDouble();
2315 
2316  ++node;
2317  }
2318 
2319  return true;
2320 }
2321 
2323 {
2324  ossimString xpath;
2325  std::vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
2326 
2327  //---
2328  // Get the version string which can be used as a key for parsing.
2329  //---
2330  xpath = "/Dimap_Document/Metadata_Id/METADATA_FORMAT";
2331  xmlDocument->findNodes(xpath, xml_nodes);
2332  if (xml_nodes.size() == 0)
2333  {
2334  setErrorStatus();
2335  if(traceDebug())
2336  {
2338  << "DEBUG:\nCould not find: " << xpath
2339  << endl;
2340  }
2341  return false;
2342  }
2343 
2344  ossimString attribute = "version";
2345  ossimString value;
2346  xml_nodes[0]->getAttributeValue(value, attribute);
2347  if (value == "1.0")
2348  {
2350  }
2351  else if (value == "1.1")
2352  {
2354  }
2355 
2357  {
2358  setErrorStatus();
2359  if (traceDebug())
2360  {
2362  << "WARNING: metadata version not found!"
2363  << std::endl;
2364  }
2365  return false;
2366  }
2367  return true;
2368 }
2369 
2371  ossimRefPtr<ossimXmlDocument> xmlDocument)
2372 {
2373  ossimString xpath;
2374  vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
2375 
2376  //---
2377  // Fetch the Image ID:
2378  //---
2379  xpath = "/Dimap_Document/Production/JOB_ID";
2380  xmlDocument->findNodes(xpath, xml_nodes);
2381  if (xml_nodes.size() == 0)
2382  {
2383  setErrorStatus();
2384  if(traceDebug())
2385  {
2387  << "DEBUG:\nCould not find: " << xpath
2388  << endl;
2389  }
2390  return false;
2391  }
2392  theImageID = xml_nodes[0]->getText();
2393  return true;
2394 }
2395 
2397  ossimRefPtr<ossimXmlDocument> xmlDocument)
2398 {
2399  ossimString xpath;
2400  vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
2401 
2402  //---
2403  // Fetch the mission index (Formosat 1 or 2):
2404  // and generate theSensorID
2405  //---
2406  xml_nodes.clear();
2407  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/MISSION_INDEX";
2408  xmlDocument->findNodes(xpath, xml_nodes);
2409  if (xml_nodes.size() == 0)
2410  {
2411  setErrorStatus();
2412  if(traceDebug())
2413  {
2415  << "DEBUG:\nCould not find: " << xpath
2416  << std::endl;
2417  }
2418  return false;
2419  }
2420  if (xml_nodes[0]->getText() == "1")
2421  theSensorID = "Formosat 1";
2422  if (xml_nodes[0]->getText() == "2")
2423  theSensorID = "Formosat 2";
2424 
2425  //---
2426  // Fetch the Viewing Angle Along Track:
2427  //---
2428  xml_nodes.clear();
2429  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/SUN_AZIMUTH";
2430  xmlDocument->findNodes(xpath, xml_nodes);
2431  if (xml_nodes.size() == 0)
2432  {
2433  setErrorStatus();
2434  if(traceDebug())
2435  {
2437  << "DEBUG:\nCould not find: " << xpath
2438  << std::endl;
2439  }
2440  return false;
2441  }
2442  theSunAzimuth = xml_nodes[0]->getText().toDouble();
2443 
2444  //---
2445  // Fetch the Viewing Angle Across Track:
2446  //---
2447  xml_nodes.clear();
2448  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/VIEWING_ANGLE_ALONG_TRACK";
2449  xmlDocument->findNodes(xpath, xml_nodes);
2450  if (xml_nodes.size() == 0)
2451  {
2452  setErrorStatus();
2453  if(traceDebug())
2454  {
2456  << "DEBUG:\nCould not find: " << xpath
2457  << std::endl;
2458  }
2459  return false;
2460  }
2461  theViewingAngleAlongTrack = xml_nodes[0]->getText().toDouble();
2462 
2463  //---
2464  // Fetch the Sun Azimuth:
2465  //---
2466  xml_nodes.clear();
2467  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/VIEWING_ANGLE_ACROSS_TRACK";
2468  xmlDocument->findNodes(xpath, xml_nodes);
2469  if (xml_nodes.size() == 0)
2470  {
2471  setErrorStatus();
2472  if(traceDebug())
2473  {
2475  << "DEBUG:\nCould not find: " << xpath
2476  << std::endl;
2477  }
2478  return false;
2479  }
2480  theViewingAngleAcrossTrack = xml_nodes[0]->getText().toDouble();
2481 
2482  //---
2483  // Fetch the Sun Elevation:
2484  //---
2485  xml_nodes.clear();
2486  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/SUN_ELEVATION";
2487  xmlDocument->findNodes(xpath, xml_nodes);
2488  if (xml_nodes.size() == 0)
2489  {
2490  setErrorStatus();
2491  if(traceDebug())
2492  {
2494  << "DEBUG:\nCould not find: " << xpath
2495  << std::endl;
2496  }
2497  return false;
2498  }
2499  theSunElevation = xml_nodes[0]->getText().toDouble();
2500 
2501  //---
2502  // Fetch incidence angle:
2503  //---
2504  xml_nodes.clear();
2505  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/SATELLITE_INCIDENCE_ANGLE";
2506  xmlDocument->findNodes(xpath, xml_nodes);
2507  if (xml_nodes.size() == 0)
2508  {
2509  setErrorStatus();
2510  if(traceDebug())
2511  {
2513  << "DEBUG:\nCould not find: " << xpath
2514  << std::endl;
2515  }
2516  return false;
2517  }
2518  theIncidenceAngle = xml_nodes[0]->getText().toDouble();
2519 
2520  //---
2521  // Fetch incidence angle:
2522  //---
2523  xml_nodes.clear();
2524  xpath = "/Dimap_Document/Dataset_Sources/Source_Information/Scene_Source/SATELLITE_AZIMUTH_ANGLE";
2525  xmlDocument->findNodes(xpath, xml_nodes);
2526  if (xml_nodes.size() == 0)
2527  {
2528  setErrorStatus();
2529  if(traceDebug())
2530  {
2532  << "DEBUG:\nCould not find: " << xpath
2533  << std::endl;
2534  }
2535  return false;
2536  }
2537  theSatAzimuth = xml_nodes[0]->getText().toDouble();
2538 
2539  //---
2540  // Fetch viewing angle:
2541  /*
2542  * FROM FORMOSAT: You can use use incidence angle to calculate viewing angle
2543  * (called look direction as well).
2544  * FIX (see below): need theSatelliteAltitude and theIncidenceAngle. The
2545  * equation is shown below where RT is the mean value of WGS84 ellipsoid
2546  * semi-axis.
2547  *
2548  * */
2549  //---
2550 
2551  xml_nodes.clear();
2552  xpath = "/Dimap_Document/Data_Strip/Ephemeris/SATELLITE_ALTITUDE";
2553 
2554  theViewingAngle = -1.0;
2555  xmlDocument->findNodes(xpath, xml_nodes);
2556  if (xml_nodes.size() == 0)
2557  {
2558  setErrorStatus();
2559  if(traceDebug())
2560  {
2562  << "DEBUG:\nCould not find: " << xpath
2563  << std::endl;
2564  }
2565  return false;
2566  }
2567  //compute VIEWING_ANGLE
2568  double theSatelliteAltitude = xml_nodes[0]->getText().toDouble();
2569  double RT = 63710087714.0;
2570  theViewingAngle = asin((RT/(RT+theSatelliteAltitude))*sin(theIncidenceAngle));
2571 
2572  return true;
2573 }
2574 
2576  ossimRefPtr<ossimXmlDocument> xmlDocument)
2577 {
2578  ossimString xpath;
2579  vector<ossimRefPtr<ossimXmlNode> > xml_nodes;
2580 
2581  //---
2582  // Corner points:
2583  //---
2584  xml_nodes.clear();
2585  xpath = "/Dimap_Document/Dataset_Frame/Vertex";
2586  xmlDocument->findNodes(xpath, xml_nodes);
2587  if (xml_nodes.size() != 4)
2588  {
2589  setErrorStatus();
2590  return false;
2591  }
2592  std::vector<ossimRefPtr<ossimXmlNode> >::iterator node = xml_nodes.begin();
2593  while (node != xml_nodes.end())
2594  {
2595  ossimGpt gpt;
2596  ossimDpt ipt;
2597 
2598  std::vector<ossimRefPtr<ossimXmlNode> > sub_nodes;
2599  xpath = "FRAME_LAT";
2600  (*node)->findChildNodes(xpath, sub_nodes);
2601  if (sub_nodes.size() == 0)
2602  {
2603  setErrorStatus();
2604  return false;
2605  }
2606  gpt.lat = sub_nodes[0]->getText().toDouble();
2607 
2608  sub_nodes.clear();
2609  xpath = "FRAME_LON";
2610  (*node)->findChildNodes(xpath, sub_nodes);
2611  if (sub_nodes.size() == 0)
2612  {
2613  setErrorStatus();
2614  return false;
2615  }
2616  gpt.lon = sub_nodes[0]->getText().toDouble();
2617  gpt.hgt = 0.0; // assumed
2618 
2619  sub_nodes.clear();
2620  xpath = "FRAME_ROW";
2621  (*node)->findChildNodes(xpath, sub_nodes);
2622  if (sub_nodes.size() == 0)
2623  {
2624  setErrorStatus();
2625  return false;
2626  }
2627  ipt.line = sub_nodes[0]->getText().toDouble() - 1.0;
2628 
2629  sub_nodes.clear();
2630  xpath = "FRAME_COL";
2631  (*node)->findChildNodes(xpath, sub_nodes);
2632  if (sub_nodes.size() == 0)
2633  {
2634  setErrorStatus();
2635  return false;
2636  }
2637  ipt.samp = sub_nodes[0]->getText().toDouble() - 1.0;
2638 
2639  theFrameVertexPosImagePoints.push_back(ipt);
2640  theFrameVertexPosGroundPoints.push_back(gpt);
2641 
2642  ++node;
2643  }
2644 
2645  //---
2646  // Center of frame.
2647  //---
2648  theRefGroundPoint.hgt = 0.0; // needs to be looked up
2649 
2650  xml_nodes.clear();
2651  xpath = "/Dimap_Document/Dataset_Frame/Scene_Center/FRAME_LON";
2652  xmlDocument->findNodes(xpath, xml_nodes);
2653  if (xml_nodes.size() != 1)
2654  {
2655  setErrorStatus();
2656  return false;
2657  }
2658  theRefGroundPoint.lon = xml_nodes[0]->getText().toDouble();
2659 
2660  xml_nodes.clear();
2661  xpath = "/Dimap_Document/Dataset_Frame/Scene_Center/FRAME_LAT";
2662  xmlDocument->findNodes(xpath, xml_nodes);
2663  if (xml_nodes.size() != 1)
2664  {
2665  setErrorStatus();
2666  return false;
2667  }
2668  theRefGroundPoint.lat = xml_nodes[0]->getText().toDouble();
2669 
2670 
2671  //---
2672  // Fetch scene orientation:
2673  //---
2674  xml_nodes.clear();
2675  xpath = "/Dimap_Document/Dataset_Frame/SCENE_ORIENTATION";
2676  xmlDocument->findNodes(xpath, xml_nodes);
2677  if (xml_nodes.size() == 0)
2678  {
2679  setErrorStatus();
2680  if(traceDebug())
2681  {
2683  << "DEBUG:\nCould not find: " << xpath
2684  << std::endl;
2685  }
2686  return false;
2687  }
2688  theSceneOrientation = xml_nodes[0]->getText().toDouble();
2689 
2690  return true;
2691 }
2692 
virtual const ossimDatum * create(const ossimString &code) const
create method
void clear()
Erases the entire container.
Definition: ossimString.h:432
ossim_uint32 x
std::vector< ossim_float64 > thePolynomialLookAngleX
holds the size of thePixelLookAngleX/Y
void getPixelLookAngleY(ossim_uint32 sample, ossim_float64 &pa) const
bool parsePart1(ossimRefPtr< ossimXmlDocument > xmlDocument)
Private parse methods called by loadXml.
void getAttSampTime(ossim_uint32 sample, ossim_float64 &at) const
bool parsePart4(ossimRefPtr< ossimXmlDocument > xmlDocument)
std::vector< ossim_float64 > thePhysicalGain
ossimGpt createGround(const ossimString &s) const
ossim_float64 convertTimeStamp(const ossimString &time_stamp) const
static const char * IMAGE_DATE_KW
void getRefLineTimeLine(ossim_float64 &rtl) const
relative to full frame.
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
std::vector< ossimDpt > theFrameVertexPosImagePoints
void getInterpolatedLookAngle(const ossim_float64 &p, const std::vector< ossim_float64 > &angles, ossim_float64 &la) const
void getAttitude(ossim_uint32 sample, ossimDpt3d &at) const
Represents serializable keyword/value map.
ossim_uint32 y
void getViewingAngle(ossim_float64 &va) const
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
bool initMetadataVersion(ossimRefPtr< ossimXmlDocument > xmlDocument)
Initializes theMetadataVersion.
const char * find(const char *key) const
ossim_int64 fileSize() const
double samp
Definition: ossimDpt.h:164
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
void getViewingAngleAlongTrack(ossim_float64 &va) const
double y
Definition: ossimDpt.h:165
void getBilinearInterpolation(const ossim_float64 &t, const std::vector< ossimDpt3d > &V, const std::vector< ossim_float64 > &T, ossimDpt3d &li) const
bool contains(char aChar) const
Definition: ossimString.h:58
void getVelocityEcf(ossim_uint32 sample, ossimEcefPoint &ve) const
virtual const ossimString & code() const
Definition: ossimDatum.h:57
void makeNan()
Definition: ossimGpt.h:130
static ossimString toString(bool aValue)
Numeric to string methods.
std::vector< ossimDpt3d > theAttitudeSamples
void getIncidenceAngle(ossim_float64 &ia) const
void getSubImageOffset(ossimDpt &offset) const
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
void getLagrangeInterpolation(const ossim_float64 &t, const std::vector< ossimDpt3d > &V, const std::vector< ossim_float64 > &T, ossimDpt3d &li) const
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
static const char * TYPE_KW
bool initImageId(ossimRefPtr< ossimXmlDocument > xmlDocument)
Initializes theImageId.
const ossimDatum * datum() const
datum().
Definition: ossimGpt.h:196
ossim_int32 toInt32() const
bool parsePart2(ossimRefPtr< ossimXmlDocument > xmlDocument)
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
bool initSceneSource(ossimRefPtr< ossimXmlDocument > xmlDocument)
From xml section: /Dimap_Document/Dataset_Sources/Source_Information/Scene_Source.
double z
Definition: ossimDpt3d.h:145
double line
Definition: ossimDpt.h:165
ossimFormosatMetadataVersion theMetadataVersion
ossim_float64 lon
Definition: ossimGpt.h:266
std::vector< ossim_float64 > theSolarIrradiance
ossim_float64 theRefLineTime
relative to full image
std::string::iterator begin()
Definition: ossimString.h:420
unsigned int ossim_uint32
double height() const
Definition: ossimGpt.h:107
double toDouble() const
void getGeoPosPoint(ossim_uint32 point, ossimDpt &ip, ossimGpt &gp) const
static ossimDatumFactory * instance()
void makeNan()
Definition: ossimDpt3d.h:61
ossimGpt theRefGroundPoint
Center of frame on ground, if sub image it&#39;s the center of that.
std::vector< ossim_float64 > thePolynomialLookAngleY
void getEphSampTime(ossim_uint32 sample, ossim_float64 &et) const
static const char * NUMBER_BANDS_KW
bool parsePart3(ossimRefPtr< ossimXmlDocument > xmlDocument)
ossimDpt createDpt(const ossimString &s) const
static const char * AZIMUTH_ANGLE_KW
T min(T a, T b)
Definition: ossimCommon.h:203
void getImageRect(ossimDrect &rect) const
Zero based image rectangle, sub image if there is one.
void getPositionEcf(ossim_uint32 sample, ossimEcefPoint &pe) const
virtual ossimErrorCode getErrorStatus() const
std::vector< ossimGpt > theFrameVertexPosGroundPoints
void getRefImagePoint(ossimDpt &rp) const
zero base center point
bool initFramePoints(ossimRefPtr< ossimXmlDocument > xmlDocument)
Frame points:
void getRefLineTime(ossim_float64 &rt) const
void getPixelLookAngleX(ossim_uint32 sample, ossim_float64 &pa) const
ossim_float64 theRefLineTimeLine
relative to full image
std::vector< ossim_float64 > theEphSampTimes
double x
Definition: ossimDpt.h:164
double x
Definition: ossimDpt3d.h:143
long long ossim_int64
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
bool empty() const
Definition: ossimString.h:411
void getRefGroundPoint(ossimGpt &gp) const
Center of frame, sub image if there is one.
bool loadXmlFile(const ossimFilename &file)
bool read(std::istream &in)
void getSunElevation(ossim_float64 &el) const
void getSatAzimuth(ossim_float64 &az) const
ossim_float64 lat
Definition: ossimGpt.h:265
void getSunAzimuth(ossim_float64 &az) const
void findNodes(const ossimString &xpath, std::vector< ossimRefPtr< ossimXmlNode > > &nodelist) const
Appends any matching nodes to the list supplied (should be empty):
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
static const char * ELEVATION_ANGLE_KW
std::vector< ossim_float64 > theAttSampTimes
double y
Definition: ossimDpt3d.h:144
ossimDpt theRefImagePoint
Zero based center of frame.
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
std::vector< ossim_float64 > thePhysicalBias
callibration information for radiometric corrections
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
void getViewingAngleAcrossTrack(ossim_float64 &va) const
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void makeNan()
Definition: ossimDpt.h:65
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32
void getSceneOrientation(ossim_float64 &so) const
void getLineSamplingPeriod(ossim_float64 &pe) const