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