GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
get_projinfo.c
Go to the documentation of this file.
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 */
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>"),
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 */
62 {
63  struct Key_Value *in_proj_keys, *in_epsg_keys;
64  char path[GPATH_MAX];
65 
67  if (access(path, 0) != 0) {
68  if (G_projection() != PROJECTION_XY) {
69  G_warning(_("<%s> file not found for location <%s>"),
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 */
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 
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 
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 }
#define G_malloc(n)
Definition: defs/gis.h:112
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition: file_name.c:38
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
#define PERMANENT
Definition: get_projinfo.c:19
struct Key_Value * G_read_key_value_file(const char *)
Read key/values pairs from file.
Definition: key_value3.c:53
struct Key_Value * G_get_projunits(void)
Gets units information for location.
Definition: get_projinfo.c:32
int G_projection(void)
Query cartographic projection.
Definition: proj1.c:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:149
#define PROJECTION_XY
Projection code - XY coordinate system (unreferenced data)
Definition: gis.h:110
#define NULL
Definition: ccmath.h:32
const char * G_location(void)
Get current location name.
Definition: location.c:32
char * G_get_projwkt(void)
Get WKT information for the current location.
Definition: get_projinfo.c:127
void G_set_key_value(const char *, const char *, struct Key_Value *)
Set value for given key.
Definition: key_value1.c:38
#define GPATH_MAX
Definition: gis.h:170
char * G_get_projsrid(void)
Get srid (spatial reference id) for the current location.
Definition: get_projinfo.c:233
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
Definition: get_projinfo.c:61
Definition: gis.h:501
int nalloc
Definition: gis.h:504
char * G_chop(char *)
Chop leading and trailing white spaces.
Definition: strings.c:328
struct Key_Value * G_get_projepsg(void)
Gets EPSG information for the current location.
Definition: get_projinfo.c:102
#define EPSG_FILE
Definition: gis.h:122
void G_warning(const char *,...) __attribute__((format(printf
#define SRID_FILE
Definition: gis.h:124
Definition: path.h:16
#define G_realloc(p, n)
Definition: defs/gis.h:114
#define WKT_FILE
Definition: gis.h:123
#define _(str)
Definition: glocale.h:10
#define UNIT_FILE
Definition: gis.h:121
int G_asprintf(char **, const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
Definition: key_value1.c:103
#define PROJECTION_FILE
Definition: gis.h:120
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition: key_value1.c:84