GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-602118adcc
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  struct datum {
29  char *name; /* Short Name / acronym of map datum */
30  char *descr; /* Long Name for map datum */
31  char *ellps; /* acronym for ellipsoid used with this datum */
32  double dx; /* delta x */
33  double dy; /* delta y */
34  double dz; /* delta z */
35  } *datums;
36  int size;
37  int count;
38  int initialized;
39 } table;
40 
41 static int compare_table_names(const void *, const void *);
42 
43 int G_get_datum_by_name(const char *name)
44 {
45  int i;
46 
48 
49  for (i = 0; i < table.count; i++)
50  if (G_strcasecmp(name, table.datums[i].name) == 0)
51  return i;
52 
53  return -1;
54 }
55 
56 const char *G_datum_name(int n)
57 {
59 
60  if (n < 0 || n >= table.count)
61  return NULL;
62 
63  return table.datums[n].name;
64 }
65 
66 const char *G_datum_description(int n)
67 {
69 
70  if (n < 0 || n >= table.count)
71  return NULL;
72 
73  return table.datums[n].descr;
74 }
75 
76 const char *G_datum_ellipsoid(int n)
77 {
79 
80  if (n < 0 || n >= table.count)
81  return NULL;
82 
83  return table.datums[n].ellps;
84 }
85 
86 /***********************************************************
87  * G_get_datumparams_from_projinfo(projinfo, datumname, params)
88  * struct Key_Value *projinfo Set of key_value pairs containing
89  * projection information in PROJ_INFO file
90  * format
91  * char *datumname Pointer into which a string containing
92  * the datum name (if present) will be
93  * placed.
94  * char *params Pointer into which a string containing
95  * the datum parameters (if present) will
96  * be placed.
97  *
98  * Extract the datum transformation-related parameters from a
99  * set of general PROJ_INFO parameters.
100  * This function can be used to test if a location set-up
101  * supports datum transformation.
102  *
103  * returns: -1 error or no datum information found,
104  * 1 only datum name found, 2 params found
105  ************************************************************/
106 
107 int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo,
108  char *datumname, char *params)
109 {
110  int returnval = -1;
111 
112  if (NULL != G_find_key_value("datum", projinfo)) {
113  sprintf(datumname, "%s", G_find_key_value("datum", projinfo));
114  returnval = 1;
115  }
116 
117  if (G_find_key_value("datumparams", projinfo) != NULL) {
118  sprintf(params, "%s", G_find_key_value("datumparams", projinfo));
119  returnval = 2;
120  }
121  else if (G_find_key_value("nadgrids", projinfo) != NULL) {
122  sprintf(params, "nadgrids=%s", G_find_key_value("nadgrids", projinfo));
123  returnval = 2;
124  }
125  else if (G_find_key_value("towgs84", projinfo) != NULL) {
126  sprintf(params, "towgs84=%s", G_find_key_value("towgs84", projinfo));
127  returnval = 2;
128  }
129  else if (G_find_key_value("dx", projinfo) != NULL &&
130  G_find_key_value("dy", projinfo) != NULL &&
131  G_find_key_value("dz", projinfo) != NULL) {
132  sprintf(params, "towgs84=%s,%s,%s", G_find_key_value("dx", projinfo),
133  G_find_key_value("dy", projinfo),
134  G_find_key_value("dz", projinfo));
135  returnval = 2;
136  }
137 
138  return returnval;
139 }
140 
142 {
143  FILE *fd;
144  char file[GPATH_MAX];
145  char buf[1024];
146  int line;
147 
148  if (G_is_initialized(&table.initialized))
149  return;
150 
151  sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
152 
153  fd = fopen(file, "r");
154  if (!fd) {
155  G_warning(_("unable to open datum table file: %s"), file);
156  G_initialize_done(&table.initialized);
157  return;
158  }
159 
160  for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
161  char name[100], descr[100], ellps[100];
162  struct datum *t;
163 
164  G_strip(buf);
165  if (*buf == '\0' || *buf == '#')
166  continue;
167 
168  if (table.count >= table.size) {
169  table.size += 50;
170  table.datums =
171  G_realloc(table.datums, table.size * sizeof(struct datum));
172  }
173 
174  t = &table.datums[table.count];
175 
176  if (sscanf(buf, "%s \"%99[^\"]\" %s dx=%lf dy=%lf dz=%lf", name, descr,
177  ellps, &t->dx, &t->dy, &t->dz) != 6) {
178  G_warning(_("error in datum table file, line %d"), line);
179  continue;
180  }
181 
182  t->name = G_store(name);
183  t->descr = G_store(descr);
184  t->ellps = G_store(ellps);
185 
186  table.count++;
187  }
188 
189  qsort(table.datums, table.count, sizeof(struct datum), compare_table_names);
190 
191  G_initialize_done(&table.initialized);
192 }
193 
194 static int compare_table_names(const void *aa, const void *bb)
195 {
196  const struct datum *a = aa;
197  const struct datum *b = bb;
198 
199  return G_strcasecmp(a->name, b->name);
200 }
#define NULL
Definition: ccmath.h:32
int G_getl2(char *, int, FILE *)
Gets a line of text from a file of any pedigree.
Definition: getl.c:60
#define G_realloc(p, n)
Definition: defs/gis.h:96
void G_warning(const char *,...) __attribute__((format(printf
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition: key_value1.c:85
void G_strip(char *)
Removes all leading and trailing white space from string.
Definition: strings.c:300
int G_is_initialized(int *)
Definition: counter.c:60
void G_initialize_done(int *)
Definition: counter.c:77
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition: strings.c:47
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:39
char * G_store(const char *)
Copy string to allocated memory.
Definition: strings.c:87
const char * G_datum_name(int n)
Definition: gis/datum.c:56
int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo, char *datumname, char *params)
Definition: gis/datum.c:107
#define DATUMTABLE
Definition: gis/datum.c:17
const char * G_datum_description(int n)
Definition: gis/datum.c:66
const char * G_datum_ellipsoid(int n)
Definition: gis/datum.c:76
int G_get_datum_by_name(const char *name)
Definition: gis/datum.c:43
void G_read_datum_table(void)
Definition: gis/datum.c:141
#define GPATH_MAX
Definition: gis.h:194
#define _(str)
Definition: glocale.h:10
int count
#define file
const char * name
Definition: named_colr.c:6
double b
Definition: r_raster.c:39
double t
Definition: r_raster.c:39
Definition: gis.h:528