GRASS GIS 7 Programmer's Manual  7.0.4(2016)-r00000
proj/datum.c
Go to the documentation of this file.
1 
16 #include <unistd.h>
17 #include <string.h>
18 #include <ctype.h>
19 #include <stdlib.h>
20 
21 #include <grass/gis.h>
22 #include <grass/glocale.h>
23 #include <grass/gprojects.h>
24 #include "local_proto.h"
25 
37 int GPJ_get_datum_by_name(const char *name, struct gpj_datum *dstruct)
38 {
39  struct datum_list *list, *listhead;
40 
41  list = listhead = read_datum_table();
42 
43  while (list != NULL) {
44  if (G_strcasecmp(name, list->name) == 0) {
45  dstruct->name = G_store(list->name);
46  dstruct->longname = G_store(list->longname);
47  dstruct->ellps = G_store(list->ellps);
48  dstruct->dx = list->dx;
49  dstruct->dy = list->dy;
50  dstruct->dz = list->dz;
51  free_datum_list(listhead);
52  return 1;
53  }
54  list = list->next;
55  }
56  free_datum_list(listhead);
57  return -1;
58 }
59 
85 int GPJ_get_default_datum_params_by_name(const char *name, char **params)
86 {
87  struct gpj_datum_transform_list *list, *old;
88  int count = 0;
89 
91 
92  if (list == NULL) {
93  *params = NULL;
94  return -1;
95  }
96 
97  /* Take the first parameter set in the list as the default
98  * (will normally be a 3-parameter transformation) */
99  *params = G_store(list->params);
100 
101  while (list != NULL) {
102  count++;
103  old = list;
104  list = list->next;
106  }
107 
108  return count;
109 
110 }
111 
135 int GPJ_get_datum_params(char **name, char **params)
136 {
137  int ret;
138  struct Key_Value *proj_keys = G_get_projinfo();
139 
140  ret = GPJ__get_datum_params(proj_keys, name, params);
141  G_free_key_value(proj_keys);
142 
143  return ret;
144 }
145 
173 int GPJ__get_datum_params(const struct Key_Value *projinfo,
174  char **datumname, char **params)
175 {
176  int returnval = -1;
177 
178  if (NULL != G_find_key_value("datum", projinfo)) {
179  *datumname = G_store(G_find_key_value("datum", projinfo));
180  returnval = 1;
181  }
182  else
183  *datumname = NULL;
184 
185  if (G_find_key_value("datumparams", projinfo) != NULL) {
186  *params = G_store(G_find_key_value("datumparams", projinfo));
187  returnval = 2;
188  }
189  else if (G_find_key_value("nadgrids", projinfo) != NULL) {
190  const char *gisbase = G_gisbase();
191 
192  G_asprintf(params, "nadgrids=%s%s/%s", gisbase, GRIDDIR,
193  G_find_key_value("nadgrids", projinfo));
194  returnval = 2;
195  }
196  else if (G_find_key_value("towgs84", projinfo) != NULL) {
197  G_asprintf(params, "towgs84=%s",
198  G_find_key_value("towgs84", projinfo));
199  returnval = 2;
200  }
201  else if (G_find_key_value("dx", projinfo) != NULL
202  && G_find_key_value("dy", projinfo) != NULL
203  && G_find_key_value("dz", projinfo) != NULL) {
204  G_asprintf(params, "towgs84=%s,%s,%s",
205  G_find_key_value("dx", projinfo),
206  G_find_key_value("dy", projinfo),
207  G_find_key_value("dz", projinfo));
208  returnval = 2;
209  }
210  else
211  *params = NULL;
212 
213  return returnval;
214 
215 }
216 
229 struct gpj_datum_transform_list *GPJ_get_datum_transform_by_name(const char
230  *inputname)
231 {
232  FILE *fd;
233  char file[GPATH_MAX];
234  char buf[1024];
235  int line;
236  struct gpj_datum_transform_list *current = NULL, *outputlist = NULL;
237  struct gpj_datum dstruct;
238  int count = 0;
239 
240  GPJ_get_datum_by_name(inputname, &dstruct);
241  if (dstruct.dx < 99999 && dstruct.dy < 99999 && dstruct.dz < 99999) {
242  /* Include the old-style dx dy dz parameters from datum.table at the
243  * start of the list, unless these have been set to all 99999 to
244  * indicate only entries in datumtransform.table should be used */
245  if (current == NULL)
246  current = outputlist =
247  G_malloc(sizeof(struct gpj_datum_transform_list));
248  else
249  current = current->next =
250  G_malloc(sizeof(struct gpj_datum_transform_list));
251  G_asprintf(&(current->params), "towgs84=%.3f,%.3f,%.3f", dstruct.dx,
252  dstruct.dy, dstruct.dz);
253  G_asprintf(&(current->where_used), "whole %s region", inputname);
254  G_asprintf(&(current->comment),
255  "Default 3-Parameter Transformation (May not be optimum for "
256  "older datums; use this only if no more appropriate options "
257  "are available.)");
258  count++;
259  current->count = count;
260  current->next = NULL;
261  }
262  GPJ_free_datum(&dstruct);
263 
264  /* Now check for additional parameters in datumtransform.table */
265 
266  sprintf(file, "%s%s", G_gisbase(), DATUMTRANSFORMTABLE);
267 
268  fd = fopen(file, "r");
269  if (!fd) {
270  G_warning(_("Unable to open datum table file <%s>"), file);
271  return outputlist;
272  }
273 
274  for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
275  char name[100], params[1024], where_used[1024], comment[1024];
276 
277  G_strip(buf);
278  if (*buf == '\0' || *buf == '#')
279  continue;
280 
281  if (sscanf(buf, "%99s \"%1023[^\"]\" \"%1023[^\"]\" \"%1023[^\"]\"",
282  name, params, where_used, comment) != 4) {
283  G_warning(_("Error in datum table file <%s>, line %d"), file,
284  line);
285  continue;
286  }
287 
288  if (G_strcasecmp(inputname, name) == 0) {
289  /* If the datum name in this line matches the one we are
290  * looking for, add an entry to the linked list */
291  if (current == NULL)
292  current = outputlist =
293  G_malloc(sizeof(struct gpj_datum_transform_list));
294  else
295  current = current->next =
296  G_malloc(sizeof(struct gpj_datum_transform_list));
297  current->params = G_store(params);
298  current->where_used = G_store(where_used);
299  current->comment = G_store(comment);
300  count++;
301  current->count = count;
302  current->next = NULL;
303  }
304  }
305 
306  fclose(fd);
307 
308  return outputlist;
309 
310 }
311 
318 void GPJ_free_datum_transform(struct gpj_datum_transform_list *item)
319 {
320  G_free(item->params);
321  G_free(item->where_used);
322  G_free(item->comment);
323  G_free(item);
324  return;
325 }
326 
337 struct datum_list *read_datum_table(void)
338 {
339  FILE *fd;
340  char file[GPATH_MAX];
341  char buf[4096];
342  int line;
343  struct datum_list *current = NULL, *outputlist = NULL;
344  int count = 0;
345 
346  sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
347 
348  fd = fopen(file, "r");
349  if (!fd) {
350  G_warning(_("Unable to open datum table file <%s>"), file);
351  return NULL;
352  }
353 
354  for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
355  char name[100], descr[1024], ellps[100];
356  double dx, dy, dz;
357 
358  G_strip(buf);
359  if (*buf == '\0' || *buf == '#')
360  continue;
361 
362  if (sscanf(buf, "%s \"%1023[^\"]\" %s dx=%lf dy=%lf dz=%lf",
363  name, descr, ellps, &dx, &dy, &dz) != 6) {
364  G_warning(_("Error in datum table file <%s>, line %d"), file,
365  line);
366  continue;
367  }
368 
369  if (current == NULL)
370  current = outputlist = G_malloc(sizeof(struct datum_list));
371  else
372  current = current->next = G_malloc(sizeof(struct datum_list));
373  current->name = G_store(name);
374  current->longname = G_store(descr);
375  current->ellps = G_store(ellps);
376  current->dx = dx;
377  current->dy = dy;
378  current->dz = dz;
379  current->next = NULL;
380 
381  count++;
382  }
383 
384  fclose(fd);
385 
386  return outputlist;
387 }
388 
395 void GPJ_free_datum(struct gpj_datum *dstruct)
396 {
397  G_free(dstruct->name);
398  G_free(dstruct->longname);
399  G_free(dstruct->ellps);
400  return;
401 }
402 
409 void free_datum_list(struct datum_list *dstruct)
410 {
411  struct datum_list *old;
412 
413  while (dstruct != NULL) {
414  G_free(dstruct->name);
415  G_free(dstruct->longname);
416  G_free(dstruct->ellps);
417  old = dstruct;
418  dstruct = old->next;
419  G_free(old);
420  }
421 
422  return;
423 }
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:46
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 GPJ_free_datum(struct gpj_datum *dstruct)
Free the memory used for the strings in a gpj_datum struct.
Definition: proj/datum.c:395
int GPJ__get_datum_params(const struct Key_Value *projinfo, char **datumname, char **params)
Extract the datum transformation-related parameters from a set of general PROJ_INFO parameters...
Definition: proj/datum.c:173
void G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:258
void GPJ_free_datum_transform(struct gpj_datum_transform_list *item)
Free the memory used by a gpj_datum_transform_list struct.
Definition: proj/datum.c:318
#define DATUMTABLE
Definition: gis/datum.c:17
int count
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:86
int G_asprintf(char **out, const char *fmt,...)
Definition: asprintf.c:70
#define NULL
Definition: ccmath.h:32
struct gpj_datum_transform_list * GPJ_get_datum_transform_by_name(const char *inputname)
Internal function to find all possible sets of transformation parameters for a particular datum...
Definition: proj/datum.c:229
int GPJ_get_datum_by_name(const char *name, struct gpj_datum *dstruct)
Look up a string in datum.table file to see if it is a valid datum name and if so place its informati...
Definition: proj/datum.c:37
void G_free_key_value(struct Key_Value *kv)
Free allocated Key_Value structure.
Definition: key_value1.c:103
int G_getl2(char *buf, int n, FILE *fd)
Gets a line of text from a file of any pedigree.
Definition: getl.c:64
void free_datum_list(struct datum_list *dstruct)
Free the memory used by a datum_list linked list structure.
Definition: proj/datum.c:409
int GPJ_get_datum_params(char **name, char **params)
Extract the datum transformation-related parameters for the current location.
Definition: proj/datum.c:135
struct list * list
Definition: read_list.c:24
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
Definition: get_projinfo.c:58
struct datum_list * read_datum_table(void)
Read the current GRASS datum.table from disk and store in memory.
Definition: proj/datum.c:337
int GPJ_get_default_datum_params_by_name(const char *name, char **params)
"Last resort" function to retrieve a "default" set of datum parameters for a datum (N...
Definition: proj/datum.c:85
#define file
const char * name
Definition: named_colr.c:7
void G_free(void *buf)
Free allocated memory.
Definition: alloc.c:149
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:41
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:203