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