1 : /******************************************************************************
2 : * $Id: ogr_srs_erm.cpp 22996 2011-08-28 09:27:35Z rouault $
3 : *
4 : * Project: OpenGIS Simple Features Reference Implementation
5 : * Purpose: Implement ERMapper projection conversions.
6 : * Author: Frank Warmerdam, warmerdam@pobox.com
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, Frank Warmerdam <warmerdam@pobox.com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "ogr_spatialref.h"
31 : #include "cpl_conv.h"
32 :
33 : CPL_CVSID("$Id: ogr_srs_erm.cpp 22996 2011-08-28 09:27:35Z rouault $");
34 :
35 : /************************************************************************/
36 : /* OSRImportFromERM() */
37 : /************************************************************************/
38 :
39 : /**
40 : * \brief Create OGR WKT from ERMapper projection definitions.
41 : *
42 : * This function is the same as OGRSpatialReference::importFromERM().
43 : */
44 :
45 6 : OGRErr OSRImportFromERM( OGRSpatialReferenceH hSRS, const char *pszProj,
46 : const char *pszDatum, const char *pszUnits )
47 :
48 : {
49 6 : VALIDATE_POINTER1( hSRS, "OSRImportFromERM", CE_Failure );
50 :
51 : return ((OGRSpatialReference *) hSRS)->importFromERM( pszProj,
52 : pszDatum,
53 6 : pszUnits );
54 : }
55 :
56 : /************************************************************************/
57 : /* importFromERM() */
58 : /************************************************************************/
59 :
60 : /**
61 : * Create OGR WKT from ERMapper projection definitions.
62 : *
63 : * Generates an OGRSpatialReference definition from an ERMapper datum
64 : * and projection name. Based on the ecw_cs.wkt dictionary file from
65 : * gdal/data.
66 : *
67 : * @param pszProj the projection name, such as "NUTM11" or "GEOGRAPHIC".
68 : * @param pszDatum the datum name, such as "NAD83".
69 : * @param pszUnits the linear units "FEET" or "METERS".
70 : *
71 : * @return OGRERR_NONE on success or OGRERR_UNSUPPORTED_SRS if not found.
72 : */
73 :
74 67 : OGRErr OGRSpatialReference::importFromERM( const char *pszProj,
75 : const char *pszDatum,
76 : const char *pszUnits )
77 :
78 : {
79 67 : Clear();
80 :
81 : /* -------------------------------------------------------------------- */
82 : /* do we have projection and datum? */
83 : /* -------------------------------------------------------------------- */
84 67 : if( EQUAL(pszProj,"RAW") )
85 40 : return OGRERR_NONE;
86 :
87 : /* -------------------------------------------------------------------- */
88 : /* Do we have an EPSG coordinate system? */
89 : /* -------------------------------------------------------------------- */
90 :
91 27 : if( EQUALN(pszProj,"EPSG:",5) )
92 1 : return importFromEPSG( atoi(pszProj+5) );
93 :
94 :
95 26 : if( EQUALN(pszDatum,"EPSG:",5) )
96 0 : return importFromEPSG( atoi(pszDatum+5) );
97 :
98 : /* -------------------------------------------------------------------- */
99 : /* Set projection if we have it. */
100 : /* -------------------------------------------------------------------- */
101 : OGRErr eErr;
102 :
103 26 : if( EQUAL(pszProj,"GEODETIC") )
104 : {
105 : }
106 : else
107 : {
108 24 : eErr = importFromDict( "ecw_cs.wkt", pszProj );
109 24 : if( eErr != OGRERR_NONE )
110 0 : return eErr;
111 :
112 24 : if( EQUAL(pszUnits,"FEET") )
113 4 : SetLinearUnits( SRS_UL_US_FOOT, atof(SRS_UL_US_FOOT_CONV));
114 : else
115 20 : SetLinearUnits( SRS_UL_METER, 1.0 );
116 : }
117 :
118 : /* -------------------------------------------------------------------- */
119 : /* Set the geogcs. */
120 : /* -------------------------------------------------------------------- */
121 26 : OGRSpatialReference oGeogCS;
122 :
123 26 : eErr = oGeogCS.importFromDict( "ecw_cs.wkt", pszDatum );
124 26 : if( eErr != OGRERR_NONE )
125 : {
126 0 : Clear();
127 0 : return eErr;
128 : }
129 :
130 26 : if( !IsLocal() )
131 26 : CopyGeogCSFrom( &oGeogCS );
132 :
133 26 : return OGRERR_NONE;
134 : }
135 :
136 : /************************************************************************/
137 : /* OSRExportToERM() */
138 : /************************************************************************/
139 : /**
140 : * \brief Convert coordinate system to ERMapper format.
141 : *
142 : * This function is the same as OGRSpatialReference::exportToERM().
143 : */
144 0 : OGRErr OSRExportToERM( OGRSpatialReferenceH hSRS,
145 : char *pszProj, char *pszDatum, char *pszUnits )
146 :
147 : {
148 0 : VALIDATE_POINTER1( hSRS, "OSRExportToERM", CE_Failure );
149 :
150 : return ((OGRSpatialReference *) hSRS)->exportToERM( pszProj, pszDatum,
151 0 : pszUnits );
152 : }
153 :
154 : /************************************************************************/
155 : /* exportToERM() */
156 : /************************************************************************/
157 :
158 : /**
159 : * Convert coordinate system to ERMapper format.
160 : *
161 : * @param pszProj 32 character buffer to receive projection name.
162 : * @param pszDatum 32 character buffer to recieve datum name.
163 : * @param pszUnits 32 character buffer to receive units name.
164 : *
165 : * @return OGRERR_NONE on success, OGRERR_SRS_UNSUPPORTED if not translation is
166 : * found, or OGRERR_FAILURE on other failures.
167 : */
168 :
169 37 : OGRErr OGRSpatialReference::exportToERM( char *pszProj, char *pszDatum,
170 : char *pszUnits )
171 :
172 : {
173 37 : strcpy( pszProj, "RAW" );
174 37 : strcpy( pszDatum, "RAW" );
175 37 : strcpy( pszUnits, "METERS" );
176 :
177 37 : if( !IsProjected() && !IsGeographic() )
178 0 : return TRUE;
179 :
180 : /* -------------------------------------------------------------------- */
181 : /* Try to find the EPSG code. */
182 : /* -------------------------------------------------------------------- */
183 37 : int nEPSGCode = 0;
184 :
185 37 : if( IsProjected() )
186 : {
187 4 : const char *pszAuthName = GetAuthorityName( "PROJCS" );
188 :
189 4 : if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") )
190 : {
191 1 : nEPSGCode = atoi(GetAuthorityCode( "PROJCS" ));
192 : }
193 : }
194 33 : else if( IsGeographic() )
195 : {
196 33 : const char *pszAuthName = GetAuthorityName( "GEOGCS" );
197 :
198 33 : if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") )
199 : {
200 12 : nEPSGCode = atoi(GetAuthorityCode( "GEOGCS" ));
201 : }
202 : }
203 :
204 : /* -------------------------------------------------------------------- */
205 : /* Is our GEOGCS name already defined in ecw_cs.dat? */
206 : /* -------------------------------------------------------------------- */
207 37 : OGRSpatialReference oSRSWork;
208 37 : const char *pszWKTDatum = GetAttrValue( "DATUM" );
209 :
210 37 : if( pszWKTDatum != NULL
211 : && oSRSWork.importFromDict( "ecw_cs.wkt", pszWKTDatum ) == OGRERR_NONE)
212 : {
213 0 : strncpy( pszDatum, pszWKTDatum, 32 );
214 0 : pszDatum[31] = '\0';
215 : }
216 :
217 : /* -------------------------------------------------------------------- */
218 : /* Is this a "well known" geographic coordinate system? */
219 : /* -------------------------------------------------------------------- */
220 37 : if( EQUAL(pszDatum,"RAW") )
221 : {
222 37 : int nEPSGGCSCode = GetEPSGGeogCS();
223 :
224 37 : if( nEPSGGCSCode == 4326 )
225 34 : strcpy( pszDatum, "WGS84" );
226 :
227 3 : else if( nEPSGGCSCode == 4322 )
228 0 : strcpy( pszDatum, "WGS72DOD" );
229 :
230 3 : else if( nEPSGGCSCode == 4267 )
231 3 : strcpy( pszDatum, "NAD27" );
232 :
233 0 : else if( nEPSGGCSCode == 4269 )
234 0 : strcpy( pszDatum, "NAD83" );
235 :
236 0 : else if( nEPSGGCSCode == 4277 )
237 0 : strcpy( pszDatum, "OSGB36" );
238 :
239 0 : else if( nEPSGGCSCode == 4278 )
240 0 : strcpy( pszDatum, "OSGB78" );
241 :
242 0 : else if( nEPSGGCSCode == 4201 )
243 0 : strcpy( pszDatum, "ADINDAN" );
244 :
245 0 : else if( nEPSGGCSCode == 4202 )
246 0 : strcpy( pszDatum, "AGD66" );
247 :
248 0 : else if( nEPSGGCSCode == 4203 )
249 0 : strcpy( pszDatum, "AGD84" );
250 :
251 0 : else if( nEPSGGCSCode == 4209 )
252 0 : strcpy( pszDatum, "ARC1950" );
253 :
254 0 : else if( nEPSGGCSCode == 4210 )
255 0 : strcpy( pszDatum, "ARC1960" );
256 :
257 0 : else if( nEPSGGCSCode == 4275 )
258 0 : strcpy( pszDatum, "NTF" );
259 :
260 0 : else if( nEPSGGCSCode == 4283 )
261 0 : strcpy( pszDatum, "GDA94" );
262 :
263 0 : else if( nEPSGGCSCode == 4284 )
264 0 : strcpy( pszDatum, "PULKOVO" );
265 : }
266 :
267 : /* -------------------------------------------------------------------- */
268 : /* Are we working with a geographic (geodetic) coordinate system? */
269 : /* -------------------------------------------------------------------- */
270 :
271 37 : if( IsGeographic() )
272 : {
273 33 : if( EQUAL(pszDatum,"RAW") )
274 0 : return OGRERR_UNSUPPORTED_SRS;
275 : else
276 : {
277 33 : strcpy( pszProj, "GEODETIC" );
278 33 : return OGRERR_NONE;
279 : }
280 : }
281 :
282 : /* -------------------------------------------------------------------- */
283 : /* Is this a UTM projection? */
284 : /* -------------------------------------------------------------------- */
285 : int bNorth, nZone;
286 :
287 4 : nZone = GetUTMZone( &bNorth );
288 4 : if( nZone > 0 )
289 : {
290 3 : if( EQUAL(pszDatum,"GDA94") && !bNorth && nZone >= 48 && nZone <= 58)
291 : {
292 0 : sprintf( pszProj, "MGA%02d", nZone );
293 : }
294 : else
295 : {
296 3 : if( bNorth )
297 3 : sprintf( pszProj, "NUTM%02d", nZone );
298 : else
299 0 : sprintf( pszProj, "SUTM%02d", nZone );
300 : }
301 : }
302 :
303 : /* -------------------------------------------------------------------- */
304 : /* Is our PROJCS name already defined in ecw_cs.dat? */
305 : /* -------------------------------------------------------------------- */
306 : else
307 : {
308 1 : const char *pszPROJCS = GetAttrValue( "PROJCS" );
309 :
310 1 : if( pszPROJCS != NULL
311 : && oSRSWork.importFromDict( "ecw_cs.wkt", pszPROJCS ) == OGRERR_NONE
312 : && oSRSWork.IsProjected() )
313 : {
314 1 : strncpy( pszProj, pszPROJCS, 32 );
315 1 : pszProj[31] = '\0';
316 : }
317 : }
318 :
319 : /* -------------------------------------------------------------------- */
320 : /* If we have not translated it yet, but we have an EPSG code */
321 : /* then use EPSG:n notation. */
322 : /* -------------------------------------------------------------------- */
323 4 : if( (EQUAL(pszDatum,"RAW") || EQUAL(pszProj,"RAW")) && nEPSGCode != 0 )
324 : {
325 0 : sprintf( pszProj, "EPSG:%d", nEPSGCode );
326 0 : sprintf( pszDatum, "EPSG:%d", nEPSGCode );
327 : }
328 :
329 : /* -------------------------------------------------------------------- */
330 : /* Handle the units. */
331 : /* -------------------------------------------------------------------- */
332 4 : double dfUnits = GetLinearUnits();
333 :
334 4 : if( fabs(dfUnits-0.3048) < 0.0001 )
335 1 : strcpy( pszUnits, "FEET" );
336 : else
337 3 : strcpy( pszUnits, "METERS" );
338 :
339 4 : if( EQUAL(pszProj,"RAW") )
340 0 : return OGRERR_UNSUPPORTED_SRS;
341 : else
342 4 : return OGRERR_NONE;
343 : }
|