1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: GDAL Utilities
5 : * Purpose: Commandline application to list info about a given CRS.
6 : * Outputs a number of formats (WKT, PROJ.4, etc.).
7 : * Author: Frank Warmerdam, warmerdam@pobox.com
8 : * Etienne Tourigny, etourigny.dev-at-gmail-dot-com
9 : *
10 : * ****************************************************************************
11 : * Copyright (c) 1998, Frank Warmerdam
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : ****************************************************************************/
31 :
32 : #include "gdal_priv.h"
33 : #include "cpl_string.h"
34 : #include "ogr_spatialref.h"
35 : #include "ogr_api.h"
36 : #include "ogrsf_frmts.h"
37 :
38 : CPL_CVSID("$Id$");
39 :
40 : int FindSRS( const char *pszInput, OGRSpatialReference &oSRS );
41 : CPLErr PrintSRS( const OGRSpatialReference &oSRS,
42 : const char * pszOutputType,
43 : int bPretty, int bPrintSep );
44 : void PrintSRSOutputTypes( const OGRSpatialReference &oSRS,
45 : const char ** papszOutputTypes );
46 : int FindEPSG( const OGRSpatialReference &oSRS );
47 : int SearchCSVForWKT( const char *pszFileCSV, const char *pszTarget );
48 :
49 : /************************************************************************/
50 : /* Usage() */
51 : /************************************************************************/
52 :
53 0 : void Usage()
54 :
55 : {
56 : printf( "\nUsage: gdalsrsinfo [options] srs_def\n"
57 : "\n"
58 : "srs_def may be the filename of a dataset supported by GDAL/OGR "
59 : "from which to extract SRS information\n"
60 : "OR any of the usual GDAL/OGR forms "
61 : "(complete WKT, PROJ.4, EPSG:n or a file containing the SRS)\n"
62 : "\n"
63 : "Options: \n"
64 : " [--help-general] [-h] Show help and exit\n"
65 : " [-p] Pretty-print where applicable (e.g. WKT)\n"
66 : " [-V] Validate SRS\n"
67 : " [-e] Search for EPSG number corresponding to SRS (experimental)\n"
68 : " [-o out_type] Output type { default, all, wkt_all,\n"
69 : " proj4, epsg,\n"
70 : " wkt, wkt_simple, wkt_noct, wkt_esri,\n"
71 0 : " mapinfo, xml }\n\n" );
72 0 : exit( 1 );
73 : }
74 :
75 :
76 : /************************************************************************/
77 : /* main() */
78 : /************************************************************************/
79 :
80 34 : int main( int argc, char ** argv )
81 :
82 : {
83 : int i;
84 34 : int bGotSRS = FALSE;
85 34 : int bPretty = FALSE;
86 34 : int bValidate = FALSE;
87 34 : int bFindEPSG = FALSE;
88 34 : int nEPSGCode = -1;
89 34 : const char *pszInput = NULL;
90 34 : const char *pszOutputType = "default";
91 34 : OGRSpatialReference oSRS;
92 :
93 : /* Check strict compilation and runtime library version as we use C++ API */
94 34 : if (! GDAL_CHECK_VERSION(argv[0]))
95 0 : exit(1);
96 :
97 : /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */
98 : /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */
99 : /* for the --format or --formats options */
100 126 : for( i = 1; i < argc; i++ )
101 : {
102 92 : if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") )
103 : {
104 0 : CPLSetConfigOption( argv[i+1], argv[i+2] );
105 :
106 0 : i += 2;
107 : }
108 : }
109 :
110 : /* -------------------------------------------------------------------- */
111 : /* Register standard GDAL and OGR drivers. */
112 : /* -------------------------------------------------------------------- */
113 34 : GDALAllRegister();
114 : #ifdef OGR_ENABLED
115 34 : OGRRegisterAll();
116 : #endif
117 :
118 : /* -------------------------------------------------------------------- */
119 : /* Process --formats option. */
120 : /* Code copied from gcore/gdal_misc.cpp and ogr/ogrutils.cpp. */
121 : /* This is not ideal, but is best for more descriptive output and */
122 : /* we don't want to call OGRGeneralCmdLineProcessor(). */
123 : /* -------------------------------------------------------------------- */
124 126 : for( i = 1; i < argc; i++ )
125 : {
126 92 : if( EQUAL(argv[i], "--formats") )
127 : {
128 : int iDr;
129 :
130 : /* GDAL formats */
131 0 : printf( "Supported Raster Formats:\n" );
132 0 : for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ )
133 : {
134 0 : GDALDriverH hDriver = GDALGetDriver(iDr);
135 : const char *pszRWFlag, *pszVirtualIO;
136 :
137 0 : if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) )
138 0 : pszRWFlag = "rw+";
139 0 : else if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY,
140 : NULL ) )
141 0 : pszRWFlag = "rw";
142 : else
143 0 : pszRWFlag = "ro";
144 :
145 0 : if( GDALGetMetadataItem( hDriver, GDAL_DCAP_VIRTUALIO, NULL) )
146 0 : pszVirtualIO = "v";
147 : else
148 0 : pszVirtualIO = "";
149 :
150 : printf( " %s (%s%s): %s\n",
151 : GDALGetDriverShortName( hDriver ),
152 : pszRWFlag, pszVirtualIO,
153 0 : GDALGetDriverLongName( hDriver ) );
154 : }
155 :
156 : /* OGR formats */
157 : #ifdef OGR_ENABLED
158 0 : printf( "\nSupported Vector Formats:\n" );
159 :
160 0 : OGRSFDriverRegistrar *poR = OGRSFDriverRegistrar::GetRegistrar();
161 :
162 0 : for( iDr = 0; iDr < poR->GetDriverCount(); iDr++ )
163 : {
164 0 : OGRSFDriver *poDriver = poR->GetDriver(iDr);
165 :
166 0 : if( poDriver->TestCapability( ODrCCreateDataSource ) )
167 : printf( " -> \"%s\" (read/write)\n",
168 0 : poDriver->GetName() );
169 : else
170 : printf( " -> \"%s\" (readonly)\n",
171 0 : poDriver->GetName() );
172 : }
173 :
174 : #endif
175 0 : exit(1);
176 :
177 : }
178 : }
179 :
180 : /* -------------------------------------------------------------------- */
181 : /* Register standard GDAL drivers, and process generic GDAL */
182 : /* command options. */
183 : /* -------------------------------------------------------------------- */
184 34 : argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
185 34 : if( argc < 1 )
186 0 : exit( -argc );
187 :
188 : /* -------------------------------------------------------------------- */
189 : /* Parse arguments. */
190 : /* -------------------------------------------------------------------- */
191 98 : for( i = 1; i < argc; i++ )
192 : {
193 66 : CPLDebug( "gdalsrsinfo", "got arg #%d : [%s]", i, argv[i] );
194 :
195 66 : if( EQUAL(argv[i], "--utility_version") )
196 : {
197 : printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
198 2 : argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
199 2 : return 0;
200 : }
201 64 : else if( EQUAL(argv[i], "-h") )
202 0 : Usage();
203 64 : else if( EQUAL(argv[i], "-e") )
204 0 : bFindEPSG = TRUE;
205 90 : else if( EQUAL(argv[i], "-o") && i < argc - 1)
206 26 : pszOutputType = argv[++i];
207 38 : else if( EQUAL(argv[i], "-p") )
208 2 : bPretty = TRUE;
209 36 : else if( EQUAL(argv[i], "-V") )
210 4 : bValidate = TRUE;
211 32 : else if( argv[i][0] == '-' )
212 : {
213 0 : CSLDestroy( argv );
214 0 : Usage();
215 : }
216 : else
217 32 : pszInput = argv[i];
218 : }
219 :
220 32 : if ( pszInput == NULL ) {
221 0 : CSLDestroy( argv );
222 0 : Usage();
223 : }
224 :
225 : /* Search for SRS */
226 32 : bGotSRS = FindSRS( pszInput, oSRS );
227 :
228 : CPLDebug( "gdalsrsinfo",
229 : "bGotSRS: %d bValidate: %d pszOutputType: %s bPretty: %d",
230 32 : bGotSRS, bValidate, pszOutputType, bPretty );
231 :
232 :
233 : /* Make sure we got a SRS */
234 32 : if ( ! bGotSRS ) {
235 : CPLError( CE_Failure, CPLE_AppDefined,
236 : "ERROR - failed to load SRS definition from %s",
237 2 : pszInput );
238 : }
239 :
240 : else {
241 :
242 : /* Find EPSG code - experimental */
243 30 : if ( EQUAL(pszOutputType,"epsg") )
244 0 : bFindEPSG = TRUE;
245 30 : if ( bFindEPSG ) {
246 : CPLError( CE_Warning, CPLE_AppDefined,
247 0 : "EPSG detection is experimental and requires new data files (see bug #4345)" );
248 0 : nEPSGCode = FindEPSG( oSRS );
249 : /* If found, replace oSRS based on EPSG code */
250 0 : if(nEPSGCode != -1) {
251 : CPLDebug( "gdalsrsinfo",
252 0 : "Found EPSG code %d", nEPSGCode );
253 0 : OGRSpatialReference oSRS2;
254 0 : if ( oSRS2.importFromEPSG( nEPSGCode ) == OGRERR_NONE )
255 0 : oSRS = oSRS2;
256 : }
257 : }
258 : /* Validate - not well tested!*/
259 30 : if ( bValidate ) {
260 4 : OGRErr eErr = oSRS.Validate( );
261 4 : if ( eErr != OGRERR_NONE ) {
262 2 : printf( "\nValidate Fails" );
263 2 : if ( eErr == OGRERR_CORRUPT_DATA )
264 2 : printf( " - SRS is not well formed");
265 0 : else if ( eErr == OGRERR_UNSUPPORTED_SRS )
266 0 : printf(" - contains non-standard PROJECTION[] values");
267 2 : printf("\n");
268 : }
269 : else
270 2 : printf( "\nValidate Succeeds\n" );
271 : }
272 :
273 : /* Output */
274 30 : if ( EQUAL("default", pszOutputType ) ) {
275 : /* does this work in MSVC? */
276 : const char* papszOutputTypes[] =
277 4 : { "proj4", "wkt", NULL };
278 4 : if ( bFindEPSG )
279 0 : printf("\nEPSG:%d\n",nEPSGCode);
280 4 : PrintSRSOutputTypes( oSRS, papszOutputTypes );
281 : }
282 26 : else if ( EQUAL("all", pszOutputType ) ) {
283 0 : if ( bFindEPSG )
284 0 : printf("\nEPSG:%d\n\n",nEPSGCode);
285 : const char* papszOutputTypes[] =
286 0 : {"proj4","wkt","wkt_simple","wkt_noct","wkt_esri","mapinfo","xml",NULL};
287 0 : PrintSRSOutputTypes( oSRS, papszOutputTypes );
288 : }
289 26 : else if ( EQUAL("wkt_all", pszOutputType ) ) {
290 : const char* papszOutputTypes[] =
291 0 : { "wkt", "wkt_simple", "wkt_noct", "wkt_esri", NULL };
292 0 : PrintSRSOutputTypes( oSRS, papszOutputTypes );
293 : }
294 : else {
295 26 : if ( bPretty )
296 2 : printf( "\n" );
297 26 : if ( EQUAL(pszOutputType,"epsg") )
298 0 : printf("EPSG:%d\n",nEPSGCode);
299 : else
300 26 : PrintSRS( oSRS, pszOutputType, bPretty, FALSE );
301 26 : if ( bPretty )
302 2 : printf( "\n" );
303 : }
304 :
305 : }
306 :
307 : /* cleanup anything left */
308 32 : GDALDestroyDriverManager();
309 : #ifdef OGR_ENABLED
310 32 : OGRCleanupAll();
311 : #endif
312 32 : CSLDestroy( argv );
313 :
314 32 : return 0;
315 : }
316 :
317 : /************************************************************************/
318 : /* FindSRS() */
319 : /* */
320 : /* Search for SRS from pszInput, update oSRS. */
321 : /************************************************************************/
322 32 : int FindSRS( const char *pszInput, OGRSpatialReference &oSRS )
323 :
324 : {
325 32 : int bGotSRS = FALSE;
326 32 : VSILFILE *fp = NULL;
327 32 : GDALDataset *poGDALDS = NULL;
328 32 : OGRDataSource *poOGRDS = NULL;
329 32 : OGRLayer *poLayer = NULL;
330 32 : char *pszProjection = NULL;
331 32 : CPLErrorHandler oErrorHandler = NULL;
332 32 : int bIsFile = FALSE;
333 32 : OGRErr eErr = CE_None;
334 32 : int bDebug = FALSE;
335 :
336 : /* temporarily supress error messages we may get from xOpen() */
337 32 : bDebug = CSLTestBoolean(CPLGetConfigOption("CPL_DEBUG", "OFF"));
338 32 : if ( ! bDebug )
339 32 : oErrorHandler = CPLSetErrorHandler ( CPLQuietErrorHandler );
340 :
341 : /* Test if argument is a file */
342 32 : fp = VSIFOpenL( pszInput, "r" );
343 32 : if ( fp ) {
344 18 : bIsFile = TRUE;
345 18 : VSIFCloseL( fp );
346 18 : CPLDebug( "gdalsrsinfo", "argument is a file" );
347 : }
348 :
349 : /* try to open with GDAL */
350 32 : CPLDebug( "gdalsrsinfo", "trying to open with GDAL" );
351 32 : poGDALDS = (GDALDataset *) GDALOpen( pszInput, GA_ReadOnly );
352 32 : if ( poGDALDS != NULL && poGDALDS->GetProjectionRef( ) != NULL ) {
353 16 : pszProjection = (char *) poGDALDS->GetProjectionRef( );
354 16 : if( oSRS.importFromWkt( &pszProjection ) == CE_None ) {
355 16 : CPLDebug( "gdalsrsinfo", "got SRS from GDAL" );
356 16 : bGotSRS = TRUE;
357 : }
358 16 : GDALClose( (GDALDatasetH) poGDALDS );
359 16 : if ( ! bGotSRS )
360 0 : CPLDebug( "gdalsrsinfo", "did not open with GDAL" );
361 : }
362 :
363 : #ifdef OGR_ENABLED
364 : /* if unsuccessful, try to open with OGR */
365 32 : if ( ! bGotSRS ) {
366 16 : CPLDebug( "gdalsrsinfo", "trying to open with OGR" );
367 16 : poOGRDS = OGRSFDriverRegistrar::Open( pszInput, FALSE, NULL );
368 16 : if( poOGRDS != NULL ) {
369 2 : poLayer = poOGRDS->GetLayer( 0 );
370 2 : if ( poLayer != NULL ) {
371 2 : OGRSpatialReference *poSRS = poLayer->GetSpatialRef( );
372 2 : if ( poSRS != NULL ) {
373 2 : CPLDebug( "gdalsrsinfo", "got SRS from OGR" );
374 2 : bGotSRS = TRUE;
375 2 : OGRSpatialReference* poSRSClone = poSRS->Clone();
376 2 : oSRS = *poSRSClone;
377 2 : OGRSpatialReference::DestroySpatialReference( poSRSClone );
378 : }
379 : }
380 2 : OGRDataSource::DestroyDataSource( poOGRDS );
381 2 : poOGRDS = NULL;
382 : }
383 16 : if ( ! bGotSRS )
384 14 : CPLDebug( "gdalsrsinfo", "did not open with OGR" );
385 : }
386 : #endif // OGR_ENABLED
387 :
388 : /* Try ESRI file */
389 32 : if ( ! bGotSRS && bIsFile && (strstr(pszInput,".prj") != NULL) ) {
390 : CPLDebug( "gdalsrsinfo",
391 2 : "trying to get SRS from ESRI .prj file [%s]", pszInput );
392 :
393 : char **pszTemp;
394 2 : if ( strstr(pszInput,"ESRI::") != NULL )
395 0 : pszTemp = CSLLoad( pszInput+6 );
396 : else
397 2 : pszTemp = CSLLoad( pszInput );
398 :
399 2 : if( pszTemp ) {
400 2 : eErr = oSRS.importFromESRI( pszTemp );
401 2 : CSLDestroy( pszTemp );
402 : }
403 : else
404 0 : eErr = OGRERR_UNSUPPORTED_SRS;
405 :
406 2 : if( eErr != OGRERR_NONE ) {
407 2 : CPLDebug( "gdalsrsinfo", "did not get SRS from ESRI .prj file" );
408 : }
409 : else {
410 0 : CPLDebug( "gdalsrsinfo", "got SRS from ESRI .prj file" );
411 0 : bGotSRS = TRUE;
412 : }
413 : }
414 :
415 : /* Last resort, try OSRSetFromUserInput() */
416 32 : if ( ! bGotSRS ) {
417 : CPLDebug( "gdalsrsinfo",
418 14 : "trying to get SRS from user input [%s]", pszInput );
419 :
420 14 : eErr = oSRS.SetFromUserInput( pszInput );
421 :
422 14 : if( eErr != OGRERR_NONE ) {
423 2 : CPLDebug( "gdalsrsinfo", "did not get SRS from user input" );
424 : }
425 : else {
426 12 : CPLDebug( "gdalsrsinfo", "got SRS from user input" );
427 12 : bGotSRS = TRUE;
428 : }
429 : }
430 :
431 : /* restore error messages */
432 32 : if ( ! bDebug )
433 32 : CPLSetErrorHandler ( oErrorHandler );
434 :
435 :
436 32 : return bGotSRS;
437 : }
438 :
439 :
440 : /************************************************************************/
441 : /* PrintSRS() */
442 : /* */
443 : /* Print spatial reference in specified format. */
444 : /************************************************************************/
445 34 : CPLErr PrintSRS( const OGRSpatialReference &oSRS,
446 : const char * pszOutputType,
447 : int bPretty, int bPrintSep )
448 :
449 : {
450 34 : if ( ! pszOutputType || EQUAL(pszOutputType,""))
451 0 : return CE_None;
452 :
453 : CPLDebug( "gdalsrsinfo", "PrintSRS( oSRS, %s, %d, %d )\n",
454 34 : pszOutputType, bPretty, bPrintSep );
455 :
456 34 : char *pszOutput = NULL;
457 :
458 34 : if ( EQUAL("proj4", pszOutputType ) ) {
459 14 : if ( bPrintSep ) printf( "PROJ.4 : ");
460 14 : oSRS.exportToProj4( &pszOutput );
461 14 : printf( "\'%s\'\n", pszOutput );
462 : }
463 :
464 20 : else if ( EQUAL("wkt", pszOutputType ) ) {
465 12 : if ( bPrintSep ) printf("OGC WKT :\n");
466 12 : if ( bPretty )
467 6 : oSRS.exportToPrettyWkt( &pszOutput, FALSE );
468 : else
469 6 : oSRS.exportToWkt( &pszOutput );
470 12 : printf("%s\n",pszOutput);
471 : }
472 :
473 8 : else if ( EQUAL("wkt_simple", pszOutputType ) ) {
474 2 : if ( bPrintSep ) printf("OGC WKT (simple) :\n");
475 2 : oSRS.exportToPrettyWkt( &pszOutput, TRUE );
476 2 : printf("%s\n",pszOutput);
477 : }
478 :
479 6 : else if ( EQUAL("wkt_noct", pszOutputType ) ) {
480 2 : if ( bPrintSep ) printf("OGC WKT (no CT) :\n");
481 2 : OGRSpatialReference *poSRS = oSRS.Clone();
482 2 : poSRS->StripCTParms( );
483 2 : if ( bPretty )
484 0 : poSRS->exportToPrettyWkt( &pszOutput, FALSE );
485 : else
486 2 : poSRS->exportToWkt( &pszOutput );
487 2 : OGRSpatialReference::DestroySpatialReference( poSRS );
488 2 : printf("%s\n",pszOutput);
489 : }
490 :
491 4 : else if ( EQUAL("wkt_esri", pszOutputType ) ) {
492 2 : if ( bPrintSep ) printf("ESRI WKT :\n");
493 2 : OGRSpatialReference *poSRS = oSRS.Clone();
494 2 : poSRS->morphToESRI( );
495 2 : if ( bPretty )
496 0 : poSRS->exportToPrettyWkt( &pszOutput, FALSE );
497 : else
498 2 : poSRS->exportToWkt( &pszOutput );
499 2 : OGRSpatialReference::DestroySpatialReference( poSRS );
500 2 : printf("%s\n",pszOutput);
501 : }
502 :
503 2 : else if ( EQUAL("mapinfo", pszOutputType ) ) {
504 2 : if ( bPrintSep ) printf("MAPINFO : ");
505 2 : oSRS.exportToMICoordSys( &pszOutput );
506 2 : printf("\'%s\'\n",pszOutput);
507 : }
508 :
509 0 : else if ( EQUAL("xml", pszOutputType ) ) {
510 0 : if ( bPrintSep ) printf("XML :\n");
511 0 : oSRS.exportToXML( &pszOutput, NULL );
512 0 : printf("%s\n",pszOutput);
513 : }
514 :
515 : else {
516 : CPLError( CE_Failure, CPLE_AppDefined,
517 : "ERROR - %s output not supported",
518 0 : pszOutputType );
519 0 : return CE_Failure;
520 : }
521 :
522 34 : CPLFree( pszOutput );
523 :
524 34 : return CE_None;
525 : }
526 :
527 : /************************************************************************/
528 : /* PrintSRSOutputTypes() */
529 : /* */
530 : /* Print spatial reference in specified formats. */
531 : /************************************************************************/
532 4 : void PrintSRSOutputTypes( const OGRSpatialReference &oSRS,
533 : const char ** papszOutputTypes )
534 :
535 : {
536 4 : int nOutputTypes = CSLCount((char**)papszOutputTypes);
537 4 : printf( "\n" );
538 12 : for ( int i=0; i<nOutputTypes; i++ ) {
539 8 : PrintSRS( oSRS, papszOutputTypes[i], TRUE, TRUE );
540 8 : printf( "\n" );
541 : }
542 4 : }
543 :
544 : /************************************************************************/
545 : /* SearchCSVForWKT() */
546 : /* */
547 : /* Search CSV file for target WKT, return EPSG code (or -1). */
548 : /* For saving space, the file can be compressed (gz) */
549 : /* If CSV file is absent are absent the function silently exits */
550 : /************************************************************************/
551 0 : int SearchCSVForWKT( const char *pszFileCSV, const char *pszTarget )
552 : {
553 0 : const char *pszFilename = NULL;
554 0 : const char *pszWKT = NULL;
555 : char szTemp[1024];
556 0 : int nPos = 0;
557 0 : const char *pszTemp = NULL;
558 :
559 0 : VSILFILE *fp = NULL;
560 0 : OGRSpatialReference oSRS;
561 0 : int nCode = 0;
562 0 : int nFound = -1;
563 :
564 : CPLDebug( "gdalsrsinfo",
565 : "SearchCSVForWKT()\nfile=%s\nWKT=%s\n",
566 0 : pszFileCSV, pszTarget);
567 :
568 : /* -------------------------------------------------------------------- */
569 : /* Find and open file. */
570 : /* -------------------------------------------------------------------- */
571 : // pszFilename = pszFileCSV;
572 0 : pszFilename = CPLFindFile( "gdal", pszFileCSV );
573 0 : if( pszFilename == NULL )
574 : {
575 : CPLDebug( "gdalsrsinfo", "could not find support file %s",
576 0 : pszFileCSV );
577 : // return OGRERR_UNSUPPORTED_SRS;
578 0 : return -1;
579 : }
580 :
581 : /* support gzipped file */
582 0 : if ( strstr( pszFileCSV,".gz") != NULL )
583 0 : sprintf( szTemp, "/vsigzip/%s", pszFilename);
584 : else
585 0 : sprintf( szTemp, "%s", pszFilename);
586 :
587 : CPLDebug( "gdalsrsinfo", "SearchCSVForWKT() using file %s",
588 0 : szTemp );
589 :
590 0 : fp = VSIFOpenL( szTemp, "r" );
591 0 : if( fp == NULL )
592 : {
593 : CPLDebug( "gdalsrsinfo", "could not open support file %s",
594 0 : pszFilename );
595 :
596 : // return OGRERR_UNSUPPORTED_SRS;
597 0 : return -1;
598 : }
599 :
600 : /* -------------------------------------------------------------------- */
601 : /* Process lines. */
602 : /* -------------------------------------------------------------------- */
603 : const char *pszLine;
604 :
605 0 : while( (pszLine = CPLReadLine2L(fp,-1,NULL)) != NULL )
606 :
607 : {
608 : // CPLDebug( "gdalsrsinfo", "read line %s", pszLine );
609 :
610 0 : if( pszLine[0] == '#' )
611 0 : continue;
612 : /* do nothing */;
613 :
614 : // else if( EQUALN(pszLine,"include ",8) )
615 : // {
616 : // eErr = importFromDict( pszLine + 8, pszCode );
617 : // if( eErr != OGRERR_UNSUPPORTED_SRS )
618 : // break;
619 : // }
620 :
621 : // else if( strstr(pszLine,",") == NULL )
622 : // /* do nothing */;
623 :
624 0 : pszTemp = strstr(pszLine,",");
625 0 : if (pszTemp)
626 : {
627 0 : nPos = pszTemp - pszLine;
628 :
629 0 : if ( nPos == 0 )
630 0 : continue;
631 :
632 0 : strncpy( szTemp, pszLine, nPos );
633 0 : szTemp[nPos] = '\0';
634 0 : nCode = atoi(szTemp);
635 :
636 0 : pszWKT = (char *) pszLine + nPos +1;
637 :
638 : // CPLDebug( "gdalsrsinfo",
639 : // "code=%d\nWKT=\n[%s]\ntarget=\n[%s]\n",
640 : // nCode,pszWKT, pszTarget );
641 :
642 0 : if ( EQUAL(pszTarget,pszWKT) )
643 : {
644 0 : nFound = nCode;
645 : CPLDebug( "gdalsrsinfo", "found EPSG:%d\n"
646 : "current=%s\ntarget= %s\n",
647 0 : nCode, pszWKT, pszTarget );
648 0 : break;
649 : }
650 : }
651 : }
652 :
653 0 : VSIFCloseL( fp );
654 :
655 0 : return nFound;
656 :
657 : }
658 :
659 : /* TODO
660 : - search for well-known values (AutoIdentifyEPSG())
661 :
662 : - should we search .override.csv files?
663 :
664 : - fix precision differences (namely in degree: 17 vs 15) so we can use epsg_ogc_simple
665 : target:
666 : orig: GEOGCS["SAD69",DATUM["D_South_American_1969",SPHEROID["GRS_1967_Modified",6378160,298.25]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
667 : ESRI: GEOGCS["SAD69",DATUM["D_South_American_1969",SPHEROID["GRS_1967_Truncated",6378160,298.25]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
668 : OGC: GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS_1967_Modified",6378160,298.25]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
669 : database:
670 : ESRI: GEOGCS["SAD69",DATUM["D_South_American_1969",SPHEROID["GRS_1967_Truncated",6378160,298.25]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
671 : OGC: GEOGCS["SAD69",DATUM["South_American_Datum_1969",SPHEROID["GRS 1967 Modified",6378160,298.25]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433]]
672 : */
673 :
674 : /************************************************************************/
675 : /* FindEPSG() */
676 : /* */
677 : /* Return EPSG code corresponding to spatial reference (or -1) */
678 : /************************************************************************/
679 0 : int FindEPSG( const OGRSpatialReference &oSRS )
680 : {
681 0 : char *pszWKT = NULL;
682 0 : char *pszESRI = NULL;
683 0 : int nFound = -1;
684 0 : OGRSpatialReference *poSRS = NULL;
685 :
686 0 : poSRS = oSRS.Clone();
687 0 : poSRS->StripCTParms();
688 0 : poSRS->exportToWkt( &pszWKT );
689 0 : OGRSpatialReference::DestroySpatialReference( poSRS );
690 :
691 0 : poSRS = oSRS.Clone();
692 0 : poSRS->morphToESRI( );
693 0 : poSRS->exportToWkt( &pszESRI );
694 0 : OGRSpatialReference::DestroySpatialReference( poSRS );
695 :
696 : CPLDebug( "gdalsrsinfo", "FindEPSG()\nWKT (OGC)= %s\nWKT (ESRI)=%s",
697 0 : pszWKT,pszESRI );
698 :
699 : /* search for EPSG code in epsg_*.wkt.gz files */
700 : /* using ESRI WKT for now, as it seems to work best */
701 0 : nFound = SearchCSVForWKT( "epsg_esri.wkt.gz", pszESRI );
702 0 : if ( nFound == -1 )
703 0 : nFound = SearchCSVForWKT( "epsg_ogc_simple.wkt.gz", pszESRI );
704 0 : if ( nFound == -1 )
705 0 : nFound = SearchCSVForWKT( "epsg_ogc.wkt.gz", pszESRI );
706 :
707 :
708 0 : CPLFree( pszWKT );
709 0 : CPLFree( pszESRI );
710 :
711 0 : return nFound;
712 : }
|