OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimPolynomProjection.cpp
Go to the documentation of this file.
1 //*****************************************************************************
2 // FILE: ossimPolynomProjection.cpp
3 // AUTHOR: Frederic Claudel Meraka/CSIR, oct 2005
4 //*****************************************************************************
5 //TODO: speed up getMetersPerPixel using polynom derivatives
6 //
7 
11 
13 
14 #include <ossim/base/ossimGpt.h>
15 #include <ossim/base/ossimDpt.h>
19 #include <ossim/base/ossimString.h>
20 
21 #include <iostream>
22 #include <sstream>
23 #include <float.h>
24 
25 // keywords
26 static const char* MODEL_TYPE = "ossimPolynomProjection";
27 static const char* LAT_SCALE_KW = "lat_scale";
28 static const char* LON_SCALE_KW = "long_scale";
29 static const char* HGT_SCALE_KW = "height_scale";
30 static const char* LAT_OFFSET_KW = "lat_off";
31 static const char* LON_OFFSET_KW = "long_off";
32 static const char* HGT_OFFSET_KW = "height_off";
33 static const char* POLY_LINE_KW = "poly_line";
34 static const char* POLY_SAMP_KW = "poly_samp";
35 
37  :
39  theLonOffset(0.0),
40  theLonScale(1.0),
41  theLatOffset(0.0),
42  theLatScale(1.0),
43  theHgtOffset(0.0),
44  theHgtScale(1e-5)
45  {}
46 
48  :
50 
51  thePolyLine(model.thePolySamp),
52  thePolySamp(model.thePolyLine),
53 
54  thePolyLine_DLon(model.thePolyLine_DLon),
55  thePolyLine_DLat(model.thePolyLine_DLat),
56  thePolySamp_DLon(model.thePolySamp_DLon),
57  thePolySamp_DLat(model.thePolySamp_DLat),
58 
59  theLonOffset(model.theLonOffset),
60  theLonScale(model.theLonScale),
61  theLatOffset(model.theLatOffset),
62  theLatScale(model.theLatScale),
63  theHgtOffset(model.theHgtOffset),
64  theHgtScale(model.theHgtScale)
65 {
66 }
67 
69 {}
70 
71 //*****************************************************************************
72 // METHOD: ossimPolynomProjection::worldToLineSample()
73 //
74 // Overrides base class implementation. Directly computes line-sample from
75 // the polynomials.
76 //*****************************************************************************
77 void
79  ossimDpt& imgPt)const
80 {
81  if(ground_point.isLatNan() || ground_point.isLonNan() )
82  {
83  imgPt.makeNan();
84  return;
85  }
86 
87  //***
88  // Normalize the lat, lon, hgt:
89  //***
90  vector<double> gpt(3);
91  gpt[0] = (ground_point.lon - theLonOffset) * theLonScale;
92  gpt[1] = (ground_point.lat - theLatOffset) * theLatScale;
93 
94  if(ossim::isnan(ground_point.hgt)||ossim::almostEqual(theHgtOffset, 0.0))
95  {
96  gpt[2] = 0.0;
97  }
98  else
99  {
100  gpt[2] = (ground_point.hgt - theHgtOffset) * theHgtScale;
101  }
102 
103  imgPt.x = thePolySamp.eval(gpt);
104  imgPt.y = thePolyLine.eval(gpt);
105 
106  return;
107 }
108 
109 void
111  ossimGpt& worldPoint)const
112 {
113  // how does this work on a DEM??
114  if(!imagePoint.hasNans())
115  {
116  lineSampleHeightToWorld(imagePoint,
117  worldPoint.height(),
118  worldPoint);
119  }
120  else
121  {
122  worldPoint.makeNan();
123  }
124 }
125 
126 //*****************************************************************************
127 // METHOD: ossimPolynomProjection::lineSampleHeightToWorld()
128 //
129 // Performs reverse projection of image line/sample to ground point.
130 // The imaging ray is intersected with a level plane at height = elev.
131 //
132 // NOTE: U = line, V = sample -- this differs from the convention.
133 //
134 //*****************************************************************************
136  const double& ellHeight,
137  ossimGpt& gpt) const
138 {
139  //
140  // Constants for convergence tests:
141  //
142  static const int MAX_NUM_ITERATIONS = 10;
143  static const double CONVERGENCE_EPSILON = 0.1; // pixels
144 
145  //
146  // The image point must be adjusted by the adjustable parameters as well
147  // as the scale and offsets given as part of the RPC param normalization.
148  //
149  // NOTE: U = line, V = sample
150  //
151  double U = image_point.y;
152  double V = image_point.x;
153 
154 
155  //***
156  // Initialize quantities to be used in the iteration for ground point:
157  //***
158  vector<double> ngpt(3);
159  ngpt[0] = 0.0; //normalized longitude (center)
160  ngpt[1] = 0.0; //normalized latitude
161  if(ossim::isnan(ellHeight)||ossim::almostEqual(theHgtOffset, 0.0))
162  {
163  ngpt[2] = 0; // norm height
164  }
165  else
166  {
167  ngpt[2] = (ellHeight - theHgtOffset) * theHgtScale; // norm height
168  }
169 
170  double epsilonU = CONVERGENCE_EPSILON;
171  double epsilonV = CONVERGENCE_EPSILON;
172  int iteration = 0;
173 
174  //***
175  // Declare variables only once outside the loop. These include:
176  // * polynomials (numerators Pu, Pv, and denominators Qu, Qv),
177  // * partial derivatives of polynomials wrt X, Y,
178  // * computed normalized image point: Uc, Vc,
179  // * residuals of normalized image point: deltaU, deltaV,
180  // * partial derivatives of Uc and Vc wrt X, Y,
181  // * corrections to normalized lat, lon: deltaLat, deltaLon.
182  //***
183  double Uc, Vc;
184  double deltaU, deltaV;
185  double dU_dLat, dU_dLon, dV_dLat, dV_dLon, W;
186  double deltaLat, deltaLon;
187 
188  //***
189  // Now iterate until the computed Uc, Vc is within epsilon of the desired
190  // image point U, V:
191  //***
192  do
193  {
194  //***
195  // Calculate the normalized line and sample Uc, Vc as ratio of
196  // polynomials Pu, Qu and Pv, Qv:
197  //***
198  Uc = thePolyLine.eval(ngpt); //TBC
199  Vc = thePolySamp.eval(ngpt); //TBC
200 
201  //***
202  // Compute residuals between desired and computed line, sample:
203  //***
204  deltaU = U - Uc;
205  deltaV = V - Vc;
206 
207  //***
208  // Check for convergence and skip re-linearization if converged:
209  //***
210  if ((fabs(deltaU) > epsilonU) || (fabs(deltaV) > epsilonV))
211  {
212  //***
213  // Analytically compute partials of quotients U and V wrt lat, lon:
214  //***
215  dU_dLat = thePolyLine_DLat.eval(ngpt);
216  dU_dLon = thePolyLine_DLon.eval(ngpt);
217  dV_dLat = thePolySamp_DLat.eval(ngpt);
218  dV_dLon = thePolySamp_DLon.eval(ngpt);
219 
220  W = dU_dLon*dV_dLat - dU_dLat*dV_dLon;
221 
222  //***
223  // Now compute the corrections to normalized lat, lon:
224  //***
225  deltaLat = (dU_dLon*deltaV - dV_dLon*deltaU) / W;
226  deltaLon = (dV_dLat*deltaU - dU_dLat*deltaV) / W;
227  ngpt[0] += deltaLon;
228  ngpt[1] += deltaLat;
229  }
230 
231  iteration++;
232 
233  } while (((fabs(deltaU)>epsilonU) || (fabs(deltaV)>epsilonV))
234  && (iteration < MAX_NUM_ITERATIONS));
235 
236  //***
237  // Test for exceeding allowed number of iterations. Flag error if so:
238  //***
239  if (iteration == MAX_NUM_ITERATIONS)
240  {
241  ossimNotify(ossimNotifyLevel_WARN) << "WARNING ossimPolynomProjection::lineSampleHeightToWorld: \nMax number of iterations reached in ground point "
242  << "solution. Results are inaccurate." << endl;
243  }
244 
245  //***
246  // Now un-normalize the ground point lat, lon and establish return quantity:
247  //***
248  gpt.lat = ngpt[1] / theLatScale + theLatOffset;
249  gpt.lon = ngpt[0] / theLonScale + theLonOffset;
250  gpt.hgt = ellHeight;
251 }
252 
254 {
255  //TBC should return samp = 0, line = 0, but this has no meaning here
256  return ossimGpt(theLatOffset,
257  theLonOffset,
258  theHgtOffset);
259 }
260 
261 
263 {
264  //TBC TBD : use derivative polynoms (this is approximative anyway)
265 
267  ossimDpt centerI;
268  worldToLineSample(centerG,centerI);
269 
270  ossimDpt left = centerI + ossimDpt(-1,0);
271  ossimDpt right = centerI + ossimDpt(1,0);
272  ossimDpt top = centerI + ossimDpt(0,-1);
273  ossimDpt bottom = centerI + ossimDpt(0,1);
274 
275  ossimGpt leftG;
276  ossimGpt rightG;
277  ossimGpt topG;
278  ossimGpt bottomG;
279 
280  lineSampleToWorld(left, leftG);
281  lineSampleToWorld(right, rightG);
282  lineSampleToWorld(top, topG);
283  lineSampleToWorld(bottom, bottomG);
284 
285  ossimDpt result;
286 
287  result.x = (ossimEcefPoint(leftG) - ossimEcefPoint(rightG)).magnitude()/2.0;
288  result.y = (ossimEcefPoint(topG) - ossimEcefPoint(bottomG)).magnitude()/2.0;
289 
290  return result;
291 }
292 
294 {
295  if(&projection == this) return true;
296 
297  //TBD TBC: compare polynoms after applying affine transforms (=polynom)
298  // TBD => need polynom composition
299  return false;
300 }
301 
302 
303 //*****************************************************************************
304 // METHOD: ossimPolynomProjection::print()
305 //
306 // Formatted dump of data members.
307 //
308 //*****************************************************************************
310 {
311  out << "\nDump of ossimPolynomProjection object at " << hex << this << ":\n"
312  << LAT_SCALE_KW << ": " << theLatScale << "\n"
313  << LON_SCALE_KW << ": " << theLonScale << "\n"
314  << HGT_SCALE_KW << ": " << theHgtScale << "\n"
315  << LAT_OFFSET_KW << ": " << theLatOffset << "\n"
316  << LON_OFFSET_KW << ": " << theLonOffset << "\n"
317  << HGT_OFFSET_KW << ": " << theHgtOffset << "\n"
318  << "PolySamp: " <<thePolySamp << "\n"
319  << "PolyLine: " <<thePolyLine << "\n";
320  out << endl;
321 
322  return ossimProjection::print(out);
323 }
324 
325 //*****************************************************************************
326 // METHOD: ossimPolynomProjection::saveState()
327 //
328 // Saves the model state to the KWL. This KWL also serves as a geometry file.
329 //
330 //*****************************************************************************
332  const char* prefix) const
333 {
334  kwl.add(prefix, ossimKeywordNames::TYPE_KW, MODEL_TYPE);
335 
336  ossimProjection::saveState(kwl, prefix);
337 
338  kwl.add(prefix, LAT_SCALE_KW, theLatScale);
339  kwl.add(prefix, LON_SCALE_KW, theLonScale);
340  kwl.add(prefix, HGT_SCALE_KW, theHgtScale);
341  kwl.add(prefix, LAT_OFFSET_KW, theLatOffset);
342  kwl.add(prefix, LON_OFFSET_KW, theLonOffset);
343  kwl.add(prefix, HGT_OFFSET_KW, theHgtOffset);
344 
345  ostringstream polyLineS;
346  thePolyLine.print(polyLineS);
347  ostringstream polySampS;
348  thePolySamp.print(polySampS);
349 
350  kwl.add(prefix, POLY_LINE_KW, polyLineS.str().c_str());
351  kwl.add(prefix, POLY_SAMP_KW, polySampS.str().c_str());
352  //note: dont't save derivatives
353 
354  return true;
355 }
356 
357 //*****************************************************************************
358 // METHOD: ossimPolynomProjection::loadState()
359 //
360 // Restores the model's state from the KWL. This KWL also serves as a
361 // geometry file.
362 //
363 //*****************************************************************************
365  const char* prefix)
366 {
367  const char* value;
368  const char* keyword;
369 
370  //***
371  // Pass on to the base-class for parsing first:
372  //***
373  bool success = ossimProjection::loadState(kwl, prefix);
374  if (!success)
375  {
376  ossimNotify(ossimNotifyLevel_DEBUG) << "DEBUG ossimPolynomProjection::loadState(): ossimProjection::loadState() returning with error..." << endl;
377  return false;
378  }
379 
380  //***
381  // Continue parsing for local members:
382  //***
383 
384  keyword = LAT_SCALE_KW;
385  value = kwl.find(prefix, keyword);
386  if (!value)
387  {
388  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
389  << "<" << keyword << ">. Check the keywordlist for proper syntax."
390  << std::endl;
391  return false;
392  }
393  theLatScale = ossimString(value).toDouble();
394 
395  keyword = LON_SCALE_KW;
396  value = kwl.find(prefix, keyword);
397  if (!value)
398  {
399  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
400  << "<" << keyword << ">. Check the keywordlist for proper syntax."
401  << std::endl;
402  return false;
403  }
404  theLonScale = ossimString(value).toDouble();
405 
406  keyword = HGT_SCALE_KW;
407  value = kwl.find(prefix, keyword);
408  if (!value)
409  {
410  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
411  << "<" << keyword << ">. Check the keywordlist for proper syntax."
412  << std::endl;
413  return false;
414  }
415  theHgtScale = ossimString(value).toDouble();
416 
417  keyword = LAT_OFFSET_KW;
418  value = kwl.find(prefix, keyword);
419  if (!value)
420  {
421  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
422  << "<" << keyword << ">. Check the keywordlist for proper syntax."
423  << std::endl;
424  return false;
425  }
426  theLatOffset = ossimString(value).toDouble();
427 
428  keyword = LON_OFFSET_KW;
429  value = kwl.find(prefix, keyword);
430  if (!value)
431  {
432  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
433  << "<" << keyword << ">. Check the keywordlist for proper syntax."
434  << std::endl;
435  return false;
436  }
437  theLonOffset = ossimString(value).toDouble();
438 
439  keyword = HGT_OFFSET_KW;
440  value = kwl.find(prefix, keyword);
441  if (!value)
442  {
443  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
444  << "<" << keyword << ">. Check the keywordlist for proper syntax."
445  << std::endl;
446  return false;
447  }
448  theHgtOffset = ossimString(value).toDouble();
449 
450  //load polynoms using streams
451  keyword = POLY_LINE_KW;
452  value = kwl.find(prefix, keyword);
453  if (!value)
454  {
455  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
456  << "<" << keyword << ">. Check the keywordlist for proper syntax."
457  << std::endl;
458  return false;
459  }
460  std::istringstream polyLineIS;
461  polyLineIS.str(std::string(value));
462  thePolyLine.import(polyLineIS);
463 
464  keyword = POLY_SAMP_KW;
465  value = kwl.find(prefix, keyword);
466  if (!value)
467  {
468  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::loadState(): Error encountered parsing the following required keyword: "
469  << "<" << keyword << ">. Check the keywordlist for proper syntax."
470  << std::endl;
471  return false;
472  }
473  std::istringstream polySampIS;
474  polySampIS.str(std::string(value));
475  thePolySamp.import(polySampIS);
476 
477  //init dependent members
479 
480  return true;
481 }
482 
483 void
485 {
486  thePolyLine = poly;
488 }
489 
490 void
492 {
493  thePolySamp = poly;
495 }
496 
497 void
499 {
502 }
503 
504 void
506 {
509 }
510 
511 void
513 {
516 }
517 
518 bool
520 {
521 
522  return setupDesiredExponents(setup);
523 }
524 
527 {
528  //is number of desired monoms * 2
529  return (ossim_uint32)theExpSet.size() * 2;
530 }
531 
532 bool
534 {
535  bool res=false;
536  theExpSet.clear();
537 
538  //setup monoms from a xyz1 string, eg: y 1 xy x2y3 x2y2z2
539  std::vector< ossimString > spm = monoms.explode(" \t,;");
540  for (std::vector< ossimString >::const_iterator it = spm.begin(); it!=spm.end() ;++it)
541  {
543  res = stringToExp(*it, et);
544  if (!res)
545  {
547  "FATAL ossimPolynomProjection::setupDesiredExponents(): bad exponent tuple string: "<<*it<<std::endl;
548  return false;
549  }
550  //add to exponents
551  theExpSet.insert(et);
552  }
553  return true;
554 }
555 
556 void
557 ossimPolynomProjection::setupDesiredExponents(int horizonal_ord, int vertical_ord)
558 {
559  //build a classic exponent set - two passes: first horiz (two dim), then second vertically (one dim)
560  theExpSet.clear();
561  thePolySamp.addExpTupleRight(2, horizonal_ord, theExpSet );
562  thePolySamp.addExpTupleRight(1, vertical_ord, theExpSet );
563 }
564 
565 double
566 ossimPolynomProjection::optimizeFit(const ossimTieGptSet& tieSet, double* /* targetVariance */)
567 {
568  //NOTE: ignore targetVariance
569 
570  if (tieSet.size() <=0 )
571  {
572  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::fitToTiePoints(): empty tie point set"<< std::endl;
573  return -1.0;
574  }
575 
576  // find bounds for inputs (ground points) and setup offsets and scales
577  // TBD : check anti-meridian crossings + modulo 360!
578  ossimGpt gmin,gmax;
579  tieSet.getGroundBoundaries(gmin,gmax);
580  if(gmax.isLatNan() || gmax.isLonNan()|| gmin.isLatNan()||gmin.isLonNan())
581  {
582  return -1.0;
583  }
584  //get offsets
585  theLonOffset = (gmax.lon+gmin.lon)/2.0;
586  theLatOffset = (gmax.lat+gmin.lat)/2.0;
587  if(ossim::isnan(gmax.hgt)||ossim::isnan(gmin.hgt))
588  {
589  theHgtOffset = 0.0;
590  }
591  else if (gmax.hgt <= OSSIM_DEFAULT_MIN_PIX_DOUBLE)
592  {
593  //no height value found
594  theHgtOffset = 0.0;
595  }
596  else
597  {
598  theHgtOffset = (gmax.hgt+gmin.hgt)/2.0;
599  }
600 
601  //get scales
602  ossim_float64 lonScale = (gmax.lon-gmin.lon)/2.0;
603  ossim_float64 latScale = (gmax.lat-gmin.lat)/2.0;
604  ossim_float64 hgtScale = 1.0;
605 
606  if(!ossim::isnan(gmax.hgt)&&!ossim::isnan(gmin.hgt))
607  {
608  hgtScale = (gmax.hgt-gmin.hgt)/2.0;
609  }
610  //test ranges and correct
611  if ((lonScale < DBL_EPSILON) && (latScale < DBL_EPSILON))
612  {
613  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::fitToTiePoints(): ground points are all on the same spot"<< std::endl;
614  return -1.0;
615  }
616  if (lonScale < DBL_EPSILON) lonScale = theLatScale;
617  if (latScale < DBL_EPSILON) latScale = theLonScale;
618 
619  if (hgtScale < DBL_EPSILON) hgtScale = 1.0; //TBC : arbitrary value in meters
620 
621  //store inverted extents
622  theLonScale = 1.0/lonScale;
623  theLatScale = 1.0/latScale;
624  theHgtScale = 1.0/hgtScale;
625 
626 // std::cout << "theLonScale = " << theLonScale << std::endl
627 // << "theLatScale = " << theLatScale << std::endl
628 // << "theHgtScale = " << theHgtScale << std::endl
629 // << "theHgtOffset = " << theHgtOffset << std::endl;
630  //normalize ground points and store in ossimPolynom input space
631  // + store line and samp separately
632  vector< ossimPolynom< ossim_float64 , 3 >::VAR_TUPLE > inputs(tieSet.size());
633  vector< ossim_float64 > lines(tieSet.size());
634  vector< ossim_float64 > samps(tieSet.size());
635  const vector<ossimRefPtr<ossimTieGpt> >& theTPV = tieSet.getTiePoints();
636 
637  vector< ossimPolynom< ossim_float64 , 3 >::VAR_TUPLE >::iterator pit;
638  vector< ossim_float64 >::iterator sit;
639  vector< ossim_float64 >::iterator lit;
640  vector<ossimRefPtr<ossimTieGpt> >::const_iterator tit;
641  for (tit = theTPV.begin(), pit=inputs.begin(), lit=lines.begin(), sit=samps.begin(); tit!=theTPV.end() ; ++tit,++lit, ++sit,++pit)
642  {
643  //setup input
644  pit->push_back(((*tit)->lon - theLonOffset)*theLonScale);
645  pit->push_back(((*tit)->lat - theLatOffset)*theLatScale);
646  if (ossim::isnan((*tit)->hgt))
647  {
648  pit->push_back(theHgtOffset);
649  }
650  else
651  {
652  pit->push_back(((*tit)->hgt - theHgtOffset)*theHgtScale);
653  }
654 
655  //setup line/samp outputs
656  *sit = (*tit)->tie.x;
657  *lit = (*tit)->tie.y;
658  }
659 
660  //fit polynoms to data using least mean squares
661  double line_rms=0.0;
662  bool resfit = thePolyLine.LMSfit(theExpSet, inputs, lines, &line_rms);
663  if (!resfit)
664  {
665  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::fitToTiePoints(): lines polynom LMS fit failed "<< std::endl;
666  return -1.0;
667  }
668  double samp_rms=0.0;
669  resfit = thePolySamp.LMSfit(theExpSet, inputs, samps, &samp_rms);
670  if (!resfit)
671  {
672  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::fitToTiePoints(): samples polynom LMS fit failed "<< std::endl;
673  return -1.0;
674  }
675 
676  //init
678 
679 // std::cout << "line_rms = " << line_rms << std::endl
680 // << "samp_rms = " << samp_rms << std::endl;
681  return samp_rms*samp_rms + line_rms*line_rms; //variance
682 }
683 
684 bool
686 {
687  et.clear();
688 
689  ossimString ts = s.trim().upcase();
690  ossimString tkeys("XYZ");
691 
692  if (ts.size() == 0)
693  {
694  return false;
695  }
696  //check 1
697  if (ts[static_cast<std::string::size_type>(0)] == '1')
698  {
699  for(int i=0;i<3;i++) et.push_back(0);
700  return true;
701  }
702 
703  //loop on symbols
704  int ex[3]={0,0,0};
705 
706  while (ts.size()>0)
707  {
708  int symb = getSymbol(ts, tkeys);
709  if (symb<0)
710  {
711  ossimNotify(ossimNotifyLevel_FATAL) << "FATAL ossimPolynomProjection::stringToExp(): cant find any symbol"<< std::endl;
712  return false;
713  }
714  int expo = getExponent(ts);
715  if (ex[symb]>0)
716  {
718  << "FATAL ossimPolynomProjection::stringToExp(): symbol appears twice: "
719  <<tkeys[static_cast<std::string::size_type>(symb)]
720  << std::endl;
721  return false;
722  }
723  ex[symb] = expo;
724  }
725  for(int i=0;i<3;i++) et.push_back(ex[i]);
726 
727  return true;
728 }
729 
730 int
732 { //remove symbol from string ts and return symbol index, -1 = error
733  for(unsigned int i=0;i<symbols.size();++i)
734  {
735  if (ts.operator[](0) == symbols.operator[](i))
736  {
737  ts = ts.afterPos(0);
738  return i;
739  }
740  }
741  return -1;
742 }
743 
744 int
746 { //remove exponent from string, no exponent means 1
747  unsigned int pos=0;
748  int expo=0;
749  const ossimString& cts(ts);
750  while ( (pos<ts.size()) && (cts.operator[](pos)<='9') && (cts.operator[](pos)>='0'))
751  {
752  expo = 10*expo + (cts.operator[](pos)-'0');
753  ++pos;
754  }
755  //remove exp from string
756  if (pos>0) ts=ts.afterPos(pos-1);
757 
758  if (expo==0) expo=1;
759  return expo;
760 }
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
ossimPolynom< ossim_float64, 3 >::EXPT_SET theExpSet
desired exponents tuples set (for both line and sample polynoms) used for optimization ...
virtual std::ostream & print(std::ostream &out) const
Outputs theErrorStatus as an ossimErrorCode and an ossimString.
unsigned int size() const
static ossimString upcase(const ossimString &aString)
Definition: ossimString.cpp:34
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
T eval(const VAR_TUPLE &v) const
evaluation : needs DIM values as input
Definition: ossimPolynom.h:219
Represents serializable keyword/value map.
bool isLonNan() const
Definition: ossimGpt.h:140
const char * find(const char *key) const
bool almostEqual(T x, T y, T tolerance=FLT_EPSILON)
Definition: ossimCommon.h:53
virtual std::ostream & print(std::ostream &out) const
Outputs theErrorStatus as an ossimErrorCode and an ossimString.
ossimString afterPos(std::string::size_type pos) const
void setPolyLine(const ossimPolynom< ossim_float64, 3 > &poly)
double y
Definition: ossimDpt.h:165
void setPolySamp(const ossimPolynom< ossim_float64, 3 > &poly)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
void makeNan()
Definition: ossimGpt.h:130
ossimPolynom< ossim_float64, 3 > thePolySamp_DLat
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
ossimPolynom< ossim_float64, 3 > thePolySamp
xyz polynom
bool isLatNan() const
Definition: ossimGpt.h:139
virtual void lineSampleHeightToWorld(const ossimDpt &image_point, const double &heightEllipsoid, ossimGpt &worldPoint) const
static const char * TYPE_KW
ossim_float64 theLonOffset
normalization parameters
void setupDesiredExponents(int horizonal_ord, int vertical_ord)
bool stringToExp(const ossimString &s, ossimPolynom< ossim_float64, 3 >::EXP_TUPLE &et) const
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
std::istream & import(std::istream &is)
note that it can only import for the template type T and dimesnion DIM
Definition: ossimPolynom.h:440
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual class enabling projection optimization (can be used for outlier rejection - RANSAC) ...
#define OSSIM_DEFAULT_MIN_PIX_DOUBLE
ossim_float64 lon
Definition: ossimGpt.h:266
std::string::size_type size() const
Definition: ossimString.h:405
void addExpTupleRight(int newdim, int totalOrder, EXPT_SET &eset) const
concatenate exponents (at the right) to existing tuple set, for a given maximum total order eg: with ...
Definition: ossimPolynom.h:569
unsigned int ossim_uint32
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
double height() const
Definition: ossimGpt.h:107
double toDouble() const
ossimPolynom< ossim_float64, 3 > thePolyLine_DLon
polynom partial derivatives
const vector< ossimRefPtr< ossimTieGpt > > & getTiePoints() const
void buildDerivatives()
protected methods
#define DBL_EPSILON
std::vector< ossimString > explode(const ossimString &delimeter) const
bool hasNans() const
Definition: ossimDpt.h:67
virtual void lineSampleToWorld(const ossimDpt &image_point, ossimGpt &world_point) const
ossimPolynom< ossim_float64, 3 > thePolyLine
ground (3d) to image(2D) polynoms
class for ground to image polynomial projection: (x,y,z)|->(x,y) polynom order is configurable ...
void getGroundBoundaries(ossimGpt &gBoundInf, ossimGpt &gBoundSup) const
int getExponent(ossimString &ts) const
ossimPolynom< ossim_float64, 3 > thePolySamp_DLon
storage class for a set of geographic tie points, between master and slave images ...
virtual ossimDpt getMetersPerPixel() const
double x
Definition: ossimDpt.h:164
int getSymbol(ossimString &ts, const ossimString &symbols) const
takes string of xyz monoms, x2z3
bool LMSfit(const EXPT_SET &expset, const std::vector< VAR_TUPLE > obs_input, const std::vector< T > obs_output, T *prms=NULL)
fits the polynom to the observations using Least Mean Squares returns true on success (can fail if no...
Definition: ossimPolynom.h:611
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
std::ostream & print(std::ostream &os) const
I/O.
Definition: ossimPolynom.h:370
virtual ossimGpt origin() const
void pdiff(int pdim, ossimPolynom &result) const
partial differentiation polynom
Definition: ossimPolynom.h:246
ossim_float64 lat
Definition: ossimGpt.h:265
virtual ossim_uint32 degreesOfFreedom() const
virtual double optimizeFit(const ossimTieGptSet &tieSet, double *targetVariance=NULL)
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
virtual bool operator==(const ossimProjection &projection) const
Basic operations.
ossimPolynomProjection()
Constructors.
virtual bool setupOptimizer(const ossimString &setup)
optimizableProjection implementation
RTTI_DEF2(ossimPolynomProjection, "ossimPolynomProjection", ossimProjection, ossimOptimizableProjection)
ossimPolynom< ossim_float64, 3 > thePolyLine_DLat
virtual void worldToLineSample(const ossimGpt &world_point, ossimDpt &image_point) const
Projection / localization methods.
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
void makeNan()
Definition: ossimDpt.h:65
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91