GRASS 8 Programmer's Manual  8.5.0dev(2025)-e5e60895a1
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 
38  if (access(path, 0) != 0) {
39  if (G_projection() != PROJECTION_XY) {
40  G_warning(_("<%s> file not found for location <%s>"), UNIT_FILE,
41  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  */
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  snprintf(buf, sizeof(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 
108  if (access(path, 0) != 0) {
109  if (G_projection() != PROJECTION_XY) {
110  G_debug(1, "<%s> file not found for location <%s>", EPSG_FILE,
111  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 char *G_get_projwkt(void)
127 {
128  char *wktstring = NULL;
129  char path[GPATH_MAX];
130  FILE *fp;
131  int n, nalloc;
132  int c;
133 
134  G_file_name(path, "", WKT_FILE, "PERMANENT");
135  if (access(path, 0) != 0) {
136  if (G_projection() != PROJECTION_XY) {
137  G_debug(1, "<%s> file not found for location <%s>", WKT_FILE,
138  G_location());
139  }
140  return NULL;
141  }
142 
143  fp = fopen(path, "r");
144  if (!fp)
145  G_fatal_error(_("Unable to open input file <%s>: %s"), path,
146  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 !=
163  '\n') { /* MacOS9 - we have to return the char to stream */
164  ungetc(c, fp);
165  c = '\n';
166  }
167  }
168  else { /* MacOS9 - we have to return the char to stream */
169  ungetc(c, fp);
170  c = '\n';
171  }
172  }
173 
174  if (n == nalloc) {
175  wktstring = G_realloc(wktstring, nalloc + 1024);
176  nalloc += 1024;
177  }
178 
179  wktstring[n] = c;
180 
181  n++;
182  }
183 
184  if (n > 0) {
185  if (n == nalloc) {
186  wktstring = G_realloc(wktstring, nalloc + 1);
187  nalloc += 1;
188  }
189  wktstring[n] = '\0';
190  }
191  else {
192  G_free(wktstring);
193  wktstring = NULL;
194  }
195 
196  if (fclose(fp) != 0)
197  G_fatal_error(_("Error closing output file <%s>: %s"), path,
198  strerror(errno));
199 
200  if (wktstring && *wktstring)
201  G_chop(wktstring);
202  if (wktstring && *wktstring == '\0') {
203  G_free(wktstring);
204  wktstring = NULL;
205  }
206 
207  return wktstring;
208 }
209 
210 /*!
211  \brief Get srid (spatial reference id) for the current location
212 
213  Typically an srid will be of the form authority NAME:CODE,
214  e.g. EPSG:4326
215 
216  This srid is passed to proj_create() using PROJ or
217  OSRSetFromUserInput() using GDAL. Therefore various other forms of
218  srid are possible, e.g. in OSRSetFromUserInput():
219 
220  1. Well Known Text definition - passed on to importFromWkt().
221  2. "EPSG:n" - number passed on to importFromEPSG().
222  3. "EPSGA:n" - number passed on to importFromEPSGA().
223  4. "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
224  5. "urn:ogc:def:crs:EPSG::n" - ogc urns
225  6. PROJ.4 definitions - passed on to importFromProj4().
226  7. filename - file read for WKT, XML or PROJ.4 definition.
227  8. well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83,
228  WGS84 or WGS72.
229  9. "IGNF:xxxx", "ESRI:xxxx", etc. from definitions from the PROJ database;
230  10. PROJJSON (PROJ >= 6.2)
231 
232  \return pointer to srid string
233  \return NULL when srid is not available for the current location
234  */
235 char *G_get_projsrid(void)
236 {
237  char *sridstring = NULL;
238  char path[GPATH_MAX];
239  FILE *fp;
240  int n, nalloc;
241  int c;
242 
243  G_file_name(path, "", SRID_FILE, "PERMANENT");
244  if (access(path, 0) != 0) {
245  if (G_projection() != PROJECTION_XY) {
246  struct Key_Value *projepsg;
247  const char *epsg_num;
248 
249  G_debug(1, "<%s> file not found for location <%s>", SRID_FILE,
250  G_location());
251 
252  /* for backwards compatibility, check if PROJ_EPSG exists */
253  if ((projepsg = G_get_projepsg()) != NULL) {
254  epsg_num = G_find_key_value("epsg", projepsg);
255  if (*epsg_num) {
256  G_debug(1, "Using <%s> file instead for location <%s>",
257  EPSG_FILE, G_location());
258  G_asprintf(&sridstring, "EPSG:%s", epsg_num);
259  G_free_key_value(projepsg);
260 
261  return sridstring;
262  }
263  }
264  }
265  return NULL;
266  }
267 
268  fp = fopen(path, "r");
269  if (!fp)
270  G_fatal_error(_("Unable to open input file <%s>: %s"), path,
271  strerror(errno));
272 
273  sridstring = G_malloc(1024 * sizeof(char));
274  nalloc = 1024;
275 
276  n = 0;
277  while (1) {
278  c = fgetc(fp);
279 
280  if (c == EOF) {
281  break;
282  }
283 
284  if (c == '\r') { /* DOS or MacOS9 */
285  c = fgetc(fp);
286  if (c != EOF) {
287  if (c !=
288  '\n') { /* MacOS9 - we have to return the char to stream */
289  ungetc(c, fp);
290  c = '\n';
291  }
292  }
293  else { /* MacOS9 - we have to return the char to stream */
294  ungetc(c, fp);
295  c = '\n';
296  }
297  }
298 
299  if (n == nalloc) {
300  sridstring = G_realloc(sridstring, nalloc + 1024);
301  nalloc += 1024;
302  }
303 
304  sridstring[n] = c;
305 
306  n++;
307  }
308 
309  if (n > 0) {
310  if (n == nalloc) {
311  sridstring = G_realloc(sridstring, nalloc + 1);
312  nalloc += 1;
313  }
314  sridstring[n] = '\0';
315  }
316  else {
317  G_free(sridstring);
318  sridstring = NULL;
319  }
320 
321  if (fclose(fp) != 0)
322  G_fatal_error(_("Error closing output file <%s>: %s"), path,
323  strerror(errno));
324 
325  if (sridstring && *sridstring)
326  G_chop(sridstring);
327  if (sridstring && *sridstring == '\0') {
328  G_free(sridstring);
329  sridstring = NULL;
330  }
331 
332  return sridstring;
333 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:147
#define G_realloc(p, n)
Definition: defs/gis.h:96
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
char * G_file_name(char *, const char *, const char *, const char *)
Builds full path names to GIS data files.
Definition: file_name.c:61
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition: key_value1.c:85
#define G_malloc(n)
Definition: defs/gis.h:94
void G_free_key_value(struct Key_Value *)
Free allocated Key_Value structure.
Definition: key_value1.c:104
void G_set_key_value(const char *, const char *, struct Key_Value *)
Set value for given key.
Definition: key_value1.c:39
int G_asprintf(char **, const char *,...) __attribute__((format(printf
struct Key_Value * G_read_key_value_file(const char *)
Read key/values pairs from file.
Definition: key_value3.c:55
const char * G_location(void)
Get current location name.
Definition: location.c:32
char * G_chop(char *)
Chop leading and trailing white spaces.
Definition: strings.c:332
int G_debug(int, const char *,...) __attribute__((format(printf
int G_projection(void)
Query cartographic projection.
Definition: proj1.c:32
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
Definition: get_projinfo.c:61
struct Key_Value * G_get_projunits(void)
Gets units information for location.
Definition: get_projinfo.c:32
char * G_get_projsrid(void)
Get srid (spatial reference id) for the current location.
Definition: get_projinfo.c:235
char * G_get_projwkt(void)
Get WKT information for the current location.
Definition: get_projinfo.c:126
#define PERMANENT
Definition: get_projinfo.c:19
struct Key_Value * G_get_projepsg(void)
Gets EPSG information for the current location.
Definition: get_projinfo.c:102
#define PROJECTION_XY
Projection code - XY coordinate system (unreferenced data)
Definition: gis.h:123
#define WKT_FILE
Definition: gis.h:136
#define PROJECTION_FILE
Definition: gis.h:133
#define EPSG_FILE
Definition: gis.h:135
#define GPATH_MAX
Definition: gis.h:199
#define SRID_FILE
Definition: gis.h:137
#define UNIT_FILE
Definition: gis.h:134
#define _(str)
Definition: glocale.h:10
Definition: gis.h:534
int nalloc
Definition: gis.h:536
Definition: path.h:15
#define access
Definition: unistd.h:7