GRASS GIS 7 Programmer's Manual  7.9.dev(2021)-e5379bbd7
gis/datum.c
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * MODULE: gis library
5  * AUTHOR(S): Andreas Lange - andreas.lange@rhein-main.de
6  * Paul Kelly - paul-grass@stjohnspoint.co.uk
7  * PURPOSE: provide functions for reading datum parameters from the
8  * location database.
9  * COPYRIGHT: (C) 2000, 2003 by the GRASS Development Team
10  *
11  * This program is free software under the GNU General Public
12  * License (>=v2). Read the file COPYING that comes with GRASS
13  * for details.
14  *
15  *****************************************************************************/
16 
17 #define DATUMTABLE "/etc/proj/datum.table"
18 
19 #include <unistd.h>
20 #include <string.h>
21 #include <ctype.h>
22 #include <stdlib.h>
23 
24 #include <grass/gis.h>
25 #include <grass/glocale.h>
26 
27 static struct table
28 {
29  struct datum
30  {
31  char *name; /* Short Name / acronym of map datum */
32  char *descr; /* Long Name for map datum */
33  char *ellps; /* acronym for ellipsoid used with this datum */
34  double dx; /* delta x */
35  double dy; /* delta y */
36  double dz; /* delta z */
37  } *datums;
38  int size;
39  int count;
40  int initialized;
41 } table;
42 
43 static int compare_table_names(const void *, const void *);
44 
45 int G_get_datum_by_name(const char *name)
46 {
47  int i;
48 
50 
51  for (i = 0; i < table.count; i++)
52  if (G_strcasecmp(name, table.datums[i].name) == 0)
53  return i;
54 
55  return -1;
56 }
57 
58 const char *G_datum_name(int n)
59 {
61 
62  if (n < 0 || n >= table.count)
63  return NULL;
64 
65  return table.datums[n].name;
66 }
67 
68 const char *G_datum_description(int n)
69 {
71 
72  if (n < 0 || n >= table.count)
73  return NULL;
74 
75  return table.datums[n].descr;
76 }
77 
78 const char *G_datum_ellipsoid(int n)
79 {
81 
82  if (n < 0 || n >= table.count)
83  return NULL;
84 
85  return table.datums[n].ellps;
86 }
87 
88 /***********************************************************
89  * G_get_datumparams_from_projinfo(projinfo, datumname, params)
90  * struct Key_Value *projinfo Set of key_value pairs containing
91  * projection information in PROJ_INFO file
92  * format
93  * char *datumname Pointer into which a string containing
94  * the datum name (if present) will be
95  * placed.
96  * char *params Pointer into which a string containing
97  * the datum parameters (if present) will
98  * be placed.
99  *
100  * Extract the datum transformation-related parameters from a
101  * set of general PROJ_INFO parameters.
102  * This function can be used to test if a location set-up
103  * supports datum transformation.
104  *
105  * returns: -1 error or no datum information found,
106  * 1 only datum name found, 2 params found
107  ************************************************************/
108 
109 int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo,
110  char *datumname, char *params)
111 {
112  int returnval = -1;
113 
114  if (NULL != G_find_key_value("datum", projinfo)) {
115  sprintf(datumname, "%s", G_find_key_value("datum", projinfo));
116  returnval = 1;
117  }
118 
119  if (G_find_key_value("datumparams", projinfo) != NULL) {
120  sprintf(params, "%s", G_find_key_value("datumparams", projinfo));
121  returnval = 2;
122  }
123  else if (G_find_key_value("nadgrids", projinfo) != NULL) {
124  sprintf(params, "nadgrids=%s",
125  G_find_key_value("nadgrids", projinfo));
126  returnval = 2;
127  }
128  else if (G_find_key_value("towgs84", projinfo) != NULL) {
129  sprintf(params, "towgs84=%s", G_find_key_value("towgs84", projinfo));
130  returnval = 2;
131  }
132  else if (G_find_key_value("dx", projinfo) != NULL
133  && G_find_key_value("dy", projinfo) != NULL
134  && G_find_key_value("dz", projinfo) != NULL) {
135  sprintf(params, "towgs84=%s,%s,%s",
136  G_find_key_value("dx", projinfo),
137  G_find_key_value("dy", projinfo),
138  G_find_key_value("dz", projinfo));
139  returnval = 2;
140  }
141 
142  return returnval;
143 
144 }
145 
147 {
148  FILE *fd;
149  char file[GPATH_MAX];
150  char buf[1024];
151  int line;
152 
153  if (G_is_initialized(&table.initialized))
154  return;
155 
156  sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
157 
158  fd = fopen(file, "r");
159  if (!fd) {
160  G_warning(_("unable to open datum table file: %s"), file);
161  G_initialize_done(&table.initialized);
162  return;
163  }
164 
165  for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
166  char name[100], descr[100], ellps[100];
167  struct datum *t;
168 
169  G_strip(buf);
170  if (*buf == '\0' || *buf == '#')
171  continue;
172 
173  if (table.count >= table.size) {
174  table.size += 50;
175  table.datums = G_realloc(table.datums, table.size * sizeof(struct datum));
176  }
177 
178  t = &table.datums[table.count];
179 
180  if (sscanf(buf, "%s \"%99[^\"]\" %s dx=%lf dy=%lf dz=%lf",
181  name, descr, ellps, &t->dx, &t->dy, &t->dz) != 6) {
182  G_warning(_("error in datum table file, line %d"), line);
183  continue;
184  }
185 
186  t->name = G_store(name);
187  t->descr = G_store(descr);
188  t->ellps = G_store(ellps);
189 
190  table.count++;
191  }
192 
193  qsort(table.datums, table.count, sizeof(struct datum), compare_table_names);
194 
195  G_initialize_done(&table.initialized);
196 }
197 
198 static int compare_table_names(const void *aa, const void *bb)
199 {
200  const struct datum *a = aa;
201  const struct datum *b = bb;
202 
203  return G_strcasecmp(a->name, b->name);
204 }
int G_getl2(char *, int, FILE *)
Gets a line of text from a file of any pedigree.
Definition: getl.c:64
int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo, char *datumname, char *params)
Definition: gis/datum.c:109
#define DATUMTABLE
Definition: gis/datum.c:17
void G_read_datum_table(void)
Definition: gis/datum.c:146
const char * G_datum_description(int n)
Definition: gis/datum.c:68
int count
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition: strings.c:300
#define NULL
Definition: ccmath.h:32
const char * G_datum_name(int n)
Definition: gis/datum.c:58
void G_initialize_done(int *)
Definition: counter.c:76
const char * G_datum_ellipsoid(int n)
Definition: gis/datum.c:78
double t
Definition: r_raster.c:39
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition: strings.c:47
double b
Definition: r_raster.c:39
#define GPATH_MAX
Definition: gis.h:170
Definition: gis.h:501
int G_is_initialized(int *)
Definition: counter.c:59
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:41
void G_warning(const char *,...) __attribute__((format(printf
#define file
#define G_realloc(p, n)
Definition: defs/gis.h:114
#define _(str)
Definition: glocale.h:10
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
const char * name
Definition: named_colr.c:7
int G_get_datum_by_name(const char *name)
Definition: gis/datum.c:45
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition: key_value1.c:84