OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimOrthoGraphicProjection.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: See top LICENSE.txt file.
5 //
6 // Author: Garrett Potts
7 //
8 // Description:
9 //
10 // Calls Geotrans OrthoGraphic projection code.
11 //*******************************************************************
12 // $Id: ossimOrthoGraphicProjection.cpp 9094 2006-06-13 19:12:40Z dburken $
13 
14 #include <math.h>
17 
18 RTTI_DEF1(ossimOrthoGraphicProjection, "ossimOrthoGraphicProjection", ossimMapProjection)
19 /***************************************************************************/
20 /*
21  * DEFINES
22  */
23 #ifndef PI_OVER_2
24 # define PI_OVER_2 ( M_PI / 2.0)
25 #endif
26 #ifndef TWO_PI
27 # define TWO_PI (2.0 * M_PI)
28 #endif
29 #define MAX_LAT ( (M_PI * 90) / 180.0 ) /* 90 degrees in radians */
30 
31 
32 #define ORTH_NO_ERROR 0x0000
33 #define ORTH_LAT_ERROR 0x0001
34 #define ORTH_LON_ERROR 0x0002
35 #define ORTH_EASTING_ERROR 0x0004
36 #define ORTH_NORTHING_ERROR 0x0008
37 #define ORTH_ORIGIN_LAT_ERROR 0x0010
38 #define ORTH_CENT_MER_ERROR 0x0020
39 #define ORTH_A_ERROR 0x0040
40 #define ORTH_B_ERROR 0x0080
41 #define ORTH_A_LESS_B_ERROR 0x0100
42 #define ORTH_RADIUS_ERROR 0x0200
43 
44 
46  const ossimGpt& origin)
47  :ossimMapProjection(ellipsoid, origin)
48 {
49  setDefaults();
50  update();
51 }
52 
54  const ossimGpt& origin,
55  double falseEasting,
56  double falseNorthing)
57  :ossimMapProjection(ellipsoid, origin)
58 {
59  Orth_False_Easting = falseEasting;
60  Orth_False_Northing = falseNorthing;
61 
62  update();
63 }
64 
66 {
69  theOrigin.latr(),
70  theOrigin.lonr(),
73 
76 
78 }
79 
81 {
82  Orth_False_Easting = falseEasting;
83  update();
84 }
85 
87 {
88  Orth_False_Northing = falseNorthing;
89  update();
90 }
91 
93 {
94  Orth_False_Easting = 0.0;
95  Orth_False_Northing = 0.0;
96 }
97 
99  double falseNorthing)
100 {
101  Orth_False_Easting = falseEasting;
102  Orth_False_Northing = falseNorthing;
103 
104  update();
105 }
106 
108 {
109 
111  theOrigin.lond()-90.0,
112  0.0,
113  theDatum));
114  gpts.addPoint(ossimGpt(theOrigin.latd()+90.0,
115  theOrigin.lond(),
116  0.0,
117  theDatum));
119  theOrigin.lond()+90.0,
120  0.0,
121  theDatum));
122  gpts.addPoint(ossimGpt(theOrigin.latd()-90.0,
123  theOrigin.lond(),
124  0.0,
125  theDatum));
126 
127 
128 }
129 
131 {
132  double lat = 0.0;
133  double lon = 0.0;
134  ossimGpt result;
135  if(Convert_Orthographic_To_Geodetic(eastingNorthing.x,
136  eastingNorthing.y,
137  &lat,
138  &lon)==ORTH_NO_ERROR)
139  {
140  result.datum(theDatum);
141  result.latr(lat);
142  result.lonr(lon);
143  }
144  else
145  {
146  result.makeNan();
147  }
148 
149  return result;
150 }
151 
153 {
154 
155  double easting = 0.0;
156  double northing = 0.0;
157  ossimGpt gpt = latLon;
158  ossimDpt result;
159 
160  if (theDatum)
161  {
162  if (theDatum->code() != latLon.datum()->code())
163  {
164  gpt.changeDatum(theDatum); // Shift to our datum.
165  }
166  }
167 
169  gpt.lonr(),
170  &easting,
171  &northing) == ORTH_NO_ERROR)
172  {
173  result = ossimDpt(easting, northing);
174  }
175  else
176  {
177  result.makeNan();
178  }
179 
180  return result;
181 }
182 
183 bool ossimOrthoGraphicProjection::saveState(ossimKeywordlist& kwl, const char* prefix) const
184 {
185  return ossimMapProjection::saveState(kwl, prefix);
186 }
187 
189  const char* prefix)
190 {
191  bool flag = ossimMapProjection::loadState(kwl, prefix);
192  const char* type = kwl.find(prefix, ossimKeywordNames::TYPE_KW);
193 
194  setDefaults();
195 
197  {
200  }
201 
202  update();
203 
204  return flag;
205 }
206 
207 /***************************************************************************/
208 /*
209  * FUNCTIONS
210  */
211 
212 
214  double f,
215  double Origin_Latitude,
216  double Central_Meridian,
217  double False_Easting,
218  double False_Northing)
219 { /* BEGIN Set_Orthographic_Parameters */
220 /*
221  * The function Set_Orthographic_Parameters receives the ellipsoid parameters and
222  * projection parameters as inputs, and sets the corresponding state
223  * variables. If any errors occur, the error code(s) are returned by the function,
224  * otherwise ORTH_NO_ERROR is returned.
225  *
226  * a : Semi-major axis of ellipsoid, in meters (input)
227  * f : Flattening of ellipsoid (input)
228  * Origin_Latitude : Latitude in radians at which the (input)
229  * point scale factor is 1.0
230  * Central_Meridian : Longitude in radians at the center of (input)
231  * the projection
232  * False_Easting : A coordinate value in meters assigned to the
233  * central meridian of the projection. (input)
234  * False_Northing : A coordinate value in meters assigned to the
235  * origin latitude of the projection (input)
236  */
237 
238 // double inv_f = 1 / f;
239  long Error_Code = ORTH_NO_ERROR;
240 
241  if (a <= 0.0)
242  { /* Semi-major axis must be greater than zero */
243  Error_Code |= ORTH_A_ERROR;
244  }
245 // if ((inv_f < 250) || (inv_f > 350))
246 // { /* Inverse flattening must be between 250 and 350 */
247 // Error_Code |= ORTH_INV_F_ERROR;
248 // }
249  if ((Origin_Latitude < -PI_OVER_2) || (Origin_Latitude > PI_OVER_2))
250  { /* origin latitude out of range */
251  Error_Code |= ORTH_ORIGIN_LAT_ERROR;
252  }
253  if ((Central_Meridian < -M_PI) || (Central_Meridian > TWO_PI))
254  { /* origin longitude out of range */
255  Error_Code |= ORTH_CENT_MER_ERROR;
256  }
257  if (!Error_Code)
258  { /* no errors */
259  Orth_a = a;
260  Orth_f = f;
261  es2 = 2 * Orth_f - Orth_f * Orth_f;
262  es4 = es2 * es2;
263  es6 = es4 * es2;
264  Ra = Orth_a * (1.0 - es2 / 6.0 - 17.0 * es4 / 360.0 - 67.0 * es6 /3024.0);
265  Orth_Origin_Lat = Origin_Latitude;
268 // if (Central_Meridian > M_PI)
269 // Central_Meridian -= TWO_PI;
270  Orth_Origin_Long = Central_Meridian;
271  Orth_False_Easting = False_Easting;
272  Orth_False_Northing = False_Northing;
273 
274  } /* END OF if(!Error_Code) */
275 
276  return (Error_Code);
277 } /* END OF Set_Orthographic_Parameters */
278 
279 
281  double *f,
282  double *Origin_Latitude,
283  double *Central_Meridian,
284  double *False_Easting,
285  double *False_Northing)const
286 { /* BEGIN Get_Orthographic_Parameters */
287 /*
288  * The function Get_Orthographic_Parameters returns the current ellipsoid
289  * parameters and Orthographic projection parameters.
290  *
291  * a : Semi-major axis of ellipsoid, in meters (output)
292  * f : Flattening of ellipsoid (output)
293  * Origin_Latitude : Latitude in radians at which the (output)
294  * point scale factor is 1.0
295  * Central_Meridian : Longitude in radians at the center of (output)
296  * the projection
297  * False_Easting : A coordinate value in meters assigned to the
298  * central meridian of the projection. (output)
299  * False_Northing : A coordinate value in meters assigned to the
300  * origin latitude of the projection (output)
301  */
302 
303  *a = Orth_a;
304  *f = Orth_f;
305  *Origin_Latitude = Orth_Origin_Lat;
306  *Central_Meridian = Orth_Origin_Long;
307  *False_Easting = Orth_False_Easting;
308  *False_Northing = Orth_False_Northing;
309 
310  return;
311 } /* END OF Get_Orthographic_Parameters */
312 
313 
315  double Longitude,
316  double *Easting,
317  double *Northing)const
318 
319 { /* BEGIN Convert_Geodetic_To_Orthographic */
320 /*
321  * The function Convert_Geodetic_To_Orthographic converts geodetic (latitude and
322  * longitude) coordinates to Orthographic projection (easting and northing)
323  * coordinates, according to the current ellipsoid and Orthographic projection
324  * parameters. If any errors occur, the error code(s) are returned by the
325  * function, otherwise ORTH_NO_ERROR is returned.
326  *
327  * Latitude : Latitude (phi) in radians (input)
328  * Longitude : Longitude (lambda) in radians (input)
329  * Easting : Easting (X) in meters (output)
330  * Northing : Northing (Y) in meters (output)
331  */
332 
333  double slat = sin(Latitude);
334  double clat = cos(Latitude);
335  double dlam; /* Longitude - Central Meridan */
336  double clat_cdlam;
337  double cos_c; /* Value used to determine whether the point is beyond
338  viewing. If zero or positive, the point is within view. */
339  long Error_Code = ORTH_NO_ERROR;
340 
341  if ((Latitude < -PI_OVER_2) || (Latitude > PI_OVER_2))
342  { /* Latitude out of range */
343  Error_Code |= ORTH_LAT_ERROR;
344  }
345  if ((Longitude < -M_PI) || (Longitude > TWO_PI))
346  { /* Longitude out of range */
347  Error_Code|= ORTH_LON_ERROR;
348  }
349  dlam = Longitude - Orth_Origin_Long;
350  clat_cdlam = clat * cos(dlam);
351  cos_c = Sin_Orth_Origin_Lat * slat + Cos_Orth_Origin_Lat * clat_cdlam;
352  if (cos_c < 0.0)
353  { /* Point is out of view. Will return longitude out of range message
354  since no point out of view is implemented. */
355  Error_Code |= ORTH_LON_ERROR;
356  }
357 
358  if (!Error_Code)
359  { /* no errors */
360  if (dlam > M_PI)
361  {
362  dlam -= TWO_PI;
363  }
364  if (dlam < -M_PI)
365  {
366  dlam += TWO_PI;
367  }
368  *Easting = Ra * clat * sin(dlam) + Orth_False_Easting;
369  *Northing = Ra * (Cos_Orth_Origin_Lat * slat - Sin_Orth_Origin_Lat * clat_cdlam) +
371  }
372  return (Error_Code);
373 
374 } /* END OF Convert_Geodetic_To_Orthographic */
375 
376 
378  double Northing,
379  double *Latitude,
380  double *Longitude)const
381 { /* BEGIN Convert_Orthographic_To_Geodetic */
382 /*
383  * The function Convert_Orthographic_To_Geodetic converts Orthographic projection
384  * (easting and northing) coordinates to geodetic (latitude and longitude)
385  * coordinates, according to the current ellipsoid and Orthographic projection
386  * coordinates. If any errors occur, the error code(s) are returned by the
387  * function, otherwise ORTH_NO_ERROR is returned.
388  *
389  * Easting : Easting (X) in meters (input)
390  * Northing : Northing (Y) in meters (input)
391  * Latitude : Latitude (phi) in radians (output)
392  * Longitude : Longitude (lambda) in radians (output)
393  */
394 
395  double cc;
396  double cos_cc, sin_cc;
397  double rho;
398  double dx, dy;
399  double atan_dx_over_dy;
400 // double temp;
401  double rho_OVER_Ra;
402  long Error_Code = ORTH_NO_ERROR;
403 
404  if ((Easting > (Orth_False_Easting + Ra)) ||
405  (Easting < (Orth_False_Easting - Ra)))
406  { /* Easting out of range */
407  Error_Code |= ORTH_EASTING_ERROR;
408  }
409  if ((Northing > (Orth_False_Northing + Ra)) ||
410  (Northing < (Orth_False_Northing - Ra)))
411  { /* Northing out of range */
412  Error_Code |= ORTH_NORTHING_ERROR;
413  }
414  if (!Error_Code)
415  {
416  double temp = sqrt(Easting * Easting + Northing * Northing);
417 
418  if ((temp > (Orth_False_Easting + Ra)) || (temp > (Orth_False_Northing + Ra)) ||
419  (temp < (Orth_False_Easting - Ra)) || (temp < (Orth_False_Northing - Ra)))
420  { /* Point is outside of projection area */
421  Error_Code |= ORTH_RADIUS_ERROR;
422  }
423  }
424 
425  if (!Error_Code)
426  {
427  dx = Easting - Orth_False_Easting;
428  dy = Northing - Orth_False_Northing;
429  atan_dx_over_dy = atan(dx / dy);
430  rho = sqrt(dx * dx + dy * dy);
431  if (rho == 0.0)
432  {
433  *Latitude = Orth_Origin_Lat;
434  *Longitude = Orth_Origin_Long;
435  }
436  else
437  {
438  rho_OVER_Ra = rho / Ra;
439 
440  if (rho_OVER_Ra > 1.0)
441  rho_OVER_Ra = 1.0;
442  else if (rho_OVER_Ra < -1.0)
443  rho_OVER_Ra = -1.0;
444 
445  cc = asin(rho_OVER_Ra);
446  cos_cc = cos(cc);
447  sin_cc = sin(cc);
448  *Latitude = asin(cos_cc * Sin_Orth_Origin_Lat + (dy * sin_cc * Cos_Orth_Origin_Lat / rho));
449 
450  if (Orth_Origin_Lat == MAX_LAT)
451  *Longitude = Orth_Origin_Long - atan_dx_over_dy;
452  else if (Orth_Origin_Lat == -MAX_LAT)
453  *Longitude = Orth_Origin_Long + atan_dx_over_dy;
454  else
455  *Longitude = Orth_Origin_Long + atan(dx * sin_cc / (rho *
456  Cos_Orth_Origin_Lat * cos_cc - dy * Sin_Orth_Origin_Lat * sin_cc));
457 
458 // if (*Latitude > PI_OVER_2) /* force distorted values to 90, -90 degrees */
459 // *Latitude = PI_OVER_2;
460 // else if (*Latitude < -PI_OVER_2)
461 // *Latitude = -PI_OVER_2;
462 
463 // if (*Longitude > M_PI)
464 // *Longitude -= TWO_PI;
465 // if (*Longitude < -M_PI)
466 // *Longitude += TWO_PI;
467 
468 // if (*Longitude > M_PI) /* force distorted values to 180, -180 degrees */
469 // *Longitude = M_PI;
470 // else if (*Longitude < -M_PI)
471 // *Longitude = -M_PI;
472  }
473  }
474  return (Error_Code);
475 } /* END OF Convert_Orthographic_To_Geodetic */
#define ORTH_NO_ERROR
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Method to the load (recreate) the state of an object from a keyword list.
#define ORTH_NORTHING_ERROR
#define ORTH_LON_ERROR
void Get_Orthographic_Parameters(double *a, double *f, double *Origin_Latitude, double *Origin_Longitude, double *False_Easting, double *False_Northing) const
double lond() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:97
Represents serializable keyword/value map.
const char * find(const char *key) const
double y
Definition: ossimDpt.h:165
virtual ossimGpt inverse(const ossimDpt &eastingNorthing) const
Will take a point in meters and convert it to ground.
void setFalseEasting(double falseEasting)
virtual const ossimString & code() const
Definition: ossimDatum.h:57
void makeNan()
Definition: ossimGpt.h:130
long Convert_Geodetic_To_Orthographic(double Latitude, double Longitude, double *Easting, double *Northing) const
void setFalseNorthing(double falseNorthing)
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
double latd() const
Will convert the radian measure to degrees.
Definition: ossimGpt.h:87
virtual ossimDpt forward(const ossimGpt &latLon) const
All map projections will convert the world coordinate to an easting northing (Meters).
static const char * TYPE_KW
void changeDatum(const ossimDatum *datum)
This will actually perform a shift.
Definition: ossimGpt.cpp:316
#define STATIC_TYPE_NAME(T)
Definition: ossimRtti.h:325
const ossimDatum * datum() const
datum().
Definition: ossimGpt.h:196
#define M_PI
const double & getA() const
long Convert_Orthographic_To_Geodetic(double Easting, double Northing, double *Latitude, double *Longitude) const
double lonr() const
Returns the longitude in radian measure.
Definition: ossimGpt.h:76
#define ORTH_RADIUS_ERROR
virtual bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Method to save the state of an object to a keyword list.
#define ORTH_ORIGIN_LAT_ERROR
ossimOrthoGraphicProjection(const ossimEllipsoid &ellipsoid=ossimEllipsoid(), const ossimGpt &origin=ossimGpt())
void addPoint(const ossimGpt &pt)
#define ORTH_A_ERROR
#define ORTH_CENT_MER_ERROR
double x
Definition: ossimDpt.h:164
double latr() const
latr().
Definition: ossimGpt.h:66
const double & getFlattening() const
#define ORTH_EASTING_ERROR
void setFalseEastingNorthing(double falseEasting, double falseNorthing)
ossimEllipsoid theEllipsoid
This method verifies that the projection parameters match the current pcs code.
#define RTTI_DEF1(cls, name, b1)
Definition: ossimRtti.h:485
#define ORTH_LAT_ERROR
ossimDpt theFalseEastingNorthing
Hold the false easting northing.
long Set_Orthographic_Parameters(double a, double f, double Origin_Latitude, double Central_Meridian, double False_Easting, double False_Northing)
void makeNan()
Definition: ossimDpt.h:65
virtual bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
virtual void getGroundClipPoints(ossimGeoPolygon &gpts) const
#define PI_OVER_2
const ossimDatum * theDatum
This is only set if we want to have built in datum shifting.