BISICLES AMR ice sheet model  0.9
Transformation.H
Go to the documentation of this file.
1  #ifdef CH_LANG_CC
2 /*
3 * _______ __
4 * / ___/ / ___ __ _ / / ___
5 * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6 * \___/_//_/\___/_/_/_/_.__/\___/
7 * Please refer to Copyright.txt, in Chombo's root directory.
8 */
9 #endif
10 //===========================================================================
11 // Transformation.H
12 // Abstract class defining a co-ordinate transformation, plus some concrete classes
13 //===========================================================================
14 #ifndef _TRANSFORMATION_H_
15 #define _TRANSFORMATION_H_
16 
17 #include "RealVect.H"
18 #ifdef HAVE_GDAL
19 #include "ogr_spatialref.h"
20 #endif
21 #include <sstream>
22 #include "NamespaceHeader.H"
23 
26 {
27 public:
28 
30  virtual RealVect transform(const RealVect& x) const=0;
31 
32  virtual ~Transformation(){};
33 };
34 
35 
36 
38 {
39 
40 /*
41 from: http://www.remotesensing.org/geotiff/proj_list/polar_stereographic.html
42 
43 For the forward transformation from latitude and longitude:
44 
45 E = FE + rho sin(lon - lon0)
46 N = FN - rho cos(lon - lon0)
47 where
48 rho = 2 a ko t /{[((1+e)^(1+e)) ((1-e)^(1-e))]^0.5}
49 t = tan (pi/4 - lat/2) / [(1-esin(lat) ) / (1 + e sin(lat))]^(e/2)
50 
51 For the reverse transformation:
52 
53 lat = chi+ (e^2/2 + 5e^4/24 + e^6/12 + 13e^8/360) sin(2 chi)
54 + (7e^4/48 + 29e^6/240 + 811e^8/11520) sin(4 chi)
55 + (7e^6/120 + 81e^8/1120) sin(6 chi) + (4279e^8/161280) sin(8 chi)
56 
57 lon = lon0+ arctan [(E-FE) / (FN-N)]
58 
59 where chi = pi/2 - 2 arctan t
60 t = rho [((1+e)^(1+e)) ((1-e)^(1-e))]^0.5} / 2 a ko
61 rho = [(E-FE)^2 + (N - FN)^2]^0.5
62 
63 ko == scale factor at natural origin (usually 1.0)
64 e = ellipsoid eccentricity (0.08181922 for earth)
65 a = equatorial radius (6.3781370e+6 m for earth)
66 
67 */
68 
69 
70  Real m_e, m_a, m_k0, m_lon0;
71  RealVect m_fx;
72 
73 public:
75  (const Real& a_e, const Real& a_a, const Real& a_k0, const Real& a_lon0,
76  const RealVect& a_fx)
77  :m_e(a_e),m_a(a_a),m_k0(a_k0),m_lon0(a_lon0),m_fx(a_fx)
78  {}
79 
80  virtual RealVect transform(const RealVect& x) const
81  {
82  const Real& e = m_e;
83  Real pi = M_PI;
84  Real rho = std::sqrt( std::pow(x[0]-m_fx[0],2) + std::pow(x[1]-m_fx[1],2));
85  Real t = 0.5 * rho * std::sqrt ( std::pow(1.0+e,1.0+e) * std::pow(1.0-e,1.0-e)) /( 2.0 * m_a * m_k0);
86  Real chi = 0.5*pi - 2.0*std::atan(t);
87  Real lat = chi
88  + std::sin(2.0*chi) * (0.5 * std::pow(e,2) + 5.0*std::pow(e,4)/24.0 + std::pow(e,6)/12.0 + 13.0*std::pow(e,8)/360.0)
89  + std::sin(4.0*chi) * (7.0*std::pow(e,4)/48.0 + 29.0*std::pow(e,6)/240.0 + 811.0*std::pow(e,8)/11520.0)
90  + std::sin(6.0*chi) * (7.0*std::pow(e,6)/120.0 + 81.0*std::pow(e,8)/1120.0)
91  + std::sin(8.0*chi) * (4729.0*std::pow(e,8)/161280.0);
92 
93 
94  Real lon = m_lon0 + std::atan2 ( x[0]-m_fx[0] , m_fx[1]-x[1] );
95 
96  RealVect r ( x) ;
97  r[0] = lat;
98  r[1] = lon;
99 
100  return r;
101 
102  }
103 
104 };
105 
106 #ifdef HAVE_GDAL
108 {
109 
110 /*
111 GDAL: using gdal rountines to convert from x,y to lat lon
112 */
113 
114  int m_epsg;
115  Real m_x0, m_y0;
116  OGRSpatialReference source, *poLatLon;
117  OGRCoordinateTransformation *mapping;
118 
119  Real unitDegree;
120 
121 public:
123  (const int& a_epsg, const Real& a_x0, const Real& a_y0)
124  :m_epsg(a_epsg),m_x0(a_x0),m_y0(a_y0)
125  {
126 
127  source.importFromEPSG( m_epsg );
128  poLatLon = source.CloneGeogCS();
129  mapping = OGRCreateCoordinateTransformation( &source, poLatLon );
130 
131  CH_assert( mapping != NULL );
132 
133  char *pszwkt = NULL;
134 
135  source.exportToWkt( &pszwkt );
136  pout() << " " << std::endl;
137  pout() << pszwkt << std::endl;
138  pout() << " " << std::endl;
139 
140  if (pszwkt) {delete pszwkt; pszwkt=NULL;}
141 
142  unitDegree=0.0;
143  istringstream ist(SRS_UA_DEGREE_CONV);
144  ist >> unitDegree;
145 
146  }
147 
149  {
150  if (mapping) {delete mapping; mapping=NULL;}
151  if (poLatLon) {delete poLatLon; poLatLon=NULL;}
152  }
153 
154  virtual RealVect transform(const RealVect& x) const
155  {
156 
157  RealVect rwk ( x) ;
158  Real z = 0.0;
159 #if CH_SPACEDIM > 2
160  z = rwk[2];
161 #endif
162  int nPoints = 1;
163 
164  rwk[0]=rwk[0]+m_x0; // Translate grid to Morgihem's coord system
165  rwk[1]=rwk[1]+m_y0;
166 
167  CH_assert( mapping->Transform(nPoints, &rwk[0], &rwk[1], &z) );
168  RealVect r ( D_DECL(rwk[1], rwk[0], z));
169  r *= unitDegree;
170 
171  return r;
172 
173  }
174 
175 
176 };
177 #endif
178 
179 #include "NamespaceFooter.H"
180 #endif
~gdalxytolatlon()
Definition: Transformation.H:148
virtual ~Transformation()
Definition: Transformation.H:32
virtual RealVect transform(const RealVect &x) const
given x, compute x&#39;
Definition: Transformation.H:80
virtual RealVect transform(const RealVect &x) const
given x, compute x&#39;
Definition: Transformation.H:154
virtual RealVect transform(const RealVect &x) const =0
given x, compute x&#39;
abstract class for co-ordinate Transformations.
Definition: Transformation.H:25
Definition: Transformation.H:107