OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimCoarseGridModel.cpp
Go to the documentation of this file.
1 //*****************************************************************************
2 // FILE: ossimCoarseGridModel.cc
3 //
4 // License: See LICENSE.txt file in the top level directory.
5 //
6 // AUTHOR: Oscar Kramer
7 //
8 // DESCRIPTION:
9 // Contains implementation of class ossimCoarseGridModel. This is an
10 // implementation of an interpolation sensor model.
11 //
12 // IMPORTANT: The lat/lon grid is for ground points on the ellipsoid.
13 // The dLat/dHgt and dLon/dHgt partials therefore are used against
14 // elevations relative to the ellipsoid.
15 //
16 //*****************************************************************************
17 // $Id: ossimCoarseGridModel.cpp 22825 2014-07-07 23:14:52Z dburken $
18 
20 
21 RTTI_DEF1(ossimCoarseGridModel, "ossimCoarseGridModel", ossimSensorModel);
22 
23 #include <ossim/base/ossimGpt.h>
24 #include <ossim/base/ossimDpt.h>
34 #include <cstdio>
35 #include <fstream>
36 
37 //***
38 // Define Trace flags for use within this file:
39 //***
40 #include <ossim/base/ossimTrace.h>
41 
42 static ossimTrace traceExec ("ossimCoarseGridModel:exec");
43 static ossimTrace traceDebug ("ossimCoarseGridModel:debug");
44 
45 static const char* MODEL_TYPE = "ossimCoarseGridModel";
46 static const char* GRID_FILE_NAME_KW = "grid_file_name";
47 static const char* CROSSES_DATELINE_KW = "crosses_dateline";
48 
53 
54 //*****************************************************************************
55 // DEFAULT CONSTRUCTOR: ossimCoarseGridModel()
56 //
57 //*****************************************************************************
59  :
61  theDlatDparamGrid (0),
62  theDlonDparamGrid (0),
63  theHeightEnabledFlag(true)
64 {
65  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
66  << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel: entering..."
67  << std::endl;
68 
73 
75 
76  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
77  << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel: returning..."
78  << std::endl;
79 }
80 
81 //*****************************************************************************
82 // COPY CONSTRUCTOR: ossimCoarseGridModel(ossimCoarseGridModel)
83 //
84 //*****************************************************************************
86  :
87  ossimSensorModel (model),
88  theGridFilename (model.theGridFilename),
89  theLatGrid (model.theLatGrid),
90  theLonGrid (model.theLonGrid),
91  theDlatDhGrid (model.theDlatDhGrid),
92  theDlonDhGrid (model.theDlonDhGrid),
93  theDlatDparamGrid (0),
94  theDlonDparamGrid (0),
95  theHeightEnabledFlag(true)
96 {
97  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
98  << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(model): entering..."
99  << std::endl;
100 
101  int numberOfParams = getNumberOfAdjustableParameters();
102  if(numberOfParams)
103  {
104  //***
105  // Allocate adjustable parameter partials grids then assign:
106  //***
107  theDlatDparamGrid = new ossimDblGrid [numberOfParams];
108  theDlonDparamGrid = new ossimDblGrid [numberOfParams];
109 
110  for (int i=0; i<numberOfParams; i++)
111  {
112  theDlatDparamGrid[i] = model.theDlatDparamGrid[i];
113  theDlonDparamGrid[i] = model.theDlonDparamGrid[i];
114  }
115  }
116 
117  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
118  << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel: returning..."
119  << std::endl;
120 }
121 
122 //*****************************************************************************
123 // CONSTRUCTOR: ossimCoarseGridModel(filename)
124 //
125 // Constructs model from geometry file
126 //
127 //*****************************************************************************
129  :
131  theDlatDparamGrid (0),
132  theDlonDparamGrid (0),
133  theHeightEnabledFlag(true)
134 {
135  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(geom_file): entering..." << std::endl;
136 
141 
142  ossimKeywordlist kwl;
143  if(geom_file.exists()&&kwl.addFile(geom_file))
144  {
145  loadState(kwl);
146  theGridFilename = geom_file.path();
147  }
148  else
149  {
150  ++theErrorStatus;
151  }
152 
153  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(geom_file): returning..." << std::endl;
154  return;
155 }
156 
157 //*****************************************************************************
158 // CONSTRUCTOR: ossimCoarseGridModel(kwl)
159 //
160 // Constructs model from keywordlist geometry file
161 //
162 //*****************************************************************************
164  :
166  theDlatDparamGrid (0),
167  theDlonDparamGrid (0),
168  theHeightEnabledFlag(true)
169 {
170  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::ossimCoarseGridModel(geom_kwl): entering..." << std::endl;
171 
176 
177  // Parse keywordlist for geometry:
178  loadState(geom_kwl);
179 }
180 
181 //*************************************************************************************************
183 //*************************************************************************************************
185  ossimProjection* proj,
186  double heightDelta,
187  bool enableHeightFlag,
188  bool makeAdjustableFlag)
189 {
191  geom->setProjection(proj);
192  buildGrid(imageBounds, geom.get(), heightDelta, enableHeightFlag, makeAdjustableFlag);
193 }
194 
195 
196 //*************************************************************************************************
198 //*************************************************************************************************
200  ossimImageGeometry* geom,
201  double heightDelta,
202  bool enableHeightFlag,
203  bool makeAdjustableFlag)
204 {
205  theHeightEnabledFlag = enableHeightFlag;
206 
207  if (!geom->getProjection() || imageBounds.hasNans())
208  return;
209 
210  // don't let it get any smaller than 100, 100 pixels
211  // on the input projector
212  //
213  // may want this to be adjusted by outside
214  //
215  const ossimDatum* targetDatum = ossimDatumFactory::instance()->wgs84();
216  ossimIpt gridSize(2,2);
217  ossimDpt gridOrigin(0,0);
218  ossimGpt gpt;
219  ossimGpt gpt2;
220  ossimGpt bilinearGpt;
222  double normSplit = 1.0;
223  ossimIpt imageSize = ossimIpt(imageBounds.width(), imageBounds.height());
224  double error = 0.0;
225 
226  ossimIpt imageOrigin = imageBounds.ul();
227  ossimDpt spacing ((double)(imageBounds.width()-1)/(gridSize.x-1),
228  (double)(imageBounds.height()-1)/(gridSize.y-1));
229 
231  {
232  delete [] theDlatDparamGrid;
233  theDlatDparamGrid = NULL;
234  }
236  {
237  delete [] theDlonDparamGrid;
238  theDlonDparamGrid = NULL;
239  }
240 
241  geom->localToWorld(imageBounds.midPoint(), gpt);
242 
243  do
244  {
245  if(traceDebug())
246  {
247  ossimNotify(ossimNotifyLevel_DEBUG) << "Checking grid size " << gridSize << std::endl;
248  }
249 
250  spacing = ossimDpt((double)(imageBounds.width()-1)/(gridSize.x-1),
251  (double)(imageBounds.height()-1)/(gridSize.y-1));
252 
259  theLatGrid.initialize(gridSize, gridOrigin, spacing);
260  theLonGrid.initialize(gridSize, gridOrigin, spacing);
261  theDlatDhGrid.initialize(gridSize, gridOrigin, spacing);
262  theDlonDhGrid.initialize(gridSize, gridOrigin, spacing);
263  ossim_int32 x, y;
264 
265  for(y = 0; y < gridSize.y; ++y)
266  {
267  for(x = 0; x < gridSize.x; ++x)
268  {
269  ossimDpt norm((double)x/(double)(gridSize.x-1),
270  (double)y/(double)(gridSize.y-1));
271 
272  ossimDpt pt(imageOrigin.x + norm.x*(imageSize.x-1),
273  imageOrigin.y + norm.y*(imageSize.y-1));
274 
275  geom->localToWorld(pt, gpt);
276  double h = gpt.height();
277  if(ossim::isnan(h))
278  {
279  h += heightDelta;
280  }
281  ossimDpt fullPt;
282  geom->rnToFull(pt, 0, fullPt);
283  geom->getProjection()->lineSampleHeightToWorld(fullPt, h, gpt2);
284  gpt.changeDatum(targetDatum);
285  gpt2.changeDatum(targetDatum);
286 
287  theLatGrid.setNode(x, y, gpt.latd());
288  theLonGrid.setNode(x, y, gpt.lond());
289 
290  theDlatDhGrid.setNode(x, y, (gpt2.latd() - gpt.latd())/heightDelta);
291  theDlonDhGrid.setNode(x, y, (gpt2.lond() - gpt.lond())/heightDelta);
292  }
293  }
294  ossim_int32 upperY = 2*gridSize.y;
295  ossim_int32 upperX = 2*gridSize.x;
296  error = 0.0;
297 
298  // Set all base-class data members needed for subsequent calls to projection code:
299  initializeModelParams(imageBounds);
300 
301  for(y = 0; ((y < upperY)&&(error < theInterpolationError)); ++y)
302  {
303  for(x = 0; ((x < upperX)&&(error<theInterpolationError)); ++x)
304  {
305  ossimDpt norm((double)x/(double)(upperX-1),
306  (double)y/(double)(upperY-1));
307 
308  ossimDpt imagePoint(imageOrigin.x + norm.x*(imageSize.x-1),
309  imageOrigin.y + norm.y*(imageSize.y-1));
310  ossimDpt testIpt;
311 
312  geom->localToWorld(imagePoint, gpt);
313  worldToLineSample(gpt, testIpt);
314  error = (testIpt-imagePoint).length();
315  }
316  }
317 
318  gridSize.x *= 2;
319  gridSize.y *= 2;
320  normSplit *= .5;
321  } while((error > theInterpolationError) &&
322  ((imageSize.x*normSplit) > theMinGridSpacing) &&
323  ((imageSize.y*normSplit) > theMinGridSpacing));
324 
325  gridSize = theLatGrid.size();
326 
327  ossimAdjustableParameterInterface* adjustableParameters =
330  if(adjustableParameters&&makeAdjustableFlag)
331  {
332  if(adjustableParameters->getNumberOfAdjustableParameters() > 0)
333  {
334  newAdjustment(adjustableParameters->getNumberOfAdjustableParameters());
335 
336  int numberOfParams = getNumberOfAdjustableParameters();
337  if(numberOfParams)
338  {
339  //***
340  // Allocate adjustable parameter partials grids then assign:
341  //***
342  theDlatDparamGrid = new ossimDblGrid [numberOfParams];
343  theDlonDparamGrid = new ossimDblGrid [numberOfParams];
344  for(int paramIdx = 0; paramIdx < numberOfParams; ++ paramIdx)
345  {
346  theDlonDparamGrid[paramIdx].setNullValue(0.0);
347  theDlatDparamGrid[paramIdx].setNullValue(0.0);
348  theDlatDparamGrid[paramIdx].initialize(gridSize, gridOrigin, spacing);
349  theDlonDparamGrid[paramIdx].initialize(gridSize, gridOrigin, spacing);
350  setAdjustableParameter(paramIdx, 0.0);
351  setParameterSigma(paramIdx, adjustableParameters->getParameterSigma(paramIdx));
352  setParameterUnit(paramIdx, adjustableParameters->getParameterUnit(paramIdx));
353  setParameterCenter(paramIdx, 0.0);
354  setParameterDescription(paramIdx,
355  adjustableParameters->getParameterDescription(paramIdx));
356 
357  double oldParameter = adjustableParameters->getAdjustableParameter(paramIdx);
358  adjustableParameters->setAdjustableParameter(paramIdx, 1.0, true);
359  double adjust = adjustableParameters->computeParameterOffset(paramIdx);
360  double deltaLat = 0;
361  double deltaLon = 0;
362  if(adjust != 0.0)
363  {
364  for(int y = 0; y < gridSize.y; ++y)
365  {
366  for(int x = 0; x < gridSize.x; ++x)
367  {
368  ossimDpt norm((double)x/(double)(gridSize.x-1),
369  (double)y/(double)(gridSize.y-1));
370 
371  ossimDpt pt(imageOrigin.x + norm.x*(imageSize.x-1),
372  imageOrigin.y + norm.y*(imageSize.y-1));
373  geom->localToWorld(pt, gpt);
374 
375  gpt.changeDatum(targetDatum);
376  gpt2.latd(theLatGrid(pt));
377  gpt2.lond(theLonGrid(pt));
378  deltaLat = gpt.latd()-gpt2.latd();
379  deltaLon = gpt.lond()-gpt2.lond();
380 
381  theDlatDparamGrid[paramIdx].setNode(x, y, deltaLat/adjust);
382  theDlonDparamGrid[paramIdx].setNode(x, y, deltaLon/adjust);
383  }
384  }
385 
386  // The partials grids for this parameter are initialized, now initialize the
387  // grid's extrapolator:
390  }
391  adjustableParameters->setAdjustableParameter(paramIdx, oldParameter, true);
392  }
393  }
394  }
395  }
397 }
398 
400 {
401  theInterpolationError = error;
402 }
403 
405 {
406  theMinGridSpacing = minSpacing;
407 }
408 
409 //*************************************************************************************************
412 //*************************************************************************************************
414 {
415  // NOTE: it is assumed that the grid size and spacing is the same for ALL grids:
416  ossimIpt gridSize (theLatGrid.size());
417  ossimDpt spacing (theLatGrid.spacing());
418  ossimDpt v[4];
419  v[0].lat = theLatGrid.getNode(0,0);
420  v[0].lon = theLonGrid.getNode(0,0);
421  v[1].lat = theLatGrid.getNode(gridSize.x-1, 0);
422  v[1].lon = theLonGrid.getNode(gridSize.x-1, 0);
423  v[2].lat = theLatGrid.getNode(gridSize.x-1, gridSize.y-2);
424  v[2].lon = theLonGrid.getNode(gridSize.x-1, gridSize.y-2);
425  v[3].lat = theLatGrid.getNode(0, gridSize.y-2);
426  v[3].lon = theLonGrid.getNode(0, gridSize.y-2);
427 
428  // Guaranty longitude values are -180 to 180
429  for (int i=0; i<4; i++)
430  {
431  if (v[i].lon > 180.0)
432  v[i].lon -= 360.0;
433  }
434 
436 
437  theImageSize = ossimDpt(imageBounds.width(), imageBounds.height());
438  theRefImgPt = imageBounds.midPoint();
441 
442  ossimDpt ref_ip_dx (theRefImgPt.x+1.0, theRefImgPt.y );
443  ossimDpt ref_ip_dy (theRefImgPt.x , theRefImgPt.y+1.0);
444  ossimGpt ref_gp_dx (theLatGrid(ref_ip_dx), theLonGrid(ref_ip_dx));
445  ossimGpt ref_gp_dy (theLatGrid(ref_ip_dy), theLonGrid(ref_ip_dy));
446 
447  theGSD.x = theRefGndPt.distanceTo(ref_gp_dx);
448  theGSD.y = theRefGndPt.distanceTo(ref_gp_dy);
449 
450  theMeanGSD = (theGSD.line + theGSD.samp)/2.0;
451  theImageClipRect = imageBounds;
452  theSubImageOffset = imageBounds.ul();
453 }
454 
455 //*****************************************************************************
456 // DESTRUCTOR: ~ossimCoarseGridModel()
457 //
458 //*****************************************************************************
460 {
461  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
462  << "DEBUG ossimCoarseGridModel::~ossimCoarseGridModel: entering..."
463  << std::endl;
464 
466  {
467  //***
468  // Deallocate memory:
469  //***
470  delete [] theDlatDparamGrid;
471  delete [] theDlonDparamGrid;
472  theDlatDparamGrid = NULL;
473  theDlonDparamGrid = NULL;
474  }
475  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG)
476  << "DEBUG ossimCoarseGridModel::~ossimCoarseGridModel: returning..."
477  << std::endl;
478 }
479 
480 //*************************************************************************************************
481 // METHOD
482 //*************************************************************************************************
484  ossimGpt& gpt) const
485 {
487  {
488  //
489  // Extrapolate if image point is outside image:
490  //
491  if (!insideImage(image_point))
492  {
493  gpt = extrapolate(image_point);
494  return;
495  }
496 
497  lineSampleHeightToWorld(image_point, 0.0, gpt);
498  }
499  else
500  {
501  ossimSensorModel::lineSampleToWorld(image_point, gpt);
502  }
503 }
504 
505 //*****************************************************************************
506 // METHOD: ossimCoarseGridModel::lineSampleHeightToWorld()
507 //
508 // Establishes the ground point corresponding to the input image_point and
509 // specified elevation above MSL
510 //
511 //*****************************************************************************
512 void
514  const double& arg_hgt_above_ellipsoid,
515  ossimGpt& worldPt) const
516 {
517  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::lineSampleHeightToWorld: entering..." << std::endl;
518 
519  if(theLatGrid.size().x < 1 ||
520  theLatGrid.size().y < 1)
521  {
522  worldPt.makeNan();
523  return;
524  }
525 
526  double height = (ossim::isnan(arg_hgt_above_ellipsoid)) ? 0.0 : arg_hgt_above_ellipsoid;
527 
528  // Note that there is no check for image point outside of valid image rect because this model
529  // uses the extrapolation inherent to the ossimDblGrid.
530 
531  // The image point may correspond to an offset sub-image. Need to convert
532  // to full image space before anything:
533  ossimDpt ip = lineSampPt + theSubImageOffset;
534 
535  // Establish the interpolated values from the grids:
536  worldPt.lat = theLatGrid(ip);
537  worldPt.lon = theLonGrid(ip);
538  worldPt.hgt = height;
539 
541  {
542  // Adjust horizontally due to elevation:
543  worldPt.lat += theDlatDhGrid(ip)*height;
544  worldPt.lon += theDlonDhGrid(ip)*height;
545  }
546  int numberOfParams = getNumberOfAdjustableParameters();
547 
548  // Now add increments due to adjustable parameter deltas:
549  for (int p=0; p<numberOfParams; p++)
550  {
551  worldPt.lat += (theDlatDparamGrid[p](ip) * computeParameterOffset(p));
552  worldPt.lon += (theDlonDparamGrid[p](ip) * computeParameterOffset(p));
553  }
554 
555  worldPt.limitLonTo180();
556 
557  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::lineSampleHeightToWorld: returning..." << std::endl;
558 }
559 
560 //*************************************************************************************************
561 // METHOD
562 //*************************************************************************************************
564 {
566  {
568  }
569  else
570  {
572  }
573 }
574 
575 //*************************************************************************************************
576 // METHOD
577 //*************************************************************************************************
579  ossimEcefRay& image_ray) const
580 {
581  ossimSensorModel::imagingRay(image_point, image_ray);
582 }
583 
584 
585 //*****************************************************************************
586 // METHOD: ossimCoarseGridModel::print()
587 //
588 // Formatted dump of data members.
589 //
590 //*****************************************************************************
592 {
593  out << "\nDump of ossimCoarseGridModel object at: " << this << "\n"
594  << "\n Grid File Name: " << theGridFilename
595  << "\n Image ID: " << theImageID
596  << "\n Sensor: " << theSensorID
597  << "\n Image Size (rows, cols): " << theImageSize
598  << "\n Ref Pt (samp, line): " << theRefImgPt
599  << "\n Ref Pt (lat, lon, hgt): " << theRefGndPt
600  << "\n GSD (row, col): " << theGSD
601  << "\n Bounding Ground Polygon: " << theBoundGndPolygon << endl;
602 // << "\n Number of Params: " << theNumParams << "\n"<<endl;
603 
604  char buf[256];
606  ossimDpt spacing (theLatGrid.spacing());
607  int line, samp;
608  ossimIpt node;
609 
610  out << "[ line, samp] lat lon dLat/dH dLon/dH\n"
611  << "-------------------------------------------------------------------"
612  <<endl;
613 
614  for (node.y=0; node.y<size.y; node.y++)
615  {
616  line = (int) (node.y*spacing.y);
617 
618  for (node.x=0; node.x<size.x; node.x++)
619  {
620  samp = (int) (node.x*spacing.x);
621 
622  sprintf(buf, "[%5d, %5d] %+9.5f %+10.5f %+11.4e %+11.4e",
623  line, samp,
624  theLatGrid.getNode(node),
625  theLonGrid.getNode(node),
626  theDlatDhGrid.getNode(node),
627  theDlonDhGrid.getNode(node));
628  out << buf << endl;
629  }
630  out <<"-----------------------------------------------------------------"
631  <<endl;
632  }
633 
634  out << "\n\nDump of lat/lon Partials w.r.t. Adjustable Parameters:"<<endl;
635  out << "\nEnd Dump of ossimCoarseGridModel.\n" << endl;
636  return out;
637 }
638 
639 //*****************************************************************************
640 // METHOD: ossimCoarseGridModel::saveState()
641 //
642 // Saves the model state to the KWL. This KWL also serves as a geometry file.
643 //
644 // Returns true if successful.
645 //
646 //*****************************************************************************
648  const char* prefix) const
649 {
650  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveState: entering..." << std::endl;
651 
652  kwl.add(prefix, ossimKeywordNames::TYPE_KW, "ossimCoarseGridModel");
653 
654  //---
655  // Save just the file part so that the geometry stuff is relocatable.
656  // Code was added to ossimProjectionFactoryBase::createProjectionFromGeometryFile
657  // to handle this.
658  //---
659  kwl.add( prefix, GRID_FILE_NAME_KW, theGridFilename.file() );
660 
661  kwl.add(prefix, "height_enabled_flag", theHeightEnabledFlag, true);
662  ossimSensorModel::saveState(kwl, prefix);
663  ossimString initAdjPrefix = ossimString(prefix) + "init_adjustment.";
664  theInitialAdjustment.saveState(kwl, initAdjPrefix);
665 
666  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveState: returning..." << std::endl;
667 
668  return true;
669 }
670 
671 //*****************************************************************************
672 // METHOD: ossimCoarseGridModel::loadState()
673 //
674 // Restores the model's state from the KWL. This KWL also serves as a
675 // geometry file.
676 //
677 // Returns true if successful.
678 //
679 //*****************************************************************************
681  const char* prefix)
682 {
683  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: entering..." << std::endl;
684 
686  const char* value;
687  bool success;
688 
689  //***
690  // Assure this keywordlist contains correct type info:
691  //***
692  value = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
693  if (!value || (strcmp(value, "ossimCoarseGridModel")))
694  {
695  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning..." << std::endl;
696  theErrorStatus++;
697  return false;
698  }
699  value = kwl.find(prefix, "height_enabled_flag");
700  if(value)
701  {
703  }
704 
705  //***
706  // Pass on to the base-class for parsing first:
707  //***
708  success = ossimSensorModel::loadState(kwl, prefix);
709  if (!success)
710  {
711  theErrorStatus++;
712  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning with error..." << std::endl;
713  return false;
714  }
715 
716  //***
717  // Look for geom filename or explicit grid filename to establish path to grid:
718  //***
719  theGridFilename = kwl.find(prefix, GRID_FILE_NAME_KW);
720 
722  {
723  //---
724  // This is set in ossimProjectionFactoryBase::createProjectionFromGeometryFile
725  // so we can derive the dot.ocg from it.
726  //---
727  ossimFilename alt_path_to_grid = kwl.find("kwl_source");
729 
731  {
732  ossimFilename alt_path_to_grid = kwl.find(prefix, ossimKeywordNames::GEOM_FILE_KW);
734  }
735  }
736 
738  {
739  ossimNotify(ossimNotifyLevel_FATAL) << "ossimCoarseGridModel::loadState() -- Error "
740  "encountered opening coarse grid file at "<< "<" <<theGridFilename << ">." << std::endl;
741  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning with error..." << std::endl;
742  theErrorStatus++;
743  return false;
744  }
745 
746  // Load the coarse grid file specified in KWL. This method resets the
747  // theErrorStatus to OSSIM_OK if successful:
749  {
750  theErrorStatus++;
751  return false;
752  }
753 
754  // crossesDateline legacy. No longer saved.
755  bool crossesDateline = false;
756  kwl.getBoolKeywordValue(crossesDateline, CROSSES_DATELINE_KW, prefix);
757  if (crossesDateline)
759 
760  // Add the coarse grid filename to list of support files being referenced for logging purposes:
762 
763  ossimString initAdjPrefix = ossimString(prefix) + "init_adjustment.";
764  theInitialAdjustment.loadState(kwl, initAdjPrefix.c_str());
765 
766  if((ossim::isnan(theRefGndPt.hgt)) ||
767  (theRefGndPt.hgt == 0))
768  {
770  if(theRefGndPt.hgt < 0)
771  {
772  theRefGndPt.hgt = fabs(theRefGndPt.hgt);
773  }
774  }
775 
777  {
779  }
780  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadState: returning..." << std::endl;
781  if (theErrorStatus)
782  return false;
783 
784  return true;
785 }
786 
787 //*****************************************************************************
788 // METHOD: ossimCoarseGridModel::saveCoarseGrid(cgFileName)
789 //
790 // Saves the coarse grid to disk file.
791 //
792 // Returns true if successful.
793 //
794 //*****************************************************************************
796 {
797  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: entering..." << std::endl;
798 
799  // Create and open grid file as stream:
800  theGridFilename = fileName.expand();
802  ofstream outstream (theGridFilename.chars());
803  if (!outstream.is_open())
804  {
805  theErrorStatus++;
806  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: Error "
807  "encountered creating coarse grid file <" << theGridFilename<< ">. Check that directory "
808  "exists and is writable." << std::endl;
809  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: returning with error..." << std::endl;
810  return false;
811  }
812 
813  // Let each grid object write itself to the output file:
814  theLatGrid.save(outstream, "Latitude Grid");
815  theLonGrid.save(outstream, "Longitude Grid");
816  theDlatDhGrid.save(outstream, "dLat/dH Grid");
817  theDlonDhGrid.save(outstream, "dLon_dH Grid");
818 
819  ossimString descr;
820  int numberOfParams = getNumberOfAdjustableParameters();
821  for (int p=0; p<numberOfParams; p++)
822  {
823  descr = getParameterDescription(p) + " dLat_dParam Grid";
824  theDlatDparamGrid[p].save(outstream, descr.chars());
825  descr = getParameterDescription(p) + " dLon_dParam Grid";
826  theDlonDparamGrid[p].save(outstream, descr.chars());
827  }
828 
829  // Since the geom file is needed in the same path as the grid file, take this opportunity to
830  // write the geom file out as well:
831  ossimFilename geom_file (theGridFilename);
833  ossimKeywordlist kwl;
834  saveState(kwl);
835  kwl.write(geom_file);
836 
837  // Add to the list of support files referenced (though technically it has not yet been
838  // referenced, but will be next time this image is opened):
839  ossimSupportFilesList::instance()->add(geom_file);
841 
842  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::saveCoarseGrid: returning..." << std::endl;
843  return true;
844 }
845 
846 
847 //*****************************************************************************
848 // METHOD: ossimCoarseGridModel::loadCoarseGrid(cgFileName)
849 //
850 // Loads the coarse grid from disk file.
851 //
852 // Returns true if successful.
853 //
854 //*****************************************************************************
856 {
857  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadCoarseGrid: entering..." << std::endl;
858 
859  ossimDpt v[4];
860  ossimIpt grid_size;
861 
862  //***
863  // Open existing grid file:
864  //***
865  ifstream instream (cgFileName.chars());
866  if (!instream.is_open())
867  {
868  theErrorStatus++;
869  if(traceDebug())
870  {
871  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimCoarseGridModel::loadCoarseGrid: Error encountered opening coarse grid file <" << cgFileName
872  << ">. Check that the file exists and is readable." << std::endl;
873  }
874  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "CEBUG ossimCoarseGridModel::loadCoarseGrid: returning with error..." << std::endl;
875  return false;
876  }
877  theGridFilename = cgFileName;
879  {
880  delete [] theDlatDparamGrid;
881  theDlatDparamGrid = NULL;
882  }
884  {
885  delete [] theDlonDparamGrid;
886  theDlonDparamGrid = NULL;
887  }
888  //
889  // Reallocate memory:
890  //
891  int numberOfParams = getNumberOfAdjustableParameters();
892  if(numberOfParams)
893  {
894  theDlatDparamGrid = new ossimDblGrid [numberOfParams];
895  theDlonDparamGrid = new ossimDblGrid [numberOfParams];
896  }
897  //***
898  // Let each grid object read itself from the input file:
899  //***
900  if (!theLatGrid.load(instream))
901  {
902  ++theErrorStatus;
903  return false;
904  }
905  if (!theLonGrid.load(instream))
906  {
907  ++theErrorStatus;
908  return false;
909  }
910  if (!theDlatDhGrid.load(instream))
911  {
912  ++theErrorStatus;
913  return false;
914  }
915  if (!theDlonDhGrid.load(instream))
916  {
917  ++theErrorStatus;
918  return false;
919  }
920 
921  for (int p=0; p<numberOfParams; p++)
922  {
923  if (!theDlatDparamGrid[p].load(instream))
924  {
925  ++theErrorStatus;
926  return false;
927  }
928  if (!theDlonDparamGrid[p].load(instream))
929  {
930  ++theErrorStatus;
931  return false;
932  }
933  }
934 
935  //***
936  // Initialize the bounding ground rectangle:
937  //***
938  grid_size = theLatGrid.size();
939 
940  v[0].lat = theLatGrid(0,0);
941  v[0].lon = theLonGrid(0,0);
942  v[1].lat = theLatGrid(theImageSize.x-1, 0);
943  v[1].lon = theLonGrid(theImageSize.x-1, 0);
944  v[2].lat = theLatGrid(theImageSize.x-1, theImageSize.y-1);
945  v[2].lon = theLonGrid(theImageSize.x-1, theImageSize.y-1);
946  v[3].lat = theLatGrid(0, theImageSize.y-1);
947  v[3].lon = theLonGrid(0, theImageSize.y-1);
948 
950 
951  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::loadCoarseGrid: returning..." << std::endl;
952  return true;
953 }
954 
955 
956 //*****************************************************************************
957 // METHOD: ossimCoarseGridModel::reallocateGrid()
958 //
959 // Deletes existing grid arrays and allocates new ones.
960 //
961 //*****************************************************************************
963 {
964  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::reallocateGrid:entering..." << endl;
965 
966 
967  //***
968  // Deallocate memory:
969  //***
971  {
972  delete [] theDlatDparamGrid;
973  theDlatDparamGrid = NULL;
974  }
976  {
977  delete [] theDlonDparamGrid;
978  theDlonDparamGrid = NULL;
979  }
980  //***
981  // determine grid spacing given new info:
982  //***
983  ossimDpt spacing ((double)(theImageSize.x-1)/(double)(grid_size.x-1),
984  (double)(theImageSize.y-1)/(double)(grid_size.y-1));
985 
986  //***
987  // Allocate all:
988  //***
989  ossimDpt grid_origin(0.0, 0.0);
994  theLatGrid.initialize(grid_size, grid_origin, spacing);
995  theLonGrid.initialize(grid_size, grid_origin, spacing);
996  theDlatDhGrid.initialize(grid_size, grid_origin, spacing);
997  theDlonDhGrid.initialize(grid_size, grid_origin, spacing);
998 
999  int numberOfParams = getNumberOfAdjustableParameters();
1000  if(numberOfParams)
1001  {
1002 
1003  theDlatDparamGrid = new ossimDblGrid [numberOfParams];
1004  theDlonDparamGrid = new ossimDblGrid [numberOfParams];
1005  }
1006  for (int p=0; p<numberOfParams; p++)
1007  {
1010  theDlatDparamGrid[p].initialize(grid_size, grid_origin, spacing);
1011  theDlonDparamGrid[p].initialize(grid_size, grid_origin, spacing);
1012  }
1013 
1014  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::reallocateGrid: returning..." << std::endl;
1015  return;
1016 }
1017 
1018 //*****************************************************************************
1019 // STATIC METHOD: ossimCoarseGridModel::writeGeomTemplate
1020 //
1021 // Writes a sample geometry KWL to the output stream.
1022 //
1023 //*****************************************************************************
1025 {
1026  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::writeGeomTemplate: entering..." << std::endl;
1027 
1028  os <<
1029  "//**************************************************************\n"
1030  "// Template for OCG model kewordlist\n"
1031  "//**************************************************************\n"
1032  << ossimKeywordNames::TYPE_KW << ": " << MODEL_TYPE << endl;
1033 
1035 
1036  os << "//\n"
1037  << "// Derived-class ossimCoarseGridModel Keywords:\n"
1038  << "//\n"
1039  << GRID_FILE_NAME_KW << ": <string>\n" << endl;
1040 
1041  if (traceExec()) ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimCoarseGridModel::writeGeomTemplate: returning..." << std::endl;
1042  return;
1043 }
1044 
1045 //*************************************************************************************************
1046 // Overrides base-class extrapolation code. Uses extrapolation inherent to ossimDbleGrid
1047 //*************************************************************************************************
1048 ossimGpt ossimCoarseGridModel::extrapolate(const ossimDpt& local_ip, const double& height) const
1049 {
1050  ossimGpt gpt;
1051  lineSampleHeightToWorld(local_ip, height, gpt);
1052  return gpt;
1053 }
1054 
1056 {
1057  return theHeightEnabledFlag;
1058 }
ossimString theSensorID
ossim_uint32 x
void reallocateGrid(const ossimIpt &size)
Deletes existing allocated memory and reallocates new space.
virtual bool isAffectedByElevation() const
image to ground faster
void setParameterDescription(ossim_uint32 idx, const ossimString &descrption)
virtual void initAdjustableParameters()
void setProjection(ossimProjection *projection)
Sets the projection to be used for local-to-world coordinate transformation.
virtual void imagingRay(const ossimDpt &image_point, ossimEcefRay &image_ray) const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
ossim_float64 width() const
Definition: ossimDrect.h:522
static double theInterpolationError
static void setMinGridSpacing(ossim_int32 minSpacing=100)
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
Represents serializable keyword/value map.
bool addFile(const char *file)
ossim_uint32 y
std::basic_ifstream< char > ifstream
Class for char input file streams.
Definition: ossimIosFwd.h:44
const char * find(const char *key) const
ossimString theImageID
double samp
Definition: ossimDpt.h:164
ossimFilename expand() const
Method to do file name expansion.
ossim_uint32 getNumberOfAdjustableParameters() const
bool loadState(const ossimKeywordlist &kwl, const ossimString &prefix=ossimString(""))
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
const ossimDpt & ul() const
Definition: ossimDrect.h:339
const ossimIpt & size() const
Definition: ossimDblGrid.h:187
double y
Definition: ossimDpt.h:165
ossim_uint32 height() const
Definition: ossimIrect.h:487
virtual void lineSampleToWorld(const ossimDpt &image_point, ossimGpt &gpt) const
void makeNan()
Definition: ossimGpt.h:130
void setDomainType(DomainType dt)
Definition: ossimDblGrid.h:156
void setNullValue(double value)
Definition: ossimDblGrid.h:183
const ossimIpt & ul() const
Definition: ossimIrect.h:274
void initialize(const ossimIpt &size, const ossimDpt &origin, const ossimDpt &spacing, double null_value=OSSIM_DEFAULT_NULL_PIX_DOUBLE)
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Fulfills ossimObject base-class pure virtuals.
static ossimElevManager * instance()
METHOD: instance() Implements singelton pattern.
virtual void lineSampleToWorld(const ossimDpt &image_point, ossimGpt &world_point) const
virtual void buildGrid(const ossimDrect &imageBounds, ossimProjection *proj, double heightDelta=500.0, bool enableHeightFlag=false, bool makeAdjustableFlag=true)
This method will build a grid from any projector.
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
virtual bool write(const char *file, const char *comment=0) const
Methods to dump the ossimKeywordlist to a file on disk.
double distanceTo(const ossimGpt &arg_gpt) const
METHOD: distanceTo(ossimGpt) Computes straight-line distance in meters between this and arg gpt: ...
Definition: ossimGpt.cpp:431
virtual ossimGpt extrapolate(const ossimDpt &imgPt, const double &height=ossim::nan()) const
Implements its own extrapolation since this can be handled by ossimDblGrid.
static const char * TYPE_KW
void changeDatum(const ossimDatum *datum)
This will actually perform a shift.
Definition: ossimGpt.cpp:316
void enableExtrapolation(bool arg=true)
Definition: ossimDblGrid.h:91
void limitLonTo180()
METHOD: limitLonTo180() Converts the lon data member to a value between -180 and +180: ...
Definition: ossimGpt.h:219
ossimDpt imageSize() const
ossimString getParameterDescription(ossim_uint32 idx) const
void setAdjustment(const ossimAdjustmentInfo &adj, bool notify=false)
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
bool loadCoarseGrid(const ossimFilename &cgFileName)
Loads the coarse grid from the specified file.
ossimDpt theSubImageOffset
void add(const ossimFilename &f)
Add support data filename to the list:
static ossim_int32 theMinGridSpacing
ossimUnitType getParameterUnit(ossim_uint32 idx) const
bool load(std::istream &is)
double line
Definition: ossimDpt.h:165
double lat
Definition: ossimDpt.h:165
void rnToFull(const ossimDpt &rnPt, ossim_uint32 resolutionLevel, ossimDpt &fullPt) const
rnToFull is a utility method that takes a rn resolution image point and maps it to the full image poi...
yy_size_t size
bool exists() const
ossim_float64 lon
Definition: ossimGpt.h:266
bool localToWorld(const ossimDpt &local_pt, ossimGpt &world_pt) const
Exposes the 3D projection from image to world coordinates.
virtual double getHeightAboveEllipsoid(const ossimGpt &gpt)
ossimIpt midPoint() const
Definition: ossimIrect.h:750
static void setInterpolationError(double error=.1)
This is used when building a grid from a projector.
bool saveState(ossimKeywordlist &kwl, const ossimString &prefix=ossimString("")) const
virtual std::ostream & print(std::ostream &out) const
Extends base-class implementation.
bool toBool() const
String to numeric methods.
virtual void lineSampleHeightToWorld(const ossimDpt &lineSampPt, const double &heightAboveEllipsoid, ossimGpt &worldPt) const =0
void newAdjustment(ossim_uint32 numberOfParameters=0)
const char * chars() const
For backward compatibility.
Definition: ossimString.h:77
ossimPolygon theBoundGndPolygon
double height() const
Definition: ossimGpt.h:107
void addAdjustment(const ossimAdjustmentInfo &adj, bool notify)
#define PTR_CAST(T, p)
Definition: ossimRtti.h:321
static ossimDatumFactory * instance()
const ossimFilename DEFAULT_GRID_FILE_EXT("ocg")
double getNode(const ossimIpt &p) const
Definition: ossimDblGrid.h:111
void setParameterUnit(ossim_uint32 idx, ossimUnitType unit)
virtual void imagingRay(const ossimDpt &image_point, ossimEcefRay &image_ray) const
static const char * GEOM_FILE_KW
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
bool hasNans() const
Definition: ossimDrect.h:396
ossim_uint32 width() const
Definition: ossimIrect.h:500
const ossimFilename DEFAULT_GEOM_FILE_EXT("geom")
bool getBoolKeywordValue(bool &rtn_val, const char *keyword, const char *prefix=0) const
[OLK, Aug/2008] Sets the boolean <rtn_val> depending on value associated with keyword for values = (y...
double lon
Definition: ossimDpt.h:164
ossim_float64 height() const
Definition: ossimDrect.h:517
static void writeGeomTemplate(ostream &os)
Container class that holds both 2D transform and 3D projection information for an image Only one inst...
bool isReadable() const
bool save(std::ostream &os, const char *descr) const
ossimAdjustmentInfo theInitialAdjustment
virtual void worldToLineSample(const ossimGpt &world_point, ossimDpt &image_point) const
const ossimProjection * getProjection() const
Access methods for projection (may be NULL pointer).
ossimDrect theImageClipRect
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Fulfills ossimObject base-class pure virtuals.
ossimDpt midPoint() const
Definition: ossimDrect.h:817
virtual void setAdjustableParameter(ossim_uint32 idx, double value, bool notify=false)
ossim_int32 y
Definition: ossimIpt.h:142
bool saveCoarseGrid(const ossimFilename &cgFileName) const
Saves the coarse grid to the specified file.
double x
Definition: ossimDpt.h:164
void resizeAdjustableParameterArray(ossim_uint32 numberOfParameters)
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
void initializeModelParams(ossimIrect irect)
Initializes base class data members after grids have been assigned.
ossimFilename file() const
virtual bool insideImage(const ossimDpt &p) const
ossim_int32 x
Definition: ossimIpt.h:141
ossim_float64 lat
Definition: ossimGpt.h:265
void getAdjustment(ossimAdjustmentInfo &adj) const
std::basic_ofstream< char > ofstream
Class for char output file streams.
Definition: ossimIosFwd.h:47
static ossimSupportFilesList * instance()
const ossimDatum * wgs84() const
ossimDblGrid * theDlonDparamGrid
ossimDblGrid * theDlatDparamGrid
ossimFilename & setExtension(const ossimString &e)
Sets the extension of a file name.
void setParameterCenter(ossim_uint32 idx, double center, bool notify=false)
bool crossesDateline(H5::DataSet &dataset, const ossimIrect &validRect)
Checks for dateline cross.
RTTI_DEF1(ossimCoarseGridModel, "ossimCoarseGridModel", ossimSensorModel)
ossimFilename path() const
static void writeGeomTemplate(ostream &os)
Writes a template of geometry keywords processed by loadState and saveState to output stream...
void setParameterSigma(ossim_uint32 idx, double value, bool notify=false)
void setNode(const ossimIpt &p, const double &value)
Definition: ossimDblGrid.h:107
virtual void lineSampleHeightToWorld(const ossimDpt &image_point, const double &heightEllipsoid, ossimGpt &world_pt) const
This is the virtual that performs the actual work of projecting the image point to the earth at some ...
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
ossim_float64 theMeanGSD
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32
const ossimDpt & spacing() const
Definition: ossimDblGrid.h:189
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91