GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-602118adcc
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  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 
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 
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>", WKT_FILE,
139  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,
147  strerror(errno));
148 
149  wktstring = G_malloc(1024 * sizeof(char));
150  nalloc = 1024;
151 
152  n = 0;
153  while (1) {
154  c = fgetc(fp);
155 
156  if (c == EOF) {
157  break;
158  }
159 
160  if (c == '\r') { /* DOS or MacOS9 */
161  c = fgetc(fp);
162  if (c != EOF) {
163  if (c !=
164  '\n') { /* MacOS9 - we have to return the char to stream */
165  ungetc(c, fp);
166  c = '\n';
167  }
168  }
169  else { /* MacOS9 - we have to return the char to stream */
170  ungetc(c, fp);
171  c = '\n';
172  }
173  }
174 
175  if (n == nalloc) {
176  wktstring = G_realloc(wktstring, nalloc + 1024);
177  nalloc += 1024;
178  }
179 
180  wktstring[n] = c;
181 
182  n++;
183  }
184 
185  if (n > 0) {
186  if (n == nalloc) {
187  wktstring = G_realloc(wktstring, nalloc + 1);
188  nalloc += 1;
189  }
190  wktstring[n] = '\0';
191  }
192  else {
193  G_free(wktstring);
194  wktstring = NULL;
195  }
196 
197  if (fclose(fp) != 0)
198  G_fatal_error(_("Error closing output file <%s>: %s"), path,
199  strerror(errno));
200 
201  if (wktstring && *wktstring)
202  G_chop(wktstring);
203  if (wktstring && *wktstring == '\0') {
204  G_free(wktstring);
205  wktstring = NULL;
206  }
207 
208  return wktstring;
209 }
210 
211 /*!
212  \brief Get srid (spatial reference id) for the current location
213 
214  Typically an srid will be of the form authority NAME:CODE,
215  e.g. EPSG:4326
216 
217  This srid is passed to proj_create() using PROJ or
218  OSRSetFromUserInput() using GDAL. Therefore various other forms of
219  srid are possible, e.g. in OSRSetFromUserInput():
220 
221  1. Well Known Text definition - passed on to importFromWkt().
222  2. "EPSG:n" - number passed on to importFromEPSG().
223  3. "EPSGA:n" - number passed on to importFromEPSGA().
224  4. "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
225  5. "urn:ogc:def:crs:EPSG::n" - ogc urns
226  6. PROJ.4 definitions - passed on to importFromProj4().
227  7. filename - file read for WKT, XML or PROJ.4 definition.
228  8. well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83,
229  WGS84 or WGS72.
230  9. "IGNF:xxxx", "ESRI:xxxx", etc. from definitions from the PROJ database;
231  10. PROJJSON (PROJ >= 6.2)
232 
233  \return pointer to srid string
234  \return NULL when srid is not available for the current location
235  */
236 
237 char *G_get_projsrid(void)
238 {
239  char *sridstring = NULL;
240  char path[GPATH_MAX];
241  FILE *fp;
242  int n, nalloc;
243  int c;
244 
245  G_file_name(path, "", SRID_FILE, "PERMANENT");
246  if (access(path, 0) != 0) {
247  if (G_projection() != PROJECTION_XY) {
248  struct Key_Value *projepsg;
249  const char *epsg_num;
250 
251  G_debug(1, "<%s> file not found for location <%s>", SRID_FILE,
252  G_location());
253 
254  /* for backwards compatibility, check if PROJ_EPSG exists */
255  if ((projepsg = G_get_projepsg()) != NULL) {
256  epsg_num = G_find_key_value("epsg", projepsg);
257  if (*epsg_num) {
258  G_debug(1, "Using <%s> file instead for location <%s>",
259  EPSG_FILE, G_location());
260  G_asprintf(&sridstring, "EPSG:%s", epsg_num);
261  G_free_key_value(projepsg);
262 
263  return sridstring;
264  }
265  }
266  }
267  return NULL;
268  }
269 
270  fp = fopen(path, "r");
271  if (!fp)
272  G_fatal_error(_("Unable to open input file <%s>: %s"), path,
273  strerror(errno));
274 
275  sridstring = G_malloc(1024 * sizeof(char));
276  nalloc = 1024;
277 
278  n = 0;
279  while (1) {
280  c = fgetc(fp);
281 
282  if (c == EOF) {
283  break;
284  }
285 
286  if (c == '\r') { /* DOS or MacOS9 */
287  c = fgetc(fp);
288  if (c != EOF) {
289  if (c !=
290  '\n') { /* MacOS9 - we have to return the char to stream */
291  ungetc(c, fp);
292  c = '\n';
293  }
294  }
295  else { /* MacOS9 - we have to return the char to stream */
296  ungetc(c, fp);
297  c = '\n';
298  }
299  }
300 
301  if (n == nalloc) {
302  sridstring = G_realloc(sridstring, nalloc + 1024);
303  nalloc += 1024;
304  }
305 
306  sridstring[n] = c;
307 
308  n++;
309  }
310 
311  if (n > 0) {
312  if (n == nalloc) {
313  sridstring = G_realloc(sridstring, nalloc + 1);
314  nalloc += 1;
315  }
316  sridstring[n] = '\0';
317  }
318  else {
319  G_free(sridstring);
320  sridstring = NULL;
321  }
322 
323  if (fclose(fp) != 0)
324  G_fatal_error(_("Error closing output file <%s>: %s"), path,
325  strerror(errno));
326 
327  if (sridstring && *sridstring)
328  G_chop(sridstring);
329  if (sridstring && *sridstring == '\0') {
330  G_free(sridstring);
331  sridstring = NULL;
332  }
333 
334  return sridstring;
335 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#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:237
char * G_get_projwkt(void)
Get WKT information for the current location.
Definition: get_projinfo.c:127
#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:124
#define WKT_FILE
Definition: gis.h:137
#define PROJECTION_FILE
Definition: gis.h:134
#define EPSG_FILE
Definition: gis.h:136
#define GPATH_MAX
Definition: gis.h:194
#define SRID_FILE
Definition: gis.h:138
#define UNIT_FILE
Definition: gis.h:135
#define _(str)
Definition: glocale.h:10
Definition: gis.h:528
int nalloc
Definition: gis.h:530
Definition: path.h:15