OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimQuadProjection.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // Author: Garrett Potts
6 //
7 //********************************************************************
8 // $Id: ossimQuadProjection.cpp 17206 2010-04-25 23:20:40Z dburken $
9 
12 #include <ossim/base/ossimGpt.h>
13 #include <ossim/base/ossimDpt.h>
16 #include <ossim/base/ossimDrect.h>
17 #include <ossim/base/ossimDatum.h>
20 
21 RTTI_DEF1(ossimQuadProjection, "ossimQuadProjection", ossimProjection);
22 
25 {
27  theUlg.makeNan();
28  theUrg.makeNan();
29  theLrg.makeNan();
30  theLlg.makeNan();
31 }
32 
34  :ossimProjection(rhs),
35  theInputRect(rhs.theInputRect),
36  theUlg(rhs.theUlg),
37  theUrg(rhs.theUrg),
38  theLrg(rhs.theLrg),
39  theLlg(rhs.theLlg),
40  theLatGrid(rhs.theLatGrid),
41  theLonGrid(rhs.theLonGrid)
42 {
43 }
44 
46  const ossimGpt& ulg,
47  const ossimGpt& urg,
48  const ossimGpt& lrg,
49  const ossimGpt& llg)
50  :theInputRect(rect),
51  theUlg(ulg),
52  theUrg(urg),
53  theLrg(lrg),
54  theLlg(llg)
55 {
57 }
58 
60 {
61 }
62 
64 {
65  return new ossimQuadProjection(*this);
66 }
67 
69 {
70  ossimGpt result;
71  result.makeNan();
72  if(theUlg.isLatNan()||
73  theUlg.isLonNan()||
74  theUrg.isLatNan()||
75  theUrg.isLonNan()||
76  theLrg.isLatNan()||
77  theLrg.isLonNan()||
78  theLlg.isLatNan()||
79  theLlg.isLonNan())
80  {
81  return result;
82  }
83 
84  result.latd( (theUlg.latd() + theUrg.latd() + theLrg.latd() + theLlg.latd())*.25);
85  result.lond( (theUlg.lond() + theUrg.lond() + theLrg.lond() + theLlg.lond())*.25);
86 
87  result.datum(theUlg.datum());
88 
89  return result;
90 }
91 
93  ossimDpt& lineSampPt) const
94 {
95  ossimProjection::worldToLineSample(worldPoint, lineSampPt);
96 }
97 
99  ossimGpt& worldPt) const
100 {
101  lineSampleHeightToWorld(lineSampPt,
102  ossim::nan(),
103  worldPt);
104 
105 }
106 
108  const double& heightAboveEllipsoid,
109  ossimGpt& worldPt) const
110 {
111  worldPt.makeNan();
112  worldPt.datum(theUlg.datum());
113 
114  if(theUlg.isLatNan()||
115  theUlg.isLonNan()||
116  theUrg.isLatNan()||
117  theUrg.isLonNan()||
118  theLrg.isLatNan()||
119  theLrg.isLonNan()||
120  theLlg.isLatNan()||
121  theLlg.isLonNan()||
123  {
124  return;
125  }
126 
127  if(!theInputRect.pointWithin(lineSampPt))
128  {
129  worldPt = extrapolate(lineSampPt,
130  heightAboveEllipsoid);
132  return;
133  }
134 
135  worldPt.lat = theLatGrid(lineSampPt);
136  worldPt.lon = theLonGrid(lineSampPt);
137  worldPt.hgt = heightAboveEllipsoid;
139 }
140 
142  const char* prefix)const
143 {
144  ossimProjection::saveState(kwl, prefix);
145  kwl.add(prefix,
147  theUlg.datum()->code(),
148  true);
149 
150  if(theInputRect.hasNans())
151  {
152  kwl.add(prefix,
154  "nan",
155  true);
156  kwl.add(prefix,
158  "nan",
159  true);
160  kwl.add(prefix,
161  "width",
162  0,
163  true);
164  kwl.add(prefix,
165  "height",
166  0,
167  true);
168  }
169  else
170  {
171  kwl.add(prefix,
173  theInputRect.ul().x,
174  true);
175  kwl.add(prefix,
177  theInputRect.ul().y,
178  true);
179  kwl.add(prefix,
180  "width",
182  true);
183  kwl.add(prefix,
184  "height",
186  true);
187  }
188 
189  if(theUlg.isLatNan()||
190  theUlg.isLonNan()||
191  theUrg.isLatNan()||
192  theUrg.isLonNan()||
193  theLrg.isLatNan()||
194  theLrg.isLonNan()||
195  theLlg.isLatNan()||
196  theLlg.isLonNan())
197  {
198  kwl.add(prefix,
200  "nan",
201  true);
202  kwl.add(prefix,
204  "nan",
205  true);
206  kwl.add(prefix,
208  "nan",
209  true);
210  kwl.add(prefix,
212  "nan",
213  true);
214  kwl.add(prefix,
216  "nan",
217  true);
218  kwl.add(prefix,
220  "nan",
221  true);
222  kwl.add(prefix,
224  "nan",
225  true);
226  kwl.add(prefix,
228  "nan",
229  true);
230  }
231  else
232  {
233  kwl.add(prefix,
235  theUlg.latd(),
236  true);
237  kwl.add(prefix,
239  theUlg.lond(),
240  true);
241  kwl.add(prefix,
243  theUrg.latd(),
244  true);
245  kwl.add(prefix,
247  theUrg.lond(),
248  true);
249  kwl.add(prefix,
251  theLrg.latd(),
252  true);
253  kwl.add(prefix,
255  theLrg.lond(),
256  true);
257  kwl.add(prefix,
259  theLlg.latd(),
260  true);
261  kwl.add(prefix,
263  theLlg.lond(),
264  true);
265  }
266  return true;
267 }
268 
270  const char* prefix)
271 {
272  ossimProjection::loadState(kwl, prefix);
273  theUlg.makeNan();
274  theUrg.makeNan();
275  theLrg.makeNan();
276  theLlg.makeNan();
278 
279  ossimString ulLat = kwl.find(prefix, ossimKeywordNames::UL_LAT_KW);
280  ossimString ulLon = kwl.find(prefix, ossimKeywordNames::UL_LON_KW);
281  ossimString urLat = kwl.find(prefix, ossimKeywordNames::UR_LAT_KW);
282  ossimString urLon = kwl.find(prefix, ossimKeywordNames::UR_LON_KW);
283  ossimString lrLat = kwl.find(prefix, ossimKeywordNames::LR_LAT_KW);
284  ossimString lrLon = kwl.find(prefix, ossimKeywordNames::LR_LON_KW);
285  ossimString llLat = kwl.find(prefix, ossimKeywordNames::LL_LAT_KW);
286  ossimString llLon = kwl.find(prefix, ossimKeywordNames::LL_LON_KW);
287  ossimString datum = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
288  ossimString ulX = kwl.find(prefix, ossimKeywordNames::UL_X_KW);
289  ossimString ulY = kwl.find(prefix, ossimKeywordNames::UL_Y_KW);
290  ossimString width = kwl.find(prefix, "width");
291  ossimString height = kwl.find(prefix, "height");
292 
293  if(ulLat == "nan")
294  {
296  }
297  else
298  {
299  theUlg.latd(ulLat.toDouble());
300  }
301  if(ulLon == "nan")
302  {
304  }
305  else
306  {
307  theUlg.lond(ulLon.toDouble());
308  }
309 
310  if(urLat == "nan")
311  {
313  }
314  else
315  {
316  theUrg.latd(urLat.toDouble());
317  }
318  if(urLon == "nan")
319  {
321  }
322  else
323  {
324  theUrg.lond(urLon.toDouble());
325  }
326 
327  if(lrLat == "nan")
328  {
330  }
331  else
332  {
333  theLrg.latd(lrLat.toDouble());
334  }
335  if(lrLon == "nan")
336  {
338  }
339  else
340  {
341  theLrg.lond(lrLon.toDouble());
342  }
343 
344  if(llLat == "nan")
345  {
347  }
348  else
349  {
350  theLlg.latd(llLat.toDouble());
351  }
352  if(llLon == "nan")
353  {
355  }
356  else
357  {
358  theLlg.lond(llLon.toDouble());
359  }
360 
361  ossimIpt ul;
362 
363  ul.makeNan();
364 
365  if((ulX != "nan") &&
366  (ulY != "nan"))
367  {
368  ul.x = ulX.toInt32();
369  ul.y = ulY.toInt32();
370  }
371  ossim_uint32 w = width.toUInt32();
372  ossim_uint32 h = height.toUInt32();
373  if(datum == "")
374  {
375  datum = "WGE";
376  }
377  const ossimDatum* datumPtr = ossimDatumFactory::instance()->create(datum);
378  theUlg.datum(datumPtr);
379  theUrg.datum(datumPtr);
380  theLrg.datum(datumPtr);
381  theLlg.datum(datumPtr);
382 
383  if(w&&h)
384  {
386  ul.y,
387  ul.x + w - 1,
388  ul.y + h - 1);
389  }
390  else
391  {
393  }
394 
395  initializeGrids();
396 
397  return true;
398 }
399 
400 bool ossimQuadProjection::operator==(const ossimProjection& /* projection */) const
401 {
402  return false;
403 }
404 
406 {
407  ossimGpt centerG;
408  ossimGpt rightG;
409  ossimGpt topG;
410 
414 
415  ossimEcefPoint centerP = centerG;
416  ossimEcefPoint rightP = rightG;
417  ossimEcefPoint topP = topG;
418 
419  ossimEcefVector horizontal = rightP-centerP;
420  ossimEcefVector vertical = topP-centerP;
421 
422  ossimDpt result(horizontal.magnitude(),
423  vertical.magnitude());
424 
425  result.x = (result.x + result.y)/2.0;
426  result.y = result.x;
427 
428 
429  return result;
430 }
431 
433 {
434  ossimIpt gridSize(2,2);
435 
436  ossimDpt spacing = ossimDpt((double)(theInputRect.width()-1)/(gridSize.x-1),
437  (double)(theInputRect.height()-1)/(gridSize.y-1));
438 
441  theLatGrid.initialize(gridSize, theInputRect.ul(), spacing);
442  theLonGrid.initialize(gridSize, theInputRect.ul(), spacing);
443 
444  theLatGrid.setNode(0,0, theUlg.latd());
445  theLatGrid.setNode(1,0, theUrg.latd());
446  theLatGrid.setNode(1,1, theLrg.latd());
447  theLatGrid.setNode(0,1, theLlg.latd());
448 
449  theLonGrid.setNode(0,0, theUlg.lond());
450  theLonGrid.setNode(1,0, theUrg.lond());
451  theLonGrid.setNode(1,1, theLrg.lond());
452  theLonGrid.setNode(0,1, theLlg.lond());
453 }
454 
456  const double& height) const
457 {
458  //---
459  // If image point supplied has NaN components, return now with a NaN point.
460  // This prevents an infinite recursion between model worldToLineSample
461  // and this method:
462  //---
463  if (imagePoint.hasNans())
464  {
465  return ossimGpt(ossim::nan(), ossim::nan(), ossim::nan());
466  }
467 
468  //***
469  // Determine which edge is intersected by the radial, and establish
470  // intersection:
471  //***
472  ossimGpt gpt;
473  ossimDpt edgePt (imagePoint);
474  ossimDpt image_center (theInputRect.midPoint());
475  ossimDrect clipRect = theInputRect;
476  clipRect.clip(image_center, edgePt);
477 
478  //***
479  // Need edgePt relative to image center. Compute an epsilon perturbation in
480  // the direction of edgePt for later computing directional derivative,
481  // and back out the offset to origin:
482  //***
483  ossimDpt deltaPt (edgePt - image_center);
484  ossimDpt epsilon (deltaPt/deltaPt.length());
485  edgePt -= epsilon; // insure that we are inside the image
486  ossimDpt edgePt_prime (edgePt - epsilon); // epsilon=1pixel
487 
488  //***
489  // Establish ground point corresponding to edge point and edgePt+epsilon:
490  //***
491  ossimGpt edgeGP;
492  ossimGpt edgeGP_prime;
493 
494  if (ossim::isnan(height))
495  {
496  lineSampleToWorld(edgePt, edgeGP);
497  lineSampleToWorld(edgePt_prime, edgeGP_prime);
498  }
499  else
500  {
501  lineSampleHeightToWorld(edgePt, height, edgeGP);
502  lineSampleHeightToWorld(edgePt_prime, height, edgeGP_prime);
503  }
504 
505  //***
506  // Compute approximate directional derivatives of lat and lon along radial
507  // at the edge:
508  //***
509  double dpixel = (edgePt-edgePt_prime).length();
510  double dlat_drad = (edgeGP.lat - edgeGP_prime.lat)/dpixel;
511  double dlon_drad = (edgeGP.lon - edgeGP_prime.lon)/dpixel;
512 
513  //***
514  // Now extrapolate to image point of interest:
515  //***
516  double delta_pixel = (imagePoint - edgePt).length();
517 
518  gpt.lat = edgeGP.lat + dlat_drad*delta_pixel;
519  gpt.lon = edgeGP.lon + dlon_drad*delta_pixel;
520 // if (height == OSSIM_DBL_NAN)
521 // {
522 // gpt.hgt = theElevation->getHeightAboveMSL(gpt);
523 // }
524 // else
525  gpt.hgt = height;
526 
527  return gpt;
528 
529 }
virtual const ossimDatum * create(const ossimString &code) const
create method
void makeNan()
Definition: ossimIpt.h:56
static const char * DATUM_KW
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
Represents serializable keyword/value map.
bool isLonNan() const
Definition: ossimGpt.h:140
static const char * UL_LAT_KW
virtual bool operator==(const ossimProjection &projection) const
const char * find(const char *key) const
virtual void worldToLineSample(const ossimGpt &worldPoint, ossimDpt &lineSampPt) const
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
ossim_uint32 height() const
Definition: ossimIrect.h:487
virtual const ossimString & code() const
Definition: ossimDatum.h:57
void makeNan()
Definition: ossimGpt.h:130
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual ossimDpt getMetersPerPixel() const
void setNullValue(double value)
Definition: ossimDblGrid.h:183
const ossimIpt & ul() const
Definition: ossimIrect.h:274
static const char * LR_LON_KW
double magnitude() const
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
ossim_uint32 toUInt32() const
static ossimElevManager * instance()
METHOD: instance() Implements singelton pattern.
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
bool isLatNan() const
Definition: ossimGpt.h:139
double length() const
Definition: ossimDpt.h:81
const ossimDatum * datum() const
datum().
Definition: ossimGpt.h:196
ossim_int32 toInt32() const
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
static const char * LR_LAT_KW
static const char * UL_X_KW
ossim_float64 lon
Definition: ossimGpt.h:266
static const char * LL_LON_KW
virtual double getHeightAboveEllipsoid(const ossimGpt &gpt)
ossimIpt midPoint() const
Definition: ossimIrect.h:750
unsigned int ossim_uint32
double toDouble() const
static ossimDatumFactory * instance()
static const char * LL_LAT_KW
virtual ossimObject * dup() const
static const char * UL_Y_KW
ossim_uint32 width() const
Definition: ossimIrect.h:500
bool hasNans() const
Definition: ossimDpt.h:67
virtual void lineSampleHeightToWorld(const ossimDpt &lineSampPt, const double &heightAboveEllipsoid, ossimGpt &worldPt) const
virtual ossimGpt origin() const
virtual void lineSampleToWorld(const ossimDpt &lineSampPt, ossimGpt &worldPt) const
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
ossim_int32 y
Definition: ossimIpt.h:142
void makeNan()
Definition: ossimIrect.h:329
double x
Definition: ossimDpt.h:164
static const char * UL_LON_KW
static const char * UR_LAT_KW
static const char * UR_LON_KW
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
bool hasNans() const
Definition: ossimIrect.h:337
ossim_int32 x
Definition: ossimIpt.h:141
ossim_float64 lat
Definition: ossimGpt.h:265
ossimGpt extrapolate(const ossimDpt &imagePoint, const double &height) const
RTTI_DEF1(ossimQuadProjection, "ossimQuadProjection", ossimProjection)
virtual void worldToLineSample(const ossimGpt &worldPoint, ossimDpt &lineSampPt) const =0
void setNode(const ossimIpt &p, const double &value)
Definition: ossimDblGrid.h:107
bool pointWithin(const ossimIpt &pt) const
Definition: ossimIrect.h:729
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91