OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimMapProjection.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 // Description:
8 //
9 // Base class for all map projections.
10 //
11 //*******************************************************************
12 // $Id: ossimMapProjection.cpp 23418 2015-07-09 18:46:41Z gpotts $
13 
14 #include <iostream>
15 #include <cstdlib>
16 #include <iomanip>
17 #include <sstream>
18 
24 #include <ossim/base/ossimDpt.h>
25 #include <ossim/base/ossimGpt.h>
26 #include <ossim/base/ossimDatum.h>
28 #include <ossim/base/ossimString.h>
33 #include <ossim/base/ossimTrace.h>
34 
35 static ossimTrace traceDebug("ossimMapProjection:debug");
36 
37 // RTTI information for the ossimMapProjection
38 RTTI_DEF1(ossimMapProjection, "ossimMapProjection" , ossimProjection);
39 
41  const ossimGpt& origin)
42  :theEllipsoid(ellipsoid),
43  theOrigin(origin),
44  theDatum(origin.datum()), // force no shifting
45  theUlGpt(0, 0),
46  theUlEastingNorthing(0, 0),
47  theFalseEastingNorthing(0, 0),
48  thePcsCode(0),
49  theElevationLookupFlag(false),
50  theModelTransform(),
51  theInverseModelTransform(),
52  theModelTransformUnitType(OSSIM_UNIT_UNKNOWN),
53  theProjectionUnits(OSSIM_METERS)
54 {
59 }
60 
62  : ossimProjection(src),
63  theEllipsoid(src.theEllipsoid),
64  theOrigin(src.theOrigin),
65  theDatum(src.theDatum),
66  theMetersPerPixel(src.theMetersPerPixel),
67  theDegreesPerPixel(src.theDegreesPerPixel),
68  theUlGpt(src.theUlGpt),
69  theUlEastingNorthing(src.theUlEastingNorthing),
70  theFalseEastingNorthing(src.theFalseEastingNorthing),
71  thePcsCode(src.thePcsCode),
72  theElevationLookupFlag(false),
73  theModelTransform(src.theModelTransform),
74  theInverseModelTransform(src.theInverseModelTransform),
75  theModelTransformUnitType(src.theModelTransformUnitType),
76  theProjectionUnits(src.theProjectionUnits)
77 {
78 }
79 
81 {
82 }
83 
85 {
86  return theOrigin;
87 }
88 
90 {
91  thePcsCode = pcsCode;
92 }
93 
95 {
96  // The PCS code is not always set when the projection is instantiated with explicit parameters,
97  // since the code is only necessary when looking up those parameters in a database. However, it
98  // is still necessary to recognize when an explicit projection coincides with an EPSG-specified
99  // projection, and assign our PCS code to match it. So let's take this opportunity now to make
100  // sure the PCS code is properly initialized.
101  if (thePcsCode == 0)
102  {
104  if (thePcsCode == 0)
105  thePcsCode = 32767; // user-defined (non-EPSG) projection
106  }
107 
108  if (thePcsCode == 32767)
109  return 0; // 32767 only used internally. To the rest of OSSIM, the PCS=0 is undefined
110 
111  return thePcsCode;
112 }
113 
115 {
116  return getClassName();
117 }
118 
120 {
121  return theEllipsoid.getA();
122 }
123 
125 {
126  return theEllipsoid.getB();
127 }
128 
130 {
131  return theEllipsoid.getFlattening();
132 }
133 
135 {
136  return theMetersPerPixel;
137 }
138 
140 {
141  return theDegreesPerPixel;
142 }
143 
145 {
146  return theUlEastingNorthing;
147 }
148 
150 {
151  return theUlGpt;
152 }
153 
155 {
156  return theOrigin;
157 }
158 
160 {
161  return theDatum;
162 }
163 
165 {
166  return false;
167 }
168 
170 {
171  theEllipsoid = ellipsoid; update();
172 }
173 
174 void ossimMapProjection::setAB(double a, double b)
175 {
177 }
178 
180 {
181 
182  if (!datum || (*theDatum == *datum))
183  return;
184 
185  theDatum = datum;
187 
188  // Change the datum of the ossimGpt data members:
191 
192  update();
193 
194  // A change of datum usually implies a change of EPSG codes. Reset the PCS code. It will be
195  // reestablished as needed in the getPcsCode() method:
196  thePcsCode = 0;
197 }
198 
200 {
201  // Set the origin and since the origin has a datum which in turn has
202  // an ellipsoid, sync them up.
203  // NOTE: Or perhaps we need to change the datum of the input origin to that of theDatum? (OLK 05/11)
204  theOrigin = origin;
206 
207  update();
208 }
209 
210 //*****************************************************************************
211 // METHOD: ossimMapProjection::assign
212 //
213 //*****************************************************************************
215 {
216  if(&aProjection!=this)
217  {
218  ossimKeywordlist kwl;
219 
220  aProjection.saveState(kwl);
221  loadState(kwl);
222  }
223 }
224 
225 //*****************************************************************************
226 // METHOD: ossimMapProjection::update
227 //
228 //*****************************************************************************
230 {
231  // if the delta lat and lon per pixel is set then
232  // check to see if the meters were set.
233  //
234  if( hasModelTransform() )
235  {
237  }
238  else if( theDegreesPerPixel.hasNans() == false )
239  {
241  {
243  }
244  }
245  else if(!theMetersPerPixel.hasNans())
246  {
248  }
249  // compute the tie points if not already computed
250  //
251  // The tiepoint was specified either as easting/northing or lat/lon. Need to initialize the one
252  // that has not been assigned yet:
255  else if (theUlGpt.hasNans() && !theUlEastingNorthing.hasNans())
258  {
261  }
262  if(theMetersPerPixel.hasNans() &&
264  {
266  if(isGeographic())
267  {
268  theDegreesPerPixel.lat = 1.0/mpd.y;
269  theDegreesPerPixel.lon = 1.0/mpd.x;
271  }
272  else
273  {
274  theMetersPerPixel.x = 1.0;
275  theMetersPerPixel.y = 1.0;
277  }
278  }
279 }
280 
282 {
283  if ( hasModelTransform() )
284  {
285  const NEWMAT::Matrix& m = theModelTransform.getData();
286  ossimDpt ls1(0, 0);
287  ossimDpt ls2(1, 0);
288  ossimDpt ls3(0, 1);
289  ossimGpt wpt1;
290  ossimGpt wpt2;
291  lineSampleToWorld(ls1, wpt1);
292  ossimDpt mpt1(m[0][0]*ls1.x + m[0][1]*ls1.y + m[0][3],
293  m[1][0]*ls1.x + m[1][1]*ls1.y + m[1][3]);
294  ossimDpt mpt2(m[0][0]*ls2.x + m[0][1]*ls2.y + m[0][3],
295  m[1][0]*ls2.x + m[1][1]*ls2.y + m[1][3]);
296  ossimDpt mpt3(m[0][0]*ls3.x + m[0][1]*ls3.y + m[0][3],
297  m[1][0]*ls3.x + m[1][1]*ls3.y + m[1][3]);
298 
299  double len = 1.0;
300  double len2 = 1.0;
302  {
303  case OSSIM_DEGREES:
304  case OSSIM_MINUTES:
305  case OSSIM_SECONDS:
306  case OSSIM_RADIANS:
307  {
309  len = (mpt1-mpt2).length();
310  len2 = (mpt1-mpt3).length();
311  ut.setValue((len+len2)*.5, theModelTransformUnitType);
312  len = ut.getValue(OSSIM_DEGREES);
313  theDegreesPerPixel = ossimDpt(len, len);
314  theUlGpt = wpt1;
316  break;
317  }
318  default:
319  {
321  len = (mpt1-mpt2).length();
322  len2 = (mpt1-mpt3).length();
324  mpt1.x = ut.getValue(OSSIM_METERS);
326  mpt1.y = ut.getValue(OSSIM_METERS);
327  ut.setValue((len+len2)*.5, theModelTransformUnitType);
328  len = ut.getValue(OSSIM_METERS);
329  theMetersPerPixel = ossimDpt(len, len);
330  theUlEastingNorthing = mpt1;
332  break;
333  }
334  }
335  theUlGpt = wpt1;
336  }
337 
338 }
339 
341  bool recenterTiePoint)
342 {
343  ossimDpt mapTieDpt;
344  ossimGpt mapTieGpt;
345  if (recenterTiePoint)
346  {
347  if (isGeographic())
348  {
349  mapTieGpt = getUlGpt();
350  mapTieGpt.lat += theDegreesPerPixel.lat/2.0;
351  mapTieGpt.lon -= theDegreesPerPixel.lon/2.0;
352  }
353  else
354  {
355  mapTieDpt = getUlEastingNorthing();
356  mapTieDpt.x -= theMetersPerPixel.x/2.0;
357  mapTieDpt.y += theMetersPerPixel.y/2.0;
358  }
359  }
360 
361  theDegreesPerPixel.x *= scale.x;
362  theDegreesPerPixel.y *= scale.y;
363  theMetersPerPixel.x *= scale.x;
364  theMetersPerPixel.y *= scale.y;
365 
366  if ( recenterTiePoint )
367  {
368  if (isGeographic())
369  {
370  mapTieGpt.lat -= theDegreesPerPixel.lat/2.0;
371  mapTieGpt.lon += theDegreesPerPixel.lon/2.0;
372  setUlTiePoints(mapTieGpt);
373  }
374  else
375  {
376  mapTieDpt.x += theMetersPerPixel.x/2.0;
377  mapTieDpt.y -= theMetersPerPixel.y/2.0;
378  setUlTiePoints(mapTieDpt);
379  }
380  }
381 
383  {
384  theModelTransform.getData()[0][0] = theModelTransform.getData()[0][0]*scale.x;
385  theModelTransform.getData()[1][1] = theModelTransform.getData()[1][1]*scale.y;
386 
389 
391  }
392 }
393 
394 
395 //*****************************************************************************
396 // METHOD: ossimMapProjection::worldToLineSample
397 //
398 //*****************************************************************************
400 {
401  ossimDpt result;
402 
403  worldToLineSample(worldPoint, result);
404 
405  return result;
406 }
407 
408 //*****************************************************************************
409 // METHOD: ossimMapProjection::lineSampleToWorld
410 //
411 //*****************************************************************************
413 {
414  ossimGpt result;
415 
416  lineSampleToWorld(lineSample, result);
417 
418  return result;
419 }
420 
421 //*****************************************************************************
422 // METHOD: ossimMapProjection::worldToLineSample
423 //
424 //*****************************************************************************
426  ossimDpt& lineSample)const
427 {
428 
430  {
431  ossimGpt gpt = worldPoint;
432  if(theDatum)
433  {
434  gpt.changeDatum(theDatum);
435  }
437  {
438  case OSSIM_METERS:
439  case OSSIM_FEET:
441  {
442  ossimDpt modelPoint = forward(gpt);
444  ut.setValue(modelPoint.x, OSSIM_METERS);
445  modelPoint.x = ut.getValue(theModelTransformUnitType);
446  ut.setValue(modelPoint.y, OSSIM_METERS);
447  modelPoint.y = ut.getValue(theModelTransformUnitType);
448  const NEWMAT::Matrix& m = theInverseModelTransform.getData();
449 
450  lineSample.x = m[0][0]*modelPoint.x + m[0][1]*modelPoint.y + m[0][3];
451  lineSample.y = m[1][0]*modelPoint.x + m[1][1]*modelPoint.y + m[1][3];
452 
453  return;
454  }
455  case OSSIM_DEGREES:
456  case OSSIM_RADIANS:
457  case OSSIM_MINUTES:
458  case OSSIM_SECONDS:
459  {
461  ossimDpt modelPoint;
462  modelPoint.lat = gpt.latd();
463  modelPoint.lon = gpt.lond();
464  ut.setValue(modelPoint.lat, OSSIM_DEGREES);
465  modelPoint.lat = ut.getValue(theModelTransformUnitType);
466  ut.setValue(modelPoint.lon, OSSIM_DEGREES);
467  modelPoint.lon = ut.getValue(theModelTransformUnitType);
468  const NEWMAT::Matrix& m = theInverseModelTransform.getData();
469 
470  lineSample.x = m[0][0]*modelPoint.x + m[0][1]*modelPoint.y + m[0][3];
471  lineSample.y = m[1][0]*modelPoint.x + m[1][1]*modelPoint.y + m[1][3];
472  return;
473  }
474  default:
475  {
476  lineSample.makeNan();
477  return;
478  }
479  }
480  }
481  else if(isGeographic())
482  {
483  ossimGpt gpt = worldPoint;
484 
485  if (theOrigin.datum() != gpt.datum())
486  {
487  // Apply datum shift if it's not the same.
488  gpt.changeDatum(theOrigin.datum());
489  }
490 
491  lineSample.line = (theUlGpt.latd() - gpt.latd()) / theDegreesPerPixel.y;
492  lineSample.samp = (gpt.lond() - theUlGpt.lond()) / theDegreesPerPixel.x;
493  }
494  else
495  {
496  // make sure our tie point is good and world point
497  // is good.
498  //
500  worldPoint.isLatNan() || worldPoint.isLonNan())
501  {
502  lineSample.makeNan();
503  return;
504  }
505  // initialize line sample
506  // lineSample = ossimDpt(0,0);
507 
508  // I am commenting this code out because I am going to
509  // move it to the ossimImageViewProjectionTransform.
510  //
511  // see if we have a datum set and if so
512  // shift the world to our datum. If not then
513  // find the easting northing value for the world
514  // point.
515  if(theDatum)
516  {
517  ossimGpt gpt = worldPoint;
518 
519  gpt.changeDatum(theDatum);
520 
521  // lineSample is currently in easting northing
522  // and will need to be converted to line sample.
523  lineSample = forward(gpt);
524  }
525  else
526  {
527  // lineSample is currently in easting northing
528  // and will need to be converted to line sample.
529  lineSample = forward(worldPoint);
530  }
531 
532  // check the final result to make sure there were no
533  // problems.
534  //
535  if(!lineSample.isNan())
536  {
537 // if(!isIdentityMatrix())
538 // {
539 // ossimDpt temp = lineSample;
540 
541 // lineSample.x = theInverseTrans[0][0]*temp.x+
542 // theInverseTrans[0][1]*temp.y+
543 // theInverseTrans[0][2];
544 
545 // lineSample.y = theInverseTrans[1][0]*temp.x+
546 // theInverseTrans[1][1]*temp.y+
547 // theInverseTrans[1][2];
548 // }
549 // else
550  {
551  lineSample.x = ((lineSample.x - theUlEastingNorthing.x)/theMetersPerPixel.x);
552 
553  // We must remember that the Northing is negative since the positive
554  // axis for an image is assumed to go down since it's image space.
555  lineSample.y = (-(lineSample.y - theUlEastingNorthing.y)/theMetersPerPixel.y);
556  }
557  }
558  }
559 }
560 
561 //*****************************************************************************
562 // METHOD: ossimMapProjection::lineSampleHeightToWorld
563 //
564 //*****************************************************************************
566  const double& hgtEllipsoid,
567  ossimGpt& gpt)const
568 {
569  // make sure that the passed in lineSample is good and
570  // check to make sure our easting northing is good so
571  // we can compute the line sample.
572  if(lineSample.hasNans())
573  {
574  gpt.makeNan();
575  return;
576  }
578  {
579  const NEWMAT::Matrix& m = theModelTransform.getData();
580  // map transforms can only be 2-D for now so we will look at
581  // the first 2 rows only
582  ossimDpt modelPoint(m[0][0]*lineSample.x + m[0][1]*lineSample.y + m[0][3],
583  m[1][0]*lineSample.x + m[1][1]*lineSample.y + m[1][3]);
585  {
586  case OSSIM_DEGREES:
587  {
588  gpt.latd(modelPoint.lat);
589  gpt.lond(modelPoint.lon);
590  gpt.datum(theDatum);
591  return;
592  }
593  case OSSIM_MINUTES:
594  case OSSIM_SECONDS:
595  case OSSIM_RADIANS:
596  {
598  ut.setValue(modelPoint.x, theModelTransformUnitType);
599  modelPoint.x = ut.getValue(OSSIM_DEGREES);
600  ut.setValue(modelPoint.y, theModelTransformUnitType);
601  modelPoint.y = ut.getValue(OSSIM_DEGREES);
602  gpt.latd(modelPoint.lat);
603  gpt.lond(modelPoint.lon);
604  gpt.datum(theDatum);
605  return;
606  }
607  default:
608  {
610  ut.setValue(modelPoint.x, theModelTransformUnitType);
611  modelPoint.x = ut.getValue(OSSIM_METERS);
612  ut.setValue(modelPoint.y, theModelTransformUnitType);
613  modelPoint.y = ut.getValue(OSSIM_METERS);
614  gpt = inverse(modelPoint);
615  break;
616  }
617  }
618  gpt.datum(theDatum);
619  }
620  else if(isGeographic())
621  {
622  double lat = theUlGpt.latd() - (lineSample.line * theDegreesPerPixel.y);
623  double lon = theUlGpt.lond() + (lineSample.samp * theDegreesPerPixel.x);
624 
625  gpt.latd(lat);
626  gpt.lond(lon);
627  gpt.hgt = hgtEllipsoid;
628  }
629  else
630  {
632  {
633  gpt.makeNan();
634  return;
635  }
636  ossimDpt eastingNorthing;
637 
638  eastingNorthing = (theUlEastingNorthing);
639 
640  eastingNorthing.x += (lineSample.x*theMetersPerPixel.x);
641 
642  //
643  // Note: the Northing is positive up. In image space
644  // the positive axis is down so we must multiply by
645  // -1
646  //
647  eastingNorthing.y += (-lineSample.y*theMetersPerPixel.y);
648 
649 
650  //
651  // now invert the meters into a ground point.
652  //
653  gpt = inverse(eastingNorthing);
654  gpt.datum(theDatum);
655 
656  if(gpt.isLatNan() && gpt.isLonNan())
657  {
658  gpt.makeNan();
659  }
660  else
661  {
662  gpt.clampLat(-90, 90);
663  gpt.clampLon(-180, 180);
664 
665  // Finally assign the specified height:
666  gpt.hgt = hgtEllipsoid;
667  }
668  }
670  {
672  }
673 }
674 
675 //*****************************************************************************
676 // METHOD: ossimMapProjection::lineSampleToWorld
677 //
678 // Implements the base class pure virtual. Simply calls lineSampleToWorld()
679 // and assigns argument height to the resultant groundpoint.
680 //
681 //*****************************************************************************
683  ossimGpt& worldPt) const
684 {
685  double elev = ossim::nan();
686 
687 // if(theElevationLookupFlag)
688 // {
689 // elev = ossimElevManager::instance()->getHeightAboveEllipsoid(worldPt);
690 // }
691 
692  lineSampleHeightToWorld(lineSampPt, elev, worldPt);
693 
694 }
695 
696 //*****************************************************************************
697 // METHOD: ossimMapProjection::lineSampleToEastingNorthing
698 //
699 //*****************************************************************************
701  ossimDpt& eastingNorthing)const
702 {
703  // make sure that the passed in lineSample is good and
704  // check to make sure our easting northing is good so
705  // we can compute the line sample.
706  //
707  if(lineSample.hasNans()||theUlEastingNorthing.hasNans())
708  {
709  eastingNorthing.makeNan();
710  return;
711  }
712  ossimDpt deltaPoint = lineSample;
713 
714  eastingNorthing.x = theUlEastingNorthing.x + deltaPoint.x*theMetersPerPixel.x;
715  eastingNorthing.y = theUlEastingNorthing.y + (-deltaPoint.y)*theMetersPerPixel.y ;
716 
717  // eastingNorthing.x += (lineSample.x*theMetersPerPixel.x);
718 
719  // Note: the Northing is positive up. In image space
720  // the positive axis is down so we must multiply by
721  // -1
722  // eastingNorthing.y += (-lineSample.y*theMetersPerPixel.y);
723 }
724 
725 
727 {
728  theMetersPerPixel = resolution;
730 }
731 
733 {
734  theDegreesPerPixel = resolution;
736 }
737 
739  ossimGpt& worldPt)const
740 {
741  ossimDpt lineSample;
742  eastingNorthingToLineSample(eastingNorthing, lineSample);
743  lineSampleToWorld(lineSample, worldPt);
744 }
745 
746 
747 //*****************************************************************************
748 // METHOD: ossimMapProjection::eastingNorthingToLineSample
749 //
750 //*****************************************************************************
752  ossimDpt& lineSample)const
753 {
754  if(eastingNorthing.hasNans())
755  {
756  lineSample.makeNan();
757  return;
758  }
759  // check the final result to make sure there were no
760  // problems.
761  //
762  if(!eastingNorthing.isNan())
763  {
764  lineSample.x = (eastingNorthing.x - theUlEastingNorthing.x)/theMetersPerPixel.x;
765 
766  // We must remember that the Northing is negative since the positive
767  // axis for an image is assumed to go down since it's image space.
768  lineSample.y = (-(eastingNorthing.y-theUlEastingNorthing.y))/theMetersPerPixel.y;
769  }
770 }
771 
773 {
774  setUlGpt(gpt);
776 }
777 
778 void ossimMapProjection::setUlTiePoints(const ossimDpt& eastingNorthing)
779 {
780  setUlEastingNorthing(eastingNorthing);
781  setUlGpt(inverse(eastingNorthing));
782 }
783 
784 
785 //*****************************************************************************
786 // METHOD: ossimMapProjection::setUlEastingNorthing
787 //
788 //*****************************************************************************
790 {
791  theUlEastingNorthing = ulEastingNorthing;
792 }
793 
794 //*****************************************************************************
795 // METHOD: ossimMapProjection::setUlGpt
796 //
797 //*****************************************************************************
799 {
800  theUlGpt = ulGpt;
801 
802  // The ossimGpt data members need to use the same datum as this projection:
803  if (*theDatum != *(ulGpt.datum()))
805 }
806 
807 //*****************************************************************************
808 // METHOD: ossimMapProjection::saveState
809 //
810 //*****************************************************************************
811 bool ossimMapProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
812 {
813  ossimProjection::saveState(kwl, prefix);
814 
815  kwl.add(prefix,
817  theOrigin.latd(),
818  true);
819 
820  kwl.add(prefix,
822  theOrigin.lond(),
823  true);
824 
825  theEllipsoid.saveState(kwl, prefix);
826 
827  if(theDatum)
828  {
829  kwl.add(prefix,
831  theDatum->code(),
832  true);
833  }
834 
835  // Calling access method to give it an opportunity to update the code in case of param change:
836  ossim_uint32 code = getPcsCode();
837  if (code)
838  {
839  ossimString epsg_spec = ossimString("EPSG:") + ossimString::toString(code);
840  kwl.add(prefix, ossimKeywordNames::SRS_NAME_KW, epsg_spec, true);
841  }
842 
843  if(isGeographic())
844  {
845  kwl.add(prefix,
847  ossimDpt(theUlGpt).toString().c_str(),
848  true);
849  kwl.add(prefix,
851  ossimUnitTypeLut::instance()->getEntryString(OSSIM_DEGREES),
852  true);
853  kwl.add(prefix,
856  true);
857  kwl.add(prefix,
859  ossimUnitTypeLut::instance()->getEntryString(OSSIM_DEGREES),
860  true);
861  }
862  else
863  {
864  kwl.add(prefix,
867  true);
868  kwl.add(prefix,
870  ossimUnitTypeLut::instance()->getEntryString(OSSIM_METERS),
871  true);
872  kwl.add(prefix,
875  true);
876  kwl.add(prefix,
878  ossimUnitTypeLut::instance()->getEntryString(OSSIM_METERS),
879  true);
880  kwl.add(prefix,
883  true);
884  }
885 
886  kwl.add(prefix, ossimKeywordNames::PCS_CODE_KW, code, true);
890  ossimUnitTypeLut::instance()->getEntryString(OSSIM_METERS), true);
893 
895  {
896  const NEWMAT::Matrix& m = theModelTransform.getData();
897  ostringstream out;
898  ossim_uint32 row, col;
899  for(row = 0; row < 4; ++row)
900  {
901  for(col = 0; col < 4; ++col)
902  {
903  out << std::setprecision(20) << m[row][col] << " ";
904  }
905  }
906  kwl.add(prefix,
908  out.str().c_str(),
909  true);
910  kwl.add(prefix,
913  true);
914  }
915 
916  return true;
917 }
918 
919 //*****************************************************************************
920 // METHOD: ossimMapProjection::loadState
921 //
922 //*****************************************************************************
923 bool ossimMapProjection::loadState(const ossimKeywordlist& kwl, const char* prefix)
924 {
925  ossimProjection::loadState(kwl, prefix);
926 
927  const char* elevLookupFlag = kwl.find(prefix, ossimKeywordNames::ELEVATION_LOOKUP_FLAG_KW);
928  if(elevLookupFlag)
929  {
930  theElevationLookupFlag = ossimString(elevLookupFlag).toBool();
931  }
932  // Get the ellipsoid.
933  theEllipsoid.loadState(kwl, prefix);
934 
935  const char *lookup;
936 
937  // Get the Projection Coordinate System (assumed from EPSG database).
938  // NOTE: the code is read here for saving in this object only.
939  // The code is not verified until a call to getPcs() is called. If ONLY this code
940  // had been provided, then the EPSG projection factory would populate a new instance of the
941  // corresponding map projection and have it saveState for constructing again later in the
942  // conventional fashion here
943  thePcsCode = 0;
944  lookup = kwl.find(prefix, ossimKeywordNames::PCS_CODE_KW);
945  if(lookup)
946  thePcsCode = ossimString(lookup).toUInt32(); // EPSG PROJECTION CODE
947 
948  // The datum can be specified in 2 ways: either via OSSIM/geotrans alpha-codes or EPSG code.
949  // Last resort use WGS 84 (consider throwing an exception to catch any bad datums):
951  if (theDatum == NULL)
952  {
954  }
955 
956  // Set all ossimGpt-type members to use this datum:
959 
960  // Fetch the ellipsoid from the datum:
961  const ossimEllipsoid* ellipse = theDatum->ellipsoid();
962  if(ellipse)
963  theEllipsoid = *ellipse;
964 
965  // Get the latitude of the origin.
966  lookup = kwl.find(prefix, ossimKeywordNames::ORIGIN_LATITUDE_KW);
967  if (lookup)
968  {
969  theOrigin.latd(ossimString(lookup).toFloat64());
970  }
971  // else ???
972 
973  // Get the central meridian.
974  lookup = kwl.find(prefix, ossimKeywordNames::CENTRAL_MERIDIAN_KW);
975  if (lookup)
976  {
977  theOrigin.lond(ossimString(lookup).toFloat64());
978  }
979  // else ???
980 
981 
982  // Get the pixel scale.
985  lookup = kwl.find(prefix, ossimKeywordNames::PIXEL_SCALE_UNITS_KW);
986  if (lookup)
987  {
988  ossimUnitType units =
990  getEntryNumber(lookup));
991 
992  lookup = kwl.find(prefix, ossimKeywordNames::PIXEL_SCALE_XY_KW);
993  if (lookup)
994  {
995  ossimDpt scale;
996  scale.toPoint(std::string(lookup));
997 
998  switch (units)
999  {
1000  case OSSIM_METERS:
1001  {
1002  theMetersPerPixel = scale;
1003  break;
1004  }
1005  case OSSIM_DEGREES:
1006  {
1007  theDegreesPerPixel.x = scale.x;
1008  theDegreesPerPixel.y = scale.y;
1009  break;
1010  }
1011  case OSSIM_FEET:
1012  case OSSIM_US_SURVEY_FEET:
1013  {
1015  ut.setValue(scale.x, units);
1017  ut.setValue(scale.y, units);
1019  break;
1020  }
1021  default:
1022  {
1023  if(traceDebug())
1024  {
1025  // Unhandled unit type!
1027  << "ossimMapProjection::loadState WARNING!"
1028  << "Unhandled unit type for "
1031  getEntryString(units).c_str() )
1032  << endl;
1033  }
1034  break;
1035  }
1036  } // End of switch (units)
1037 
1038  } // End of if (PIXEL_SCALE_XY)
1039 
1040  } // End of if (PIXEL_SCALE_UNITS)
1041  else
1042  {
1043  // BACKWARDS COMPATIBILITY LOOKUPS...
1044  lookup = kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_X_KW);
1045  if(lookup)
1046  {
1047  theMetersPerPixel.x = fabs(ossimString(lookup).toFloat64());
1048  }
1049 
1050  lookup = kwl.find(prefix, ossimKeywordNames::METERS_PER_PIXEL_Y_KW);
1051  if(lookup)
1052  {
1053  theMetersPerPixel.y = fabs(ossimString(lookup).toFloat64());
1054  }
1055 
1056  lookup = kwl.find(prefix,
1058  if(lookup)
1059  {
1060  theDegreesPerPixel.y = fabs(ossimString(lookup).toFloat64());
1061  }
1062 
1063  lookup = kwl.find(prefix,
1065  if(lookup)
1066  {
1067  theDegreesPerPixel.x = fabs(ossimString(lookup).toFloat64());
1068  }
1069  }
1070 
1071  // Get the tie point.
1072  theUlGpt.makeNan();
1073 
1074  // Since this won't be picked up from keywords set to 0 to keep nan out.
1075  theUlGpt.hgt = 0.0;
1076 
1078  lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_UNITS_KW);
1079  if (lookup)
1080  {
1081  ossimUnitType units = static_cast<ossimUnitType>(ossimUnitTypeLut::instance()->
1082  getEntryNumber(lookup));
1083 
1084  lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_XY_KW);
1085  if (lookup)
1086  {
1087  ossimDpt tie;
1088  tie.toPoint(std::string(lookup));
1089 
1090  switch (units)
1091  {
1092  case OSSIM_METERS:
1093  {
1094  theUlEastingNorthing = tie;
1095  break;
1096  }
1097  case OSSIM_DEGREES:
1098  {
1099  theUlGpt.lond(tie.x);
1100  theUlGpt.latd(tie.y);
1101  break;
1102  }
1103  case OSSIM_FEET:
1104  case OSSIM_US_SURVEY_FEET:
1105  {
1107  ut.setValue(tie.x, units);
1109  ut.setValue(tie.y, units);
1111  break;
1112  }
1113  default:
1114  {
1115  if(traceDebug())
1116  {
1117  // Unhandled unit type!
1119  << "ossimMapProjection::loadState WARNING!"
1120  << "Unhandled unit type for "
1123  getEntryString(units).c_str() )
1124  << endl;
1125  }
1126  break;
1127  }
1128  } // End of switch (units)
1129 
1130  } // End of if (TIE_POINT_XY)
1131 
1132  } // End of if (TIE_POINT_UNITS)
1133  else
1134  {
1135  // BACKWARDS COMPATIBILITY LOOKUPS...
1136  lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_EASTING_KW);
1137  if(lookup)
1138  {
1140  }
1141 
1142  lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_NORTHING_KW);
1143  if(lookup)
1144  {
1146  }
1147 
1148  lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LAT_KW);
1149  if (lookup)
1150  {
1151  theUlGpt.latd(ossimString(lookup).toFloat64());
1152  }
1153 
1154  lookup = kwl.find(prefix, ossimKeywordNames::TIE_POINT_LON_KW);
1155  if (lookup)
1156  {
1157  theUlGpt.lond(ossimString(lookup).toFloat64());
1158  }
1159  }
1160 
1161  // Get the false easting northing.
1162  theFalseEastingNorthing.x = 0.0;
1163  theFalseEastingNorthing.y = 0.0;
1164  ossimUnitType en_units = OSSIM_METERS;
1166  if (lookup)
1167  {
1168  en_units = static_cast<ossimUnitType>(ossimUnitTypeLut::instance()->getEntryNumber(lookup));
1169  }
1170 
1171  lookup = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_NORTHING_KW);
1172  if (lookup)
1173  {
1174  ossimDpt eastingNorthing;
1175  eastingNorthing.toPoint(std::string(lookup));
1176 
1177  switch (en_units)
1178  {
1179  case OSSIM_METERS:
1180  {
1181  theFalseEastingNorthing = eastingNorthing;
1182  break;
1183  }
1184  case OSSIM_FEET:
1185  case OSSIM_US_SURVEY_FEET:
1186  {
1188  ut.setValue(eastingNorthing.x, en_units);
1190  ut.setValue(eastingNorthing.y, en_units);
1192  break;
1193  }
1194  default:
1195  {
1196  if(traceDebug())
1197  {
1198  // Unhandled unit type!
1200  << "ossimMapProjection::loadState WARNING! Unhandled unit type for "
1202  << (ossimUnitTypeLut::instance()->getEntryString(en_units).c_str())
1203  << endl;
1204  }
1205  break;
1206  }
1207  } // End of switch (units)
1208  } // End of if (FALSE_EASTING_NORTHING_KW)
1209  else
1210  {
1211  // BACKWARDS COMPATIBILITY LOOKUPS...
1212  lookup = kwl.find(prefix, ossimKeywordNames::FALSE_EASTING_KW);
1213  if(lookup)
1214  {
1216  }
1217 
1218  lookup = kwl.find(prefix, ossimKeywordNames::FALSE_NORTHING_KW);
1219  if(lookup)
1220  {
1222  }
1223  }
1224 
1225 // if((theDegreesPerPixel.x!=OSSIM_DBL_NAN)&&
1226 // (theDegreesPerPixel.y!=OSSIM_DBL_NAN)&&
1227 // theMetersPerPixel.hasNans())
1228 // {
1229 // theMetersPerPixel = theOrigin.metersPerDegree();
1230 // theMetersPerPixel.x *= theDegreesPerPixel.x;
1231 // theMetersPerPixel.y *= theDegreesPerPixel.y;
1232 // }
1233 
1234  lookup = kwl.find(prefix, ossimKeywordNames::PIXEL_TYPE_KW);
1235  if (lookup)
1236  {
1237  ossimString pixelType = lookup;
1238  pixelType=pixelType.trim();
1239  if(pixelType!="")
1240  {
1241  pixelType.downcase();
1242  if(pixelType.contains("area"))
1243  {
1244  if( theMetersPerPixel.hasNans() == false)
1245  {
1247  {
1250  }
1251  }
1252  if(theDegreesPerPixel.hasNans() == false)
1253  {
1256  }
1257  }
1258  }
1259  }
1260 
1261  // We preserve the units of the originally created projection (typically from EPSG proj factory)
1262  // in case user needs map coordinates in those units (versus default meters)
1263  lookup = kwl.find(prefix, ossimKeywordNames::ORIGINAL_MAP_UNITS_KW);
1264  if (lookup)
1265  {
1267  getEntryNumber(lookup));
1268  }
1269 
1271  const char* modelTransform = kwl.find(prefix, ossimKeywordNames::IMAGE_MODEL_TRANSFORM_MATRIX_KW);
1272  const char* modelTransformUnit = kwl.find(prefix, ossimKeywordNames::IMAGE_MODEL_TRANSFORM_UNIT_KW);
1273  if(modelTransform&&modelTransformUnit) // row ordered 4x4 matrix. Should be 16 values
1274  {
1275 
1276  NEWMAT::Matrix& m = theModelTransform.getData();
1277  istringstream in(modelTransform);
1278  ossim_uint32 row, col;
1279  ossimString value;
1280  for(row = 0; row < 4; ++row)
1281  {
1282  for(col = 0; col < 4; ++col)
1283  {
1284  in >> value;
1285  m[row][col] = value.toDouble();
1286  }
1287  }
1288  // make sure these have the identity and all unused are 0.0
1289  m[2][2] = 1.0;
1290  m[2][0] = 0.0;
1291  m[2][1] = 0.0;
1292  m[2][3] = 0.0;
1293  m[3][3] = 1.0;
1294  m[3][2] = 0.0;
1295  m[3][1] = 0.0;
1296  m[3][0] = 0.0;
1297 
1298  if(!in.fail())
1299  {
1300  try
1301  {
1305  getEntryNumber(modelTransformUnit));
1306  }
1307  catch(...)
1308  {
1310  }
1311  }
1312  }
1313 
1314  //---
1315  // Set the datum of the origin and tie point.
1316  // Use method that does NOT perform a shift.
1317  //---
1318  if(theDatum)
1319  {
1322  }
1323 
1324  if(theMetersPerPixel.hasNans() &&
1326  {
1327  ossimDpt mpd = ossimGpt().metersPerDegree();
1328  if(isGeographic())
1329  {
1330  theDegreesPerPixel.lat = 1.0/mpd.y;
1331  theDegreesPerPixel.lon = 1.0/mpd.y;
1332  }
1333  else
1334  {
1335  theMetersPerPixel.x = 1.0;
1336  theMetersPerPixel.y = 1.0;
1337  }
1338  }
1339 
1340  //---
1341  // Final sanity check:
1342  //---
1343  if ( theOrigin.hasNans() )
1344  {
1346  {
1347  const NEWMAT::Matrix& m = theModelTransform.getData();
1348  theOrigin.lon = m[0][3];
1349  theOrigin.lat = m[1][3];
1350  }
1351  else
1352  {
1354  << __FILE__ << ": " << __LINE__
1355  << "\nossimMapProjection::loadState ERROR: Origin is not set!"
1356  << std::endl;
1357  }
1358  }
1359 
1360  return true;
1361 }
1362 
1363 //*****************************************************************************
1364 // METHOD: ossimMapProjection::print
1365 //*****************************************************************************
1367 {
1368  const char MODULE[] = "ossimMapProjection::print";
1369 
1370  out << setiosflags(ios::fixed) << setprecision(15)
1371  << "\n// " << MODULE
1372  << "\n" << ossimKeywordNames::TYPE_KW << ": "
1373  << getClassName()
1374  << "\n" << ossimKeywordNames::MAJOR_AXIS_KW << ": "
1375  << theEllipsoid.getA()
1376  << "\n" << ossimKeywordNames::MINOR_AXIS_KW << ": "
1377  << theEllipsoid.getB()
1378  << "\n" << ossimKeywordNames::ORIGIN_LATITUDE_KW << ": "
1379  << theOrigin.latd()
1380  << "\n" << ossimKeywordNames::CENTRAL_MERIDIAN_KW << ": "
1381  << theOrigin.lond()
1382  << "\norigin: " << theOrigin
1383  << "\n" << ossimKeywordNames::DATUM_KW << ": "
1384  << (theDatum?theDatum->code().c_str():"unknown")
1385  << "\n" << ossimKeywordNames::METERS_PER_PIXEL_X_KW << ": "
1387  << "\n" << ossimKeywordNames::METERS_PER_PIXEL_Y_KW << ": "
1393  << "\n" << ossimKeywordNames::PCS_CODE_KW << ": " << thePcsCode;
1394 
1395  if(isGeographic())
1396  {
1397  out << "\n" << ossimKeywordNames::TIE_POINT_XY_KW << ": "
1399  << "\n" << ossimKeywordNames::TIE_POINT_UNITS_KW << ": "
1401  << "\n" << ossimKeywordNames::PIXEL_SCALE_XY_KW << ": "
1403  << "\n" << ossimKeywordNames::PIXEL_SCALE_UNITS_KW << ": "
1405  << std::endl;
1406  }
1407  else
1408  {
1409  out << "\n" << ossimKeywordNames::TIE_POINT_XY_KW << ": "
1411  << "\n" << ossimKeywordNames::TIE_POINT_UNITS_KW << ": "
1413  << "\n" << ossimKeywordNames::PIXEL_SCALE_XY_KW << ": "
1415  << "\n" << ossimKeywordNames::PIXEL_SCALE_UNITS_KW << ": "
1417  << std::endl;
1418  }
1419 
1420  return ossimProjection::print(out);
1421 }
1422 
1423 //*****************************************************************************
1424 // METHOD: ossimMapProjection::computeDegreesPerPixel
1425 //
1426 //*****************************************************************************
1428 {
1429  ossimDpt eastNorthGround = forward(theOrigin);
1430  ossimDpt rightEastNorth = eastNorthGround;
1431  ossimDpt downEastNorth = eastNorthGround;
1432  rightEastNorth.x += theMetersPerPixel.x;
1433  downEastNorth.y -= theMetersPerPixel.y;
1434 
1435  ossimGpt rightGpt = inverse(rightEastNorth);
1436  ossimGpt downGpt = inverse(downEastNorth);
1437 
1438  // use euclidean distance to get length along the horizontal (lon)
1439  // and vertical (lat) directions
1440  //
1441  double tempDeltaLat = rightGpt.latd() - theOrigin.latd();
1442  double tempDeltaLon = rightGpt.lond() - theOrigin.lond();
1443  theDegreesPerPixel.lon = sqrt(tempDeltaLat*tempDeltaLat + tempDeltaLon*tempDeltaLon);
1444 
1445  tempDeltaLat = downGpt.latd() - theOrigin.latd();
1446  tempDeltaLon = downGpt.lond() - theOrigin.lond();
1447  theDegreesPerPixel.lat = sqrt(tempDeltaLat*tempDeltaLat + tempDeltaLon*tempDeltaLon);
1448 }
1449 
1450 //*****************************************************************************
1451 // METHOD: ossimMapProjection::computeMetersPerPixel
1452 //
1453 //*****************************************************************************
1455 {
1456 //#define USE_OSSIMGPT_METERS_PER_DEGREE
1457 #ifdef USE_OSSIMGPT_METERS_PER_DEGREE
1458  ossimDpt metersPerDegree (theOrigin.metersPerDegree());
1459  theMetersPerPixel.x = metersPerDegree.x * theDegreesPerPixel.lon;
1460  theMetersPerPixel.y = metersPerDegree.y * theDegreesPerPixel.lat;
1461 #else
1462  ossimGpt right=theOrigin;
1463  ossimGpt down=theOrigin;
1464 
1467 
1468  ossimDpt centerMeters = forward(theOrigin);
1469  ossimDpt rightMeters = forward(right);
1470  ossimDpt downMeters = forward(down);
1471 
1472  theMetersPerPixel.x = (rightMeters - centerMeters).length();
1473  theMetersPerPixel.y = (downMeters - centerMeters).length();
1474 #endif
1475 }
1476 
1477 //**************************************************************************************************
1478 // METHOD: ossimMapProjection::operator==
1483 //**************************************************************************************************
1485 {
1486  // Verify that derived types match:
1487  if (getClassName() != projection.getClassName())
1488  return false;
1489 
1490  // If both PCS codes are non-zero, that's all we need to check:
1491  const ossimMapProjection* mapProj = dynamic_cast<const ossimMapProjection*>(&projection);
1492  if (thePcsCode && mapProj->thePcsCode && (thePcsCode != 32767) &&
1493  (thePcsCode == mapProj->thePcsCode) )
1494  {
1495  return true;
1496  }
1497 
1498  if ( *theDatum != *(mapProj->theDatum) )
1499  return false;
1500 
1501  if (theOrigin != mapProj->theOrigin)
1502  return false;
1503 
1505  return false;
1506 
1507 #if 0
1508  THIS SECTION IGNORED SINCE IT DEALS WITH IMAGE GEOMETRY, NOT MAP PROJECTION
1509  if (isGeographic())
1510  {
1511  if ((theDegreesPerPixel != mapProj->theDegreesPerPixel) ||
1512  (theUlGpt != mapProj->theUlGpt))
1513  return false;
1514  }
1515  else
1516  {
1517  if ((theMetersPerPixel != mapProj->theMetersPerPixel) ||
1519  return false;
1520  }
1521 #endif
1522 
1523  // Units must match:
1525  (mapProj->theProjectionUnits != OSSIM_UNIT_UNKNOWN) &&
1526  (theProjectionUnits != mapProj->theProjectionUnits))
1527  return false;
1528 
1529  // Check transform if present and compare it also:
1530  if (hasModelTransform() && mapProj->hasModelTransform() &&
1532  return false;
1533 
1534  return true;
1535 }
1536 
1538 {
1539  const ossimMapProjection* mapProj = dynamic_cast<const ossimMapProjection*>(&obj);
1540  bool result = mapProj&&ossimProjection::isEqualTo(obj, compareType);
1541 
1542  if(result)
1543  {
1544  result = (theEllipsoid.isEqualTo(mapProj->theEllipsoid, compareType)&&
1545  theOrigin.isEqualTo(mapProj->theOrigin, compareType)&&
1546  theMetersPerPixel.isEqualTo(mapProj->theMetersPerPixel, compareType)&&
1547  theDegreesPerPixel.isEqualTo(mapProj->theDegreesPerPixel, compareType)&&
1548  theUlGpt.isEqualTo(mapProj->theUlGpt, compareType)&&
1549  theUlEastingNorthing.isEqualTo(mapProj->theUlEastingNorthing, compareType)&&
1551  (thePcsCode == mapProj->thePcsCode)&&
1557  (theProjectionUnits == mapProj->theProjectionUnits));
1558 
1559  if(result)
1560  {
1561  if(compareType == OSSIM_COMPARE_FULL)
1562  {
1563  if(theDatum&&mapProj->theDatum)
1564  {
1565  result = theDatum->isEqualTo(*mapProj->theDatum, compareType);
1566  }
1567  }
1568  else
1569  {
1570  result = (theDatum==mapProj->theDatum);
1571  }
1572  }
1573  }
1574  return result;
1575 }
1576 
1578 {
1579  return theFalseEastingNorthing.x;
1580 }
1581 
1583 {
1584  return theFalseEastingNorthing.y;
1585 }
1586 
1588 {
1589  return 0.0;
1590 }
1591 
1593 {
1594  return 0.0;
1595 }
1596 
1598  ossimUnitType unitType)
1599 {
1600  ossim_float64 convertedMultiple = multiple;
1601 
1602  if (isGeographic() && (unitType != OSSIM_DEGREES) )
1603  {
1604  // Convert to degrees.
1605  ossimUnitConversionTool convertor;
1606  convertor.setOrigin(theOrigin);
1607  convertor.setValue(multiple, unitType);
1608  convertedMultiple = convertor.getDegrees();
1609  }
1610  else if ( !isGeographic() && (unitType != OSSIM_METERS) )
1611  {
1612  // Convert to meters.
1613  ossimUnitConversionTool convertor;
1614  convertor.setOrigin(theOrigin);
1615  convertor.setValue(multiple, unitType);
1616  convertedMultiple = convertor.getMeters();
1617  }
1618 
1619  // Convert the tie point.
1620  if (isGeographic())
1621  {
1622  // Snap the latitude.
1623  ossim_float64 d = theUlGpt.latd();
1624  d = ossim::round<int>(d / convertedMultiple) * convertedMultiple;
1625  theUlGpt.latd(d);
1626 
1627  // Snap the longitude.
1628  d = theUlGpt.lond();
1629  d = ossim::round<int>(d / convertedMultiple) * convertedMultiple;
1630  theUlGpt.lond(d);
1631 
1632  // Adjust the stored easting / northing.
1634  }
1635  else
1636  {
1637  // Snap the easting.
1639  d = ossim::round<int>(d / convertedMultiple) * convertedMultiple;
1641 
1642  // Snap the northing.
1644  d = ossim::round<int>(d / convertedMultiple) * convertedMultiple;
1646 
1647  // Adjust the stored upper left ground point.
1649  }
1650 }
1651 
1653 {
1654  // Convert the tie point.
1655  if (isGeographic())
1656  {
1657  // Note the origin may not be 0.0, 0.0:
1658 
1659  // Snap the latitude.
1660  ossim_float64 d = theUlGpt.latd() - origin().latd();
1661  d = ossim::round<int>(d / theDegreesPerPixel.y) * theDegreesPerPixel.y;
1662  theUlGpt.latd(d + origin().latd());
1663 
1664  // Snap the longitude.
1665  d = theUlGpt.lond() - origin().lond();
1666  d = ossim::round<int>(d / theDegreesPerPixel.x) * theDegreesPerPixel.x;
1667  theUlGpt.lond(d + origin().lond());
1668 
1669  // Adjust the stored easting / northing.
1671  }
1672  else
1673  {
1674  // Snap the easting.
1676  d = ossim::round<int>(d / theMetersPerPixel.x) * theMetersPerPixel.x;
1678 
1679  // Snap the northing.
1681  d = ossim::round<int>(d / theMetersPerPixel.y) * theMetersPerPixel.y;
1683 
1684  // Adjust the stored upper left ground point.
1686  }
1687 }
1688 
1690 {
1691  theElevationLookupFlag = flag;
1692 }
1693 
1695 {
1696  return theElevationLookupFlag;
1697 }
1698 
1699 
ossimMatrix4x4 theModelTransform
virtual const ossimDpt & getDecimalDegreesPerPixel() const
Returns decimal degrees per pixel as an ossimDpt with "x" representing longitude and "y" representing...
virtual bool isEqualTo(const ossimObject &obj, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
const NEWMAT::Matrix & getData() const
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
static const char * MINOR_AXIS_KW
static const char * DECIMAL_DEGREES_PER_PIXEL_LAT
double getValue(ossimUnitType unitType=OSSIM_METERS) const
std::basic_ostringstream< char > ostringstream
Class for char output memory streams.
Definition: ossimIosFwd.h:35
static const char * DATUM_KW
virtual double getFalseNorthing() const
ossimMatrix4x4 & i()
static const char * FALSE_EASTING_NORTHING_UNITS_KW
bool isEqualTo(const ossimDpt &rhs, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
Definition: ossimDpt.cpp:153
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
static const char * CENTRAL_MERIDIAN_KW
ossimUnitType
Represents serializable keyword/value map.
bool isLonNan() const
Definition: ossimGpt.h:140
bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
static ossimDatumFactoryRegistry * instance()
instance method
void setB(double b)
const char * find(const char *key) const
double samp
Definition: ossimDpt.h:164
virtual ossim_uint32 getPcsCode() const
Returns the EPSG PCS code or 32767 if the projection is a custom (non-EPSG) projection.
virtual void setEllipsoid(const ossimEllipsoid &ellipsoid)
SET METHODS:
virtual ossimString getEntryString(ossim_int32 entry_number) const
virtual std::ostream & print(std::ostream &out) const
Outputs theErrorStatus as an ossimErrorCode and an ossimString.
virtual bool isEqualTo(const ossimObject &obj, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
Definition: ossimDatum.cpp:179
static const char * ORIGINAL_MAP_UNITS_KW
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
virtual double getF() const
static const char * IMAGE_MODEL_TRANSFORM_MATRIX_KW
void clampLon(double low, double high)
Definition: ossimGpt.h:228
virtual ossimDpt worldToLineSample(const ossimGpt &worldPoint) const
virtual void computeMetersPerPixel()
This will go from the ground point and give you an approximate meters per pixel.
void setValue(double value, ossimUnitType unitType=OSSIM_METERS)
double y
Definition: ossimDpt.h:165
virtual void setOrigin(const ossimGpt &origin)
Sets theOrigin to origin.
bool contains(char aChar) const
Definition: ossimString.h:58
ossimDpt theUlEastingNorthing
Hold tie point as easting northing.
virtual const ossimString & code() const
Definition: ossimDatum.h:57
void makeNan()
Definition: ossimGpt.h:130
static ossimString toString(bool aValue)
Numeric to string methods.
static const char * TIE_POINT_LON_KW
virtual bool isGeographic() const
virtual ossim_int32 getEntryNumber(const char *entry_string, bool case_insensitive=true) const
ossim_float64 hgt
Height in meters above the ellipsiod.
Definition: ossimGpt.h:274
virtual ossimString getClassName() const
Definition: ossimObject.cpp:64
virtual void setDecimalDegreesPerPixel(const ossimDpt &gsd)
ossim_uint32 toUInt32() const
static ossimElevManager * instance()
METHOD: instance() Implements singelton pattern.
ossimCompareType
bool isNan() const
Definition: ossimDpt.h:72
virtual double getStandardParallel2() const
Derived classes should implement as needed.
virtual double getB() const
ossimGpt theUlGpt
Hold tie point in decimal degrees.
ossim_uint32 findProjectionCode(const ossimString &projection_name) const
Given a projection name, assigns the group (e.g., "EPSG") and code of the projection.
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
bool isLatNan() const
Definition: ossimGpt.h:139
virtual void applyScale(const ossimDpt &scale, bool recenterTiePoint)
Applies scale to theDeltaLonPerPixel, theDeltaLatPerPixel and theMetersPerPixel data members (eg: the...
static const char * METERS_PER_PIXEL_Y_KW
static const char * TYPE_KW
virtual ossimGpt inverse(const ossimDpt &projectedPoint) const =0
Will take a point in meters and convert it to ground.
void changeDatum(const ossimDatum *datum)
This will actually perform a shift.
Definition: ossimGpt.cpp:316
ossimMatrix4x4 theInverseModelTransform
virtual double getStandardParallel1() const
Derived classes should implement as needed.
virtual void setUlGpt(const ossimGpt &ulGpt)
virtual void setMetersPerPixel(const ossimDpt &gsd)
const ossimDatum * datum() const
datum().
Definition: ossimGpt.h:196
void snapTiePointTo(ossim_float64 multiple, ossimUnitType unitType)
Utility method to snap the tie point to some multiple.
static const char * PIXEL_SCALE_XY_KW
static const char * ELEVATION_LOOKUP_FLAG_KW
static const char * TIE_POINT_NORTHING_KW
virtual bool isEqualTo(const ossimObject &obj, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
double ossim_float64
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual bool isEqualTo(const ossimEllipsoid &rhs, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
virtual ossimGpt lineSampleToWorld(const ossimDpt &projectedPoint) const
double line
Definition: ossimDpt.h:165
double lat
Definition: ossimDpt.h:165
ossimDpt theMetersPerPixel
Holds the number of meters per pixel.
bool hasModelTransform() const
ossimUnitType theModelTransformUnitType
virtual bool operator==(const ossimProjection &projection) const
Compares this to arg projection and returns TRUE if the same.
virtual const ossimDatum * getDatum() const
static const char * TIE_POINT_XY_KW
bool isEqualTo(const ossimGpt &rhs, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
Definition: ossimGpt.cpp:366
ossim_float64 lon
Definition: ossimGpt.h:266
static const char * TIE_POINT_EASTING_KW
virtual void setUlEastingNorthing(const ossimDpt &ulEastingNorthing)
virtual void setPcsCode(ossim_uint32 pcsCode)
virtual void lineSampleToEastingNorthing(const ossimDpt &liineSample, ossimDpt &eastingNorthing) const
static const char * FALSE_NORTHING_KW
static ossimEpsgProjectionDatabase * instance()
Instantiates singleton instance of this class:
virtual double getHeightAboveEllipsoid(const ossimGpt &gpt)
virtual void assign(const ossimProjection &aProjection)
static const char * MAJOR_AXIS_KW
bool toBool() const
String to numeric methods.
const double & getA() const
virtual ossimString getProjectionName() const
Returns the projection name.
virtual ossimGpt origin() const
ossimMapProjection(const ossimEllipsoid &ellipsoid=ossimEllipsoid(), const ossimGpt &origin=ossimGpt())
unsigned int ossim_uint32
virtual const ossimDatum * create(const ossimString &code) const
create method
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
void toPoint(const std::string &s)
Initializes this point from string.
Definition: ossimDpt.cpp:192
virtual const ossimEllipsoid * ellipsoid() const
Definition: ossimDatum.h:60
double toDouble() const
ossim_float64 toFloat64() const
static ossimDatumFactory * instance()
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
static const char * FALSE_EASTING_KW
static const char * DECIMAL_DEGREES_PER_PIXEL_LON
static const char * IMAGE_MODEL_TRANSFORM_UNIT_KW
void clampLat(double low, double high)
Definition: ossimGpt.h:234
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
void setOrigin(const ossimGpt &gpt)
static const char * FALSE_EASTING_NORTHING_KW
ossimUnitType theProjectionUnits
Linear units of the projection as indicated in the projection&#39;s specification:
bool hasNans() const
Definition: ossimDpt.h:67
double lon
Definition: ossimDpt.h:164
virtual const ossimGpt & getUlGpt() const
const ossimGpt & getOrigin() const
virtual ossimDpt forward(const ossimGpt &worldPoint) const =0
All map projections will convert the world coordinate to an easting northing (Meters).
static const char * ORIGIN_LATITUDE_KW
virtual double getFalseEasting() const
ossim_uint32 thePcsCode
Projection Coordinate System(PCS) code.
static const char * PCS_CODE_KW
ossimString toString(ossim_uint32 precision=15) const
Definition: ossimDpt.cpp:160
bool getElevationLookupFlag() const
bool hasNans() const
Definition: ossimGpt.h:135
const double & getB() const
ossimDpt theDegreesPerPixel
Hold the decimal degrees per pixel.
static const char * PIXEL_TYPE_KW
RTTI_DEF1(ossimMapProjection, "ossimMapProjection", ossimProjection)
virtual void setAB(double a, double b)
void setA(double a)
double x
Definition: ossimDpt.h:164
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
virtual void eastingNorthingToLineSample(const ossimDpt &eastingNorthing, ossimDpt &lineSample) const
bool isEqualTo(const ossimMatrix4x4 &rhs, ossimCompareType compareType=OSSIM_COMPARE_FULL) const
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
virtual void setUlTiePoints(const ossimGpt &gpt)
ossimDpt metersPerDegree() const
Definition: ossimGpt.cpp:498
const double & getFlattening() const
ossim_float64 lat
Definition: ossimGpt.h:265
static const char * TIE_POINT_LAT_KW
virtual const ossimDpt & getUlEastingNorthing() const
ossimEllipsoid theEllipsoid
This method verifies that the projection parameters match the current pcs code.
const ossimDatum * wgs84() const
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
ossimDpt theFalseEastingNorthing
Hold the false easting northing.
virtual void setDatum(const ossimDatum *datum)
Sets theDatum to datum.
virtual ossimDpt getMetersPerPixel() const
virtual void eastingNorthingToWorld(const ossimDpt &eastingNorthing, ossimGpt &worldPt) const
virtual void computeDegreesPerPixel()
Computes the approximate resolution in degrees/pixel.
virtual void lineSampleHeightToWorld(const ossimDpt &lineSampPt, const double &heightAboveEllipsoid, ossimGpt &worldPt) const
This is the pure virtual that projects the image point to the given elevation above ellipsoid...
void setElevationLookupFlag(bool flag)
static ossimUnitTypeLut * instance()
Returns the static instance of an ossimUnitTypeLut object.
virtual std::ostream & print(std::ostream &out) const
Prints data members to stream.
virtual double getA() const
ACCESS METHODS:
static const char * METERS_PER_PIXEL_X_KW
OSSIMDLLEXPORT std::ostream & ossimNotify(ossimNotifyLevel level=ossimNotifyLevel_WARN)
static const char * SRS_NAME_KW
void makeNan()
Definition: ossimDpt.h:65
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
static const char * PIXEL_SCALE_UNITS_KW
static const char * TIE_POINT_UNITS_KW
bool isnan(const float &v)
isnan Test for floating point Not A Number (NAN) value.
Definition: ossimCommon.h:91
const ossimDatum * theDatum
This is only set if we want to have built in datum shifting.