1 /*!
2 \file lib/gis/get_projinfo.c
3
4 \brief GIS Library - Get projection info
5
6 (C) 1999-2014 by the GRASS Development Team
7
8 This program is free software under the GNU General Public License
9 (>=v2). Read the file COPYING that comes with GRASS for details.
10 */
11
12 #include <string.h>
13 #include <errno.h>
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <grass/gis.h>
17 #include <grass/glocale.h>
18
19 #define PERMANENT "PERMANENT"
20
21 /*!
22 \brief Gets units information for location
23
24 Note: Allocated Key_Value structure should be freed by
25 G_free_key_value().
26
27 Prints a warning if no units information available.
28
29 \return pointer to Key_Value structure with key/value pairs
30 \return NULL on failure
31 */
G_get_projunits(void)32 struct Key_Value *G_get_projunits(void)
33 {
34 struct Key_Value *in_units_keys;
35 char path[GPATH_MAX];
36
37 G_file_name(path, "", UNIT_FILE, PERMANENT);
38 if (access(path, 0) != 0) {
39 if (G_projection() != PROJECTION_XY) {
40 G_warning(_("<%s> file not found for location <%s>"),
41 UNIT_FILE, G_location());
42 }
43 return NULL;
44 }
45 in_units_keys = G_read_key_value_file(path);
46
47 return in_units_keys;
48 }
49
50 /*!
51 \brief Gets projection information for location
52
53 Note: Allocated Key_Value structure should be freed by
54 G_free_key_value().
55
56 Prints a warning if no projection information available.
57
58 \return pointer to Key_Value structure with key/value pairs
59 \return NULL on failure
60 */
G_get_projinfo(void)61 struct Key_Value *G_get_projinfo(void)
62 {
63 struct Key_Value *in_proj_keys, *in_epsg_keys;
64 char path[GPATH_MAX];
65
66 G_file_name(path, "", PROJECTION_FILE, PERMANENT);
67 if (access(path, 0) != 0) {
68 if (G_projection() != PROJECTION_XY) {
69 G_warning(_("<%s> file not found for location <%s>"),
70 PROJECTION_FILE, G_location());
71 }
72 return NULL;
73 }
74 in_proj_keys = G_read_key_value_file(path);
75
76 /* TODO: do not restrict to EPSG as the only authority */
77 if ((in_epsg_keys = G_get_projepsg()) != NULL) {
78 const char *epsgstr = G_find_key_value("epsg", in_epsg_keys);
79 char buf[4096];
80
81 sprintf(buf, "EPSG:%s", epsgstr);
82 G_set_key_value("init", buf, in_proj_keys);
83 G_free_key_value(in_epsg_keys);
84 }
85
86 return in_proj_keys;
87 }
88
89 /*!
90 \brief Gets EPSG information for the current location
91
92 DEPRECATED: Use G_get_projsrid() instead.
93
94 Note: Allocated Key_Value structure should be freed by
95 G_free_key_value().
96
97 \return pointer to Key_Value structure with key/value pairs
98 \return NULL when EPSG code is not defined for location
99 */
100
101 /* superseded by G_get_projsrid(), keep for backwards compatibility */
G_get_projepsg(void)102 struct Key_Value *G_get_projepsg(void)
103 {
104 struct Key_Value *in_epsg_keys;
105 char path[GPATH_MAX];
106
107 G_file_name(path, "", EPSG_FILE, PERMANENT);
108 if (access(path, 0) != 0) {
109 if (G_projection() != PROJECTION_XY) {
110 G_debug(1, "<%s> file not found for location <%s>",
111 EPSG_FILE, G_location());
112 }
113 return NULL;
114 }
115 in_epsg_keys = G_read_key_value_file(path);
116
117 return in_epsg_keys;
118 }
119
120 /*!
121 \brief Get WKT information for the current location
122
123 \return pointer to WKT string
124 \return NULL when WKT is not available for the current location
125 */
126
G_get_projwkt(void)127 char *G_get_projwkt(void)
128 {
129 char *wktstring = NULL;
130 char path[GPATH_MAX];
131 FILE *fp;
132 int n, nalloc;
133 int c;
134
135 G_file_name(path, "", WKT_FILE, "PERMANENT");
136 if (access(path, 0) != 0) {
137 if (G_projection() != PROJECTION_XY) {
138 G_debug(1, "<%s> file not found for location <%s>",
139 WKT_FILE, G_location());
140 }
141 return NULL;
142 }
143
144 fp = fopen(path, "r");
145 if (!fp)
146 G_fatal_error(_("Unable to open input file <%s>: %s"), path, strerror(errno));
147
148 wktstring = G_malloc(1024 * sizeof(char));
149 nalloc = 1024;
150
151 n = 0;
152 while (1) {
153 c = fgetc(fp);
154
155 if (c == EOF) {
156 break;
157 }
158
159 if (c == '\r') { /* DOS or MacOS9 */
160 c = fgetc(fp);
161 if (c != EOF) {
162 if (c != '\n') { /* MacOS9 - we have to return the char to stream */
163 ungetc(c, fp);
164 c = '\n';
165 }
166 }
167 else { /* MacOS9 - we have to return the char to stream */
168 ungetc(c, fp);
169 c = '\n';
170 }
171 }
172
173 if (n == nalloc) {
174 wktstring = G_realloc(wktstring, nalloc + 1024);
175 nalloc += 1024;
176 }
177
178 wktstring[n] = c;
179
180 n++;
181 }
182
183 if (n > 0) {
184 if (n == nalloc) {
185 wktstring = G_realloc(wktstring, nalloc + 1);
186 nalloc += 1;
187 }
188 wktstring[n] = '\0';
189 }
190 else {
191 G_free(wktstring);
192 wktstring = NULL;
193 }
194
195 if (fclose(fp) != 0)
196 G_fatal_error(_("Error closing output file <%s>: %s"), path, strerror(errno));
197
198 if (wktstring && *wktstring)
199 G_chop(wktstring);
200 if (wktstring && *wktstring == '\0') {
201 G_free(wktstring);
202 wktstring = NULL;
203 }
204
205 return wktstring;
206 }
207
208 /*!
209 \brief Get srid (spatial reference id) for the current location
210
211 Typically an srid will be of the form authority NAME:CODE,
212 e.g. EPSG:4326
213
214 This srid is passed to proj_create() using PROJ or
215 OSRSetFromUserInput() using GDAL. Therefore various other forms of
216 srid are possible, e.g. in OSRSetFromUserInput():
217
218 1. Well Known Text definition - passed on to importFromWkt().
219 2. "EPSG:n" - number passed on to importFromEPSG().
220 3. "EPSGA:n" - number passed on to importFromEPSGA().
221 4. "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
222 5. "urn:ogc:def:crs:EPSG::n" - ogc urns
223 6. PROJ.4 definitions - passed on to importFromProj4().
224 7. filename - file read for WKT, XML or PROJ.4 definition.
225 8. well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83, WGS84 or WGS72.
226 9. "IGNF:xxxx", "ESRI:xxxx", etc. from definitions from the PROJ database;
227 10. PROJJSON (PROJ >= 6.2)
228
229 \return pointer to srid string
230 \return NULL when srid is not available for the current location
231 */
232
G_get_projsrid(void)233 char *G_get_projsrid(void)
234 {
235 char *sridstring = NULL;
236 char path[GPATH_MAX];
237 FILE *fp;
238 int n, nalloc;
239 int c;
240
241 G_file_name(path, "", SRID_FILE, "PERMANENT");
242 if (access(path, 0) != 0) {
243 if (G_projection() != PROJECTION_XY) {
244 struct Key_Value *projepsg;
245 const char *epsg_num;
246
247 G_debug(1, "<%s> file not found for location <%s>",
248 SRID_FILE, G_location());
249
250 /* for backwards compatibility, check if PROJ_EPSG exists */
251 if ((projepsg = G_get_projepsg()) != NULL) {
252 epsg_num = G_find_key_value("epsg", projepsg);
253 if (*epsg_num) {
254 G_debug(1, "Using <%s> file instead for location <%s>",
255 EPSG_FILE, G_location());
256 G_asprintf(&sridstring, "EPSG:%s", epsg_num);
257 G_free_key_value(projepsg);
258
259 return sridstring;
260 }
261 }
262 }
263 return NULL;
264 }
265
266 fp = fopen(path, "r");
267 if (!fp)
268 G_fatal_error(_("Unable to open input file <%s>: %s"), path, strerror(errno));
269
270 sridstring = G_malloc(1024 * sizeof(char));
271 nalloc = 1024;
272
273 n = 0;
274 while (1) {
275 c = fgetc(fp);
276
277 if (c == EOF) {
278 break;
279 }
280
281 if (c == '\r') { /* DOS or MacOS9 */
282 c = fgetc(fp);
283 if (c != EOF) {
284 if (c != '\n') { /* MacOS9 - we have to return the char to stream */
285 ungetc(c, fp);
286 c = '\n';
287 }
288 }
289 else { /* MacOS9 - we have to return the char to stream */
290 ungetc(c, fp);
291 c = '\n';
292 }
293 }
294
295 if (n == nalloc) {
296 sridstring = G_realloc(sridstring, nalloc + 1024);
297 nalloc += 1024;
298 }
299
300 sridstring[n] = c;
301
302 n++;
303 }
304
305 if (n > 0) {
306 if (n == nalloc) {
307 sridstring = G_realloc(sridstring, nalloc + 1);
308 nalloc += 1;
309 }
310 sridstring[n] = '\0';
311 }
312 else {
313 G_free(sridstring);
314 sridstring = NULL;
315 }
316
317 if (fclose(fp) != 0)
318 G_fatal_error(_("Error closing output file <%s>: %s"), path, strerror(errno));
319
320 if (sridstring && *sridstring)
321 G_chop(sridstring);
322 if (sridstring && *sridstring == '\0') {
323 G_free(sridstring);
324 sridstring = NULL;
325 }
326
327 return sridstring;
328 }
329