GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-1b35ff81e
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  return G_chop(wktstring);
199 }
200 
201 /*!
202  \brief Get srid (spatial reference id) for the current location
203 
204  Typically an srid will be of the form authority NAME:CODE,
205  e.g. EPSG:4326
206 
207  This srid is passed to proj_create() using PROJ or
208  OSRSetFromUserInput() using GDAL. Therefore various other forms of
209  srid are possible, e.g. in OSRSetFromUserInput():
210 
211  1. Well Known Text definition - passed on to importFromWkt().
212  2. "EPSG:n" - number passed on to importFromEPSG().
213  3. "EPSGA:n" - number passed on to importFromEPSGA().
214  4. "AUTO:proj_id,unit_id,lon0,lat0" - WMS auto projections.
215  5. "urn:ogc:def:crs:EPSG::n" - ogc urns
216  6. PROJ.4 definitions - passed on to importFromProj4().
217  7. filename - file read for WKT, XML or PROJ.4 definition.
218  8. well known name accepted by SetWellKnownGeogCS(), such as NAD27, NAD83, WGS84 or WGS72.
219  9. "IGNF:xxxx", "ESRI:xxxx", etc. from definitions from the PROJ database;
220  10. PROJJSON (PROJ >= 6.2)
221 
222  \return pointer to srid string
223  \return NULL when srid is not available for the current location
224 */
225 
226 char *G_get_projsrid(void)
227 {
228  char *sridstring = NULL;
229  char path[GPATH_MAX];
230  FILE *fp;
231  int n, nalloc;
232  int c;
233 
234  G_file_name(path, "", SRID_FILE, "PERMANENT");
235  if (access(path, 0) != 0) {
236  if (G_projection() != PROJECTION_XY) {
237  struct Key_Value *projepsg;
238  const char *epsg_num;
239 
240  G_debug(1, "<%s> file not found for location <%s>",
241  SRID_FILE, G_location());
242 
243  /* for backwards compatibility, check if PROJ_EPSG exists */
244  if ((projepsg = G_get_projepsg()) != NULL) {
245  epsg_num = G_find_key_value("epsg", projepsg);
246  if (*epsg_num) {
247  G_debug(1, "Using <%s> file instead for location <%s>",
248  EPSG_FILE, G_location());
249  G_asprintf(&sridstring, "EPSG:%s", epsg_num);
250  G_free_key_value(projepsg);
251 
252  return sridstring;
253  }
254  }
255  }
256  return NULL;
257  }
258 
259  fp = fopen(path, "r");
260  if (!fp)
261  G_fatal_error(_("Unable to open input file <%s>: %s"), path, strerror(errno));
262 
263  sridstring = G_malloc(1024 * sizeof(char));
264  nalloc = 1024;
265 
266  n = 0;
267  while (1) {
268  c = fgetc(fp);
269 
270  if (c == EOF) {
271  break;
272  }
273 
274  if (c == '\r') { /* DOS or MacOS9 */
275  c = fgetc(fp);
276  if (c != EOF) {
277  if (c != '\n') { /* MacOS9 - we have to return the char to stream */
278  ungetc(c, fp);
279  c = '\n';
280  }
281  }
282  else { /* MacOS9 - we have to return the char to stream */
283  ungetc(c, fp);
284  c = '\n';
285  }
286  }
287 
288  if (n == nalloc) {
289  sridstring = G_realloc(sridstring, nalloc + 1024);
290  nalloc += 1024;
291  }
292 
293  sridstring[n] = c;
294 
295  n++;
296  }
297 
298  if (n > 0) {
299  if (n == nalloc) {
300  sridstring = G_realloc(sridstring, nalloc + 1);
301  nalloc += 1;
302  }
303  sridstring[n] = '\0';
304  }
305  else {
306  G_free(sridstring);
307  sridstring = NULL;
308  }
309 
310  if (fclose(fp) != 0)
311  G_fatal_error(_("Error closing output file <%s>: %s"), path, strerror(errno));
312 
313  return G_chop(sridstring);
314 }
const char * G_location(void)
Get current location name.
Definition: location.c:32
const char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key (case sensitive)
Definition: key_value1.c:84
void G_free(void *buf)
Free allocated memory.
Definition: gis/alloc.c:149
#define PERMANENT
Definition: get_projinfo.c:19
struct Key_Value * G_get_projunits(void)
Gets units information for location.
Definition: get_projinfo.c:32
int G_asprintf(char **out, const char *fmt,...)
Definition: asprintf.c:70
#define PROJECTION_XY
Projection code - XY coordinate system (unreferenced data)
Definition: gis.h:107
#define NULL
Definition: ccmath.h:32
char * G_chop(char *line)
Chop leading and trailing white spaces.
Definition: strings.c:328
void G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:103
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:160
struct Key_Value * G_read_key_value_file(const char *file)
Read key/values pairs from file.
Definition: key_value3.c:53
char * G_file_name(char *path, const char *element, const char *name, const char *mapset)
Builds full path names to GIS data files.
Definition: file_name.c:38
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
char * G_get_projwkt(void)
Get WKT information for the current location.
Definition: get_projinfo.c:127
#define GPATH_MAX
Definition: gis.h:167
char * G_get_projsrid(void)
Get srid (spatial reference id) for the current location.
Definition: get_projinfo.c:226
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
Definition: get_projinfo.c:61
Definition: gis.h:498
int nalloc
Definition: gis.h:501
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:119
#define SRID_FILE
Definition: gis.h:121
Definition: path.h:16
#define WKT_FILE
Definition: gis.h:120
#define _(str)
Definition: glocale.h:13
#define UNIT_FILE
Definition: gis.h:118
void G_set_key_value(const char *key, const char *value, struct Key_Value *kv)
Set value for given key.
Definition: key_value1.c:38
int G_projection(void)
Query cartographic projection.
Definition: proj1.c:32
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
#define PROJECTION_FILE
Definition: gis.h:117