openModeller  Version 1.5.0
GeoTransform.cpp
Go to the documentation of this file.
1 
29 #include <openmodeller/om_defs.hh>
30 #include <openmodeller/Log.hh>
31 
33 
34 #include <ogr_api.h>
35 #include <ogr_spatialref.h>
36 #include <cpl_error.h>
37 
38 using std::string;
39 
40 
41 /****************************************************************/
42 /******************** Geographic Transformation *****************/
43 
44 // Default spatial reference system.
45 //
46 #define OM_WGS84 "GEOGCS[\"WGS84\", DATUM[\"WGS84\", \
47  SPHEROID[\"WGS84\", 6378137.0, 298.257223563]], \
48  PRIMEM[\"Greenwich\", 0.0], \
49  UNIT[\"degree\",0.017453292519943295], \
50  AXIS[\"Longitude\",EAST], AXIS[\"Latitude\",NORTH]]"
51 
52 
53 void
54 errorHandler( CPLErr eErrClass, int err_no, const char *msg )
55 {
56  Log::instance()->info( "Error: %s\n", msg );
57 }
58 
59 
60 /******************/
61 /*** construtor ***/
62 
64  identity( true ),
65  f_ctin( 0 ),
66  f_ctout( 0 )
67 {
68 
69 }
70 
71 GeoTransform::GeoTransform( const string& dst_desc, const string& src_desc ) :
72  identity( true ),
73  f_ctin( 0 ),
74  f_ctout( 0 )
75 {
76  change( dst_desc, src_desc );
77 }
78 
79 void
81 {
82  //
83  // We need to change the geotransform.
84  // Reset this to the identity - a nice sane state.
85  identity = true;
86  if (f_ctin)
87  delete f_ctin;
88  f_ctin = 0;
89  if (f_ctout)
90  delete f_ctout;
91  f_ctout = 0;
92 }
93 
94 void
95 GeoTransform::change( const string& dst_desc, const string& src_desc )
96 {
97 
98  //
99  // We need to change the geotransform.
100  // Reset this to the identity - a nice sane state.
101  identity = true;
102  if (f_ctin)
103  delete f_ctin;
104  f_ctin = 0;
105  if (f_ctout)
106  delete f_ctout;
107  f_ctout = 0;
108 
109  // If the two coordinate strings are the same, we need the identity transform.
110  // So we can just return.
111  if ( compareCoordSystemStrings( dst_desc.c_str(), src_desc.c_str() ) ) {
112  return;
113  }
114 
115  identity = false;
116 
117  OGRSpatialReference src, dst;
118 
119  // OGRSpatialReference::importFromWkt takes a char** as a parameter.
120  // This parameter points to a variable pointing to the firs character
121  // of the WKT. The variable will be updated to point to the last
122  // character of the WKT used.
123  // Since pointer (dst_desc) are passed by value, we have our own
124  // local copies and can safely take it's address and let importFromWkt
125  // change it.
126  // However, we still need to cast away const-ness :(
127  char * src_desc_noconst = const_cast<char*>(src_desc.c_str());
128  char * dst_desc_noconst = const_cast<char*>(dst_desc.c_str());
129 
130  if ( src.importFromWkt( &src_desc_noconst ) != OGRERR_NONE ||
131  dst.importFromWkt( &dst_desc_noconst ) != OGRERR_NONE )
132  {
133  std::string msg = "Invalid GeoTransform projection:\n src (";
134  msg += src_desc.c_str();
135  msg += ")\n dst (";
136  msg += dst_desc.c_str();
137  msg += ")\n.";
138  Log::instance()->error( msg.c_str() );
139  throw InvalidParameterException( msg );
140  }
141 
142  f_ctin = OGRCreateCoordinateTransformation( &src, &dst );
143 
144  if ( ! f_ctin )
145  {
146  std::string msg = "Invalid GeoTransform projection:\n src (";
147  msg += src_desc.c_str();
148  msg += ")\n dst (";
149  msg += dst_desc.c_str();
150  msg += ")\n.";
151  Log::instance()->error( msg.c_str() );
152  throw InvalidParameterException( msg );
153  }
154 
155  f_ctout = OGRCreateCoordinateTransformation( &dst, &src );
156 
157  if ( ! f_ctout )
158  {
159  std::string msg = "Invalid GeoTransform projection:\n src (";
160  msg += src_desc.c_str();
161  msg += ")\n dst (";
162  msg += dst_desc.c_str();
163  msg += ")\n.";
164  Log::instance()->error( msg.c_str() );
165  throw InvalidParameterException( msg );
166  }
167 
168  // Deactivate GDAL error messages.
169  CPLSetErrorHandler( (CPLErrorHandler) errorHandler );
170 }
171 
172 
173 /*****************/
174 /*** destrutor ***/
175 
177 {
178  if ( f_ctin )
179  delete f_ctin;
180  if ( f_ctout )
181  delete f_ctout;
182 }
183 
184 
185 /*****************/
186 /*** transf In ***/
187 int
188 GeoTransform::transfIn( double *x, double *y ) const
189 {
190  if ( identity )
191  return 1;
192 #ifndef GEO_TRANSFORMATIONS_OFF
193  return f_ctin->Transform( 1, x, y );
194 #else
195  return 1;
196 #endif
197 }
198 
199 
200 /*****************/
201 /*** transf In ***/
202 int
203 GeoTransform::transfIn( double *x, double *y,
204  double x0, double y0 ) const
205 {
206  *x = x0;
207  *y = y0;
208  if ( identity )
209  return 1;
210 
211 #ifndef GEO_TRANSFORMATIONS_OFF
212  return f_ctin->Transform( 1, x, y );
213 #else
214  return 1;
215 #endif
216 }
217 
218 
219 /******************/
220 /*** transf Out ***/
221 int
222 GeoTransform::transfOut( double *x, double *y ) const
223 {
224  if ( identity )
225  return 1;
226 #ifndef GEO_TRANSFORMATIONS_OFF
227  return f_ctout->Transform( 1, x, y );
228 #else
229  return 1;
230 #endif
231 }
232 
233 
234 /******************/
235 /*** transf Out ***/
236 int
237 GeoTransform::transfOut( double *x, double *y,
238  double x0, double y0 ) const
239 {
240  *x = x0;
241  *y = y0;
242  if ( identity )
243  return 1;
244 
245 #ifndef GEO_TRANSFORMATIONS_OFF
246  return f_ctout->Transform( 1, x, y );
247 #else
248  return 1;
249 #endif
250 }
251 
252 /********************/
253 /*** getDefaultCS ***/
255 {
256  return OM_WGS84;
257 }
258 
259 
260 /*********************************/
261 /*** compareCoordSystemStrings ***/
262 bool GeoTransform::compareCoordSystemStrings(char const * s1, char const * s2)
263 {
264  int i = 0, j = 0;
265  while (s1[i])
266  {
267  // skip spaces in both strings
268  while (s1[i] == ' ') i++;
269  while (s2[j] == ' ') j++;
270 
271  if (s1[i] != s2[j]) {
272  return false;
273  }
274 
275  if (s1[i]) i++;
276  if (s2[j]) j++;
277  }
278  // skip trailing spaces that s2 might still have
279  while (s2[j] == ' ') j++;
280 
281  // both s1[i] and s2[j] should be NULL to be equal
282  return (s1[i] == s2[j]);
283 }
#define OM_WGS84
void errorHandler(CPLErr eErrClass, int err_no, const char *msg)
OGRCoordinateTransformation * f_ctin
Definition: GeoTransform.hh:91
static bool compareCoordSystemStrings(char const *s1, char const *s2)
static Log * instance()
Returns the instance pointer, creating the object on the first call.
Definition: Log.cpp:45
int transfIn(double *x, double *y) const
void error(const char *format,...)
'Error' level.
Definition: Log.cpp:290
int transfOut(double *x, double *y) const
static char const * getDefaultCS()
OGRCoordinateTransformation * f_ctout
Definition: GeoTransform.hh:92
void info(const char *format,...)
'Info' level.
Definition: Log.cpp:256