1 /******************************************************************************
2  *
3  * Project:  OpenGIS Simple Features Reference Implementation
4  * Purpose:  Implement importFromDict() method to read a WKT SRS from a
5  *           coordinate system dictionary in a simple text format.
6  * Author:   Frank Warmerdam, warmerdam@pobox.com
7  *
8  ******************************************************************************
9  * Copyright (c) 2004, Frank Warmerdam
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 "cpl_port.h"
31 #include "ogr_spatialref.h"
32 
33 #include <cstring>
34 
35 #include "cpl_conv.h"
36 #include "cpl_error.h"
37 #include "cpl_string.h"
38 #include "cpl_vsi.h"
39 #include "ogr_core.h"
40 #include "ogr_srs_api.h"
41 
42 CPL_CVSID("$Id: ogr_srs_dict.cpp 8e5eeb35bf76390e3134a4ea7076dab7d478ea0e 2018-11-14 22:55:13 +0100 Even Rouault $")
43 
44 /************************************************************************/
45 /*                           importFromDict()                           */
46 /************************************************************************/
47 
48 /**
49  * Read SRS from WKT dictionary.
50  *
51  * This method will attempt to find the indicated coordinate system identity
52  * in the indicated dictionary file.  If found, the WKT representation is
53  * imported and used to initialize this OGRSpatialReference.
54  *
55  * More complete information on the format of the dictionary files can
56  * be found in the epsg.wkt file in the GDAL data tree.  The dictionary
57  * files are searched for in the "GDAL" domain using CPLFindFile().  Normally
58  * this results in searching /usr/local/share/gdal or somewhere similar.
59  *
60  * This method is the same as the C function OSRImportFromDict().
61  *
62  * @param pszDictFile the name of the dictionary file to load.
63  *
64  * @param pszCode the code to lookup in the dictionary.
65  *
66  * @return OGRERR_NONE on success, or OGRERR_SRS_UNSUPPORTED if the code isn't
67  * found, and OGRERR_SRS_FAILURE if something more dramatic goes wrong.
68  */
69 
importFromDict(const char * pszDictFile,const char * pszCode)70 OGRErr OGRSpatialReference::importFromDict( const char *pszDictFile,
71                                             const char *pszCode )
72 
73 {
74     CPLString osWKT(lookupInDict(pszDictFile, pszCode));
75     if( osWKT.empty() )
76         return OGRERR_UNSUPPORTED_SRS;
77 
78     OGRErr eErr = importFromWkt( osWKT );
79     if( eErr == OGRERR_NONE && strstr(pszDictFile, "esri_") == nullptr )
80     {
81         morphFromESRI();
82     }
83 
84     return eErr;
85 }
86 
87 /************************************************************************/
88 /*                          lookupInDict()                              */
89 /************************************************************************/
90 
lookupInDict(const char * pszDictFile,const char * pszCode)91 CPLString OGRSpatialReference::lookupInDict( const char *pszDictFile,
92                                              const char *pszCode )
93 
94 {
95 /* -------------------------------------------------------------------- */
96 /*      Find and open file.                                             */
97 /* -------------------------------------------------------------------- */
98     CPLString osDictFile(pszDictFile);
99     const char *pszFilename = CPLFindFile( "gdal", pszDictFile );
100     if( pszFilename == nullptr )
101         return CPLString();
102 
103     VSILFILE *fp = VSIFOpenL( pszFilename, "rb" );
104     if( fp == nullptr )
105         return CPLString();
106 
107 /* -------------------------------------------------------------------- */
108 /*      Process lines.                                                  */
109 /* -------------------------------------------------------------------- */
110     CPLString osWKT;
111     const char *pszLine = nullptr;
112 
113     while( (pszLine = CPLReadLineL(fp)) != nullptr )
114 
115     {
116         if( pszLine[0] == '#' )
117             continue;
118 
119         if( STARTS_WITH_CI(pszLine, "include ") )
120         {
121             osWKT = lookupInDict( pszLine + 8, pszCode );
122             if( !osWKT.empty() )
123                 break;
124             continue;
125         }
126 
127         if( strstr(pszLine, ",") == nullptr )
128             continue;
129 
130         if( EQUALN(pszLine, pszCode, strlen(pszCode))
131             && pszLine[strlen(pszCode)] == ',' )
132         {
133             osWKT = pszLine + strlen(pszCode)+1;
134             break;
135         }
136     }
137 
138 /* -------------------------------------------------------------------- */
139 /*      Cleanup                                                         */
140 /* -------------------------------------------------------------------- */
141     VSIFCloseL( fp );
142 
143     return osWKT;
144 }
145 
146 /************************************************************************/
147 /*                         OSRImportFromDict()                          */
148 /************************************************************************/
149 
150 /**
151  * Read SRS from WKT dictionary.
152  *
153  * This method will attempt to find the indicated coordinate system identity
154  * in the indicated dictionary file.  If found, the WKT representation is
155  * imported and used to initialize this OGRSpatialReference.
156  *
157  * More complete information on the format of the dictionary files can
158  * be found in the epsg.wkt file in the GDAL data tree.  The dictionary
159  * files are searched for in the "GDAL" domain using CPLFindFile().  Normally
160  * this results in searching /usr/local/share/gdal or somewhere similar.
161  *
162  * This method is the same as the C++ method
163  * OGRSpatialReference::importFromDict().
164  *
165  * @param hSRS spatial reference system handle.
166  *
167  * @param pszDictFile the name of the dictionary file to load.
168  *
169  * @param pszCode the code to lookup in the dictionary.
170  *
171  * @return OGRERR_NONE on success, or OGRERR_SRS_UNSUPPORTED if the code isn't
172  * found, and OGRERR_SRS_FAILURE if something more dramatic goes wrong.
173  */
174 
OSRImportFromDict(OGRSpatialReferenceH hSRS,const char * pszDictFile,const char * pszCode)175 OGRErr OSRImportFromDict( OGRSpatialReferenceH hSRS,
176                           const char *pszDictFile,
177                           const char *pszCode )
178 
179 {
180     VALIDATE_POINTER1( hSRS, "OSRImportFromDict", OGRERR_FAILURE );
181 
182     return reinterpret_cast<OGRSpatialReference *>(hSRS)->
183         importFromDict( pszDictFile, pszCode );
184 }
185