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