GRASS GIS 7 Programmer's Manual  7.0.5(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  G_debug(3, "GPJ__get_datum_params: datumname: <%s>", G_find_key_value("datum", projinfo));
181  returnval = 1;
182  }
183  else
184  *datumname = NULL;
185 
186  if (G_find_key_value("datumparams", projinfo) != NULL) {
187  *params = G_store(G_find_key_value("datumparams", projinfo));
188  G_debug(3, "GPJ__get_datum_params: datumparams: <%s>", G_find_key_value("datumparams", projinfo));
189  returnval = 2;
190  }
191  else if (G_find_key_value("nadgrids", projinfo) != NULL) {
192  const char *gisbase = G_gisbase();
193 
194  G_asprintf(params, "nadgrids=%s%s/%s", gisbase, GRIDDIR,
195  G_find_key_value("nadgrids", projinfo));
196  returnval = 2;
197  }
198  else if (G_find_key_value("towgs84", projinfo) != NULL) {
199  G_asprintf(params, "towgs84=%s",
200  G_find_key_value("towgs84", projinfo));
201  returnval = 2;
202  }
203  else if (G_find_key_value("dx", projinfo) != NULL
204  && G_find_key_value("dy", projinfo) != NULL
205  && G_find_key_value("dz", projinfo) != NULL) {
206  G_asprintf(params, "towgs84=%s,%s,%s",
207  G_find_key_value("dx", projinfo),
208  G_find_key_value("dy", projinfo),
209  G_find_key_value("dz", projinfo));
210  returnval = 2;
211  }
212  else
213  *params = NULL;
214 
215  return returnval;
216 
217 }
218 
231 struct gpj_datum_transform_list *GPJ_get_datum_transform_by_name(const char
232  *inputname)
233 {
234  FILE *fd;
235  char file[GPATH_MAX];
236  char buf[1024];
237  int line;
238  struct gpj_datum_transform_list *current = NULL, *outputlist = NULL;
239  struct gpj_datum dstruct;
240  int count = 0;
241 
242  GPJ_get_datum_by_name(inputname, &dstruct);
243  if (dstruct.dx < 99999 && dstruct.dy < 99999 && dstruct.dz < 99999) {
244  /* Include the old-style dx dy dz parameters from datum.table at the
245  * start of the list, unless these have been set to all 99999 to
246  * indicate only entries in datumtransform.table should be used */
247  if (current == NULL)
248  current = outputlist =
249  G_malloc(sizeof(struct gpj_datum_transform_list));
250  else
251  current = current->next =
252  G_malloc(sizeof(struct gpj_datum_transform_list));
253  G_asprintf(&(current->params), "towgs84=%.3f,%.3f,%.3f", dstruct.dx,
254  dstruct.dy, dstruct.dz);
255  G_asprintf(&(current->where_used), "whole %s region", inputname);
256  G_asprintf(&(current->comment),
257  "Default 3-Parameter Transformation (May not be optimum for "
258  "older datums; use this only if no more appropriate options "
259  "are available.)");
260  count++;
261  current->count = count;
262  current->next = NULL;
263  }
264  GPJ_free_datum(&dstruct);
265 
266  /* Now check for additional parameters in datumtransform.table */
267 
268  sprintf(file, "%s%s", G_gisbase(), DATUMTRANSFORMTABLE);
269 
270  fd = fopen(file, "r");
271  if (!fd) {
272  G_warning(_("Unable to open datum table file <%s>"), file);
273  return outputlist;
274  }
275 
276  for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
277  char name[100], params[1024], where_used[1024], comment[1024];
278 
279  G_strip(buf);
280  if (*buf == '\0' || *buf == '#')
281  continue;
282 
283  if (sscanf(buf, "%99s \"%1023[^\"]\" \"%1023[^\"]\" \"%1023[^\"]\"",
284  name, params, where_used, comment) != 4) {
285  G_warning(_("Error in datum table file <%s>, line %d"), file,
286  line);
287  continue;
288  }
289 
290  if (G_strcasecmp(inputname, name) == 0) {
291  /* If the datum name in this line matches the one we are
292  * looking for, add an entry to the linked list */
293  if (current == NULL)
294  current = outputlist =
295  G_malloc(sizeof(struct gpj_datum_transform_list));
296  else
297  current = current->next =
298  G_malloc(sizeof(struct gpj_datum_transform_list));
299  current->params = G_store(params);
300  current->where_used = G_store(where_used);
301  current->comment = G_store(comment);
302  count++;
303  current->count = count;
304  current->next = NULL;
305  }
306  }
307 
308  fclose(fd);
309 
310  return outputlist;
311 
312 }
313 
320 void GPJ_free_datum_transform(struct gpj_datum_transform_list *item)
321 {
322  G_free(item->params);
323  G_free(item->where_used);
324  G_free(item->comment);
325  G_free(item);
326  return;
327 }
328 
339 struct datum_list *read_datum_table(void)
340 {
341  FILE *fd;
342  char file[GPATH_MAX];
343  char buf[4096];
344  int line;
345  struct datum_list *current = NULL, *outputlist = NULL;
346  int count = 0;
347 
348  sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
349 
350  fd = fopen(file, "r");
351  if (!fd) {
352  G_warning(_("Unable to open datum table file <%s>"), file);
353  return NULL;
354  }
355 
356  for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
357  char name[100], descr[1024], ellps[100];
358  double dx, dy, dz;
359 
360  G_strip(buf);
361  if (*buf == '\0' || *buf == '#')
362  continue;
363 
364  if (sscanf(buf, "%s \"%1023[^\"]\" %s dx=%lf dy=%lf dz=%lf",
365  name, descr, ellps, &dx, &dy, &dz) != 6) {
366  G_warning(_("Error in datum table file <%s>, line %d"), file,
367  line);
368  continue;
369  }
370 
371  if (current == NULL)
372  current = outputlist = G_malloc(sizeof(struct datum_list));
373  else
374  current = current->next = G_malloc(sizeof(struct datum_list));
375  current->name = G_store(name);
376  current->longname = G_store(descr);
377  current->ellps = G_store(ellps);
378  current->dx = dx;
379  current->dy = dy;
380  current->dz = dz;
381  current->next = NULL;
382 
383  count++;
384  }
385 
386  fclose(fd);
387 
388  return outputlist;
389 }
390 
397 void GPJ_free_datum(struct gpj_datum *dstruct)
398 {
399  G_free(dstruct->name);
400  G_free(dstruct->longname);
401  G_free(dstruct->ellps);
402  return;
403 }
404 
411 void free_datum_list(struct datum_list *dstruct)
412 {
413  struct datum_list *old;
414 
415  while (dstruct != NULL) {
416  G_free(dstruct->name);
417  G_free(dstruct->longname);
418  G_free(dstruct->ellps);
419  old = dstruct;
420  dstruct = old->next;
421  G_free(old);
422  }
423 
424  return;
425 }
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:397
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:320
#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:231
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:411
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
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: debug.c:65
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:339
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