GRASS GIS 8 Programmer's Manual 8.2.0(2022)-exported
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
27static 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
43static int compare_table_names(const void *, const void *);
44
45int 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
58const 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
68const 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
78const 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
109int 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
198static 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}
#define NULL
Definition: ccmath.h:32
void G_initialize_done(int *p)
Definition: counter.c:76
int G_is_initialized(int *p)
Definition: counter.c:59
double b
double t
int G_getl2(char *buf, int n, FILE *fd)
Gets a line of text from a file of any pedigree.
Definition: getl.c:64
const char * G_datum_description(int n)
Definition: gis/datum.c:68
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
int G_get_datum_by_name(const char *name)
Definition: gis/datum.c:45
void G_read_datum_table(void)
Definition: gis/datum.c:146
const char * G_datum_ellipsoid(int n)
Definition: gis/datum.c:78
const char * G_datum_name(int n)
Definition: gis/datum.c:58
void G_warning(const char *msg,...)
Print a warning message to stderr.
Definition: gis/error.c:204
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:41
int count
const char * G_find_key_value(const char *key, const struct Key_Value *kv)
Find given key (case sensitive)
Definition: key_value1.c:84
#define file
const char * name
Definition: named_colr.c:7
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:47
char * G_store(const char *s)
Copy string to allocated memory.
Definition: strings.c:87
void G_strip(char *buf)
Removes all leading and trailing white space from string.
Definition: strings.c:300