GRASS 8 Programmer's Manual 8.6.0dev(2026)-1878fdfec5
Loading...
Searching...
No Matches
proj3.c
Go to the documentation of this file.
1/*!
2 \file lib/gis/proj3.c
3
4 \brief GIS Library - Projection support (database)
5
6 SPDX-FileCopyrightText: 2001-2014 GRASS Development Team
7 SPDX-License-Identifier: GPL-2.0-or-later
8
9 \author Original author CERL
10 */
11
12/* TODO: the G_database_*() functions should be renamed to G_location_*()
13 * because they apply to a GRASS location, not to a GRASS database */
14
15#include <string.h>
16#include <grass/gis.h>
17#include <grass/glocale.h>
18
19static const char *lookup_proj(const char *);
20static const char *lookup_units(const char *);
21static const char *lookup_epsg(void);
22static int equal(const char *, const char *);
23static int lower(char);
24
25static int initialized;
26static struct Key_Value *proj_info, *proj_units, *proj_epsg;
27
28static void init(void)
29{
30 if (G_is_initialized(&initialized))
31 return;
32
33 proj_info = G_get_projinfo();
34 proj_units = G_get_projunits();
35 proj_epsg = G_get_projepsg();
36
37 G_initialize_done(&initialized);
38}
39
40/*!
41 \brief Get units (localized) name for the current location
42
43 Returns a string describing the database grid units. It returns a
44 plural form (eg. 'feet') if <i>plural</i> is non-zero. Otherwise it
45 returns a singular form (eg. 'foot').
46
47 \param plural plural form if non-zero
48
49 \return localized units name
50 */
52{
53 int units;
54
57}
58
59/*!
60 \brief Get units id for the current location
61
62 \return units id
63 */
65{
66 int units;
67 const char *name;
68
70
71 if (units == U_UNDEFINED) {
72 name = lookup_units("unit");
73 if (!name)
74 return U_UNKNOWN;
75
76 if (strcasecmp(name, "meter") == 0 || strcasecmp(name, "metre") == 0 ||
77 strcasecmp(name, "meters") == 0 || strcasecmp(name, "metres") == 0)
79 else if (strcasecmp(name, "kilometer") == 0 ||
80 strcasecmp(name, "kilometre") == 0 ||
81 strcasecmp(name, "kilometers") == 0 ||
82 strcasecmp(name, "kilometres") == 0)
84 else if (strcasecmp(name, "acre") == 0 ||
85 strcasecmp(name, "acres") == 0)
86 units = U_ACRES;
87 else if (strcasecmp(name, "hectare") == 0 ||
88 strcasecmp(name, "hectares") == 0)
90 else if (strcasecmp(name, "mile") == 0 ||
91 strcasecmp(name, "miles") == 0)
92 units = U_MILES;
93 else if (strcasecmp(name, "foot") == 0 || strcasecmp(name, "feet") == 0)
94 units = U_FEET;
95 else if (strcasecmp(name, "foot_us") == 0 ||
96 strcasecmp(name, "foot_uss") == 0)
98 else if (strcasecmp(name, "degree") == 0 ||
99 strcasecmp(name, "degrees") == 0)
101 else
103 }
104 return units;
105}
106
107/*!
108 \brief Query cartographic projection for the current location
109
110 Returns a pointer to a string which is a printable name for
111 projection code <i>proj</i> (as returned by G_projection). Returns
112 NULL if <i>proj</i> is not a valid projection.
113
114 \return projection name
115 */
117{
118 int n;
119 const char *name;
120
121 switch (n = G_projection()) {
122 case PROJECTION_XY:
123 case PROJECTION_UTM:
124 case PROJECTION_LL:
125 return G_projection_name(n);
126 }
127
128 name = lookup_proj("name");
129 if (!name)
130 return _("Unknown projection");
131
132 return name;
133}
134
135/*!
136 \brief Conversion to meters
137
138 Returns a factor which converts the grid unit to meters (by
139 multiplication). If the database is not metric (eg. imagery) then
140 0.0 is returned.
141
142 \return value
143 */
145{
146 const char *unit;
147 const char *buf;
148 double factor;
149 int n;
150
151 /* TODO: sync with definitions in ../proj/units.table */
152 static const struct {
153 char *unit;
154 double factor;
155 } table[] = {{"unit", 1.0}, {"meter", 1.0},
156 {"foot", .3048}, {"foot_us", 1200 / 3937.},
157 {"inch", .0254}, {NULL, 0.0}};
158
159 factor = 0.0;
160 buf = lookup_units("meters");
161 if (buf)
162 sscanf(buf, "%lf", &factor);
163 if (factor <= 0.0) {
164 unit = G_database_unit_name(0);
165 for (n = 0; table[n].unit; n++)
166 if (equal(unit, table[n].unit)) {
167 factor = table[n].factor;
168 break;
169 }
170 }
171 return factor;
172}
173
174/*!
175 \brief Get datum name for the current location
176
177 Returns a pointer to the name of the map datum of the current
178 database. If there is no map datum explicitly associated with the
179 actual database, the standard map datum WGS84 is returned, on error
180 a NULL pointer is returned.
181
182 \return datum name
183 */
184const char *G_database_datum_name(void)
185{
186 const char *name;
187 char buf[256], params[256];
188 int datumstatus;
189
190 name = lookup_proj("datum");
191 if (name)
192 return name;
193 else if (!proj_info)
194 return NULL;
195 else
196 datumstatus = G_get_datumparams_from_projinfo(proj_info, buf, params);
197
198 if (datumstatus == 2)
199 return G_store(params);
200 else
201 return NULL;
202}
203
204/*!
205 \brief Get ellipsoid name for the current location
206
207 \return pointer to valid name if ok
208 \return NULL on error
209 */
210const char *G_database_ellipse_name(void)
211{
212 const char *name;
213
214 name = lookup_proj("ellps");
215 if (!name) {
216 char buf[256];
217 double a, es;
218
220 snprintf(buf, sizeof(buf), "a=%.16g es=%.16g", a, es);
221 name = G_store(buf);
222 }
223
224 /* strcpy (name, "Unknown ellipsoid"); */
225 return name;
226}
227
228/*!
229 \brief Get EPGS code for the current location
230
231 \return pointer to valid EPSG code on success
232 \return NULL on error
233 */
234const char *G_database_epsg_code(void)
235{
236 return lookup_epsg();
237}
238
239const char *lookup_proj(const char *key)
240{
241 init();
242 return G_find_key_value(key, proj_info);
243}
244
245const char *lookup_units(const char *key)
246{
247 init();
248 return G_find_key_value(key, proj_units);
249}
250
251const char *lookup_epsg(void)
252{
253 init();
254 return G_find_key_value("epsg", proj_epsg);
255}
256
257int equal(const char *a, const char *b)
258{
259 if (a == NULL || b == NULL)
260 return a == b;
261 while (*a && *b)
262 if (lower(*a++) != lower(*b++))
263 return 0;
264 if (*a || *b)
265 return 0;
266 return 1;
267}
268
269int lower(char c)
270{
271 if (c >= 'A' && c <= 'Z')
272 c += 'a' - 'A';
273 return c;
274}
void init(double work[])
Definition as177.c:61
#define NULL
Definition ccmath.h:32
struct Key_Value * G_get_projinfo(void)
Gets projection information for location.
const char * G_projection_name(int)
Get projection name.
Definition proj2.c:53
int G_get_ellipsoid_parameters(double *, double *)
get ellipsoid parameters
Definition get_ellipse.c:64
struct Key_Value * G_get_projepsg(void)
Gets EPSG information for the current location.
const char * G_get_units_name(int, int, int)
Get localized units name.
Definition units.c:200
int G_projection_units(int)
Get projection units code (for internal use only)
Definition proj2.c:30
int G_get_datumparams_from_projinfo(const struct Key_Value *, char *, char *)
Definition gis/datum.c:104
const char * G_find_key_value(const char *, const struct Key_Value *)
Find given key (case sensitive)
Definition key_value1.c:83
int G_is_initialized(int *)
Definition counter.c:60
void G_initialize_done(int *)
Definition counter.c:77
char * G_store(const char *)
Copy string to allocated memory.
Definition strings.c:85
struct Key_Value * G_get_projunits(void)
Gets units information for location.
int G_projection(void)
Query cartographic projection.
Definition proj1.c:30
#define PROJECTION_XY
Projection code - XY coordinate system (unreferenced data)
Definition gis.h:120
#define U_UNDEFINED
List of units.
Definition gis.h:100
#define U_FEET
Definition gis.h:107
#define U_ACRES
Definition gis.h:102
#define U_METERS
Definition gis.h:105
#define U_DEGREES
Definition gis.h:109
#define PROJECTION_UTM
Projection code - UTM.
Definition gis.h:122
#define FALSE
Definition gis.h:79
#define U_UNKNOWN
Definition gis.h:101
#define U_HECTARES
Definition gis.h:103
#define PROJECTION_LL
Projection code - Latitude-Longitude.
Definition gis.h:126
#define U_USFEET
Definition gis.h:110
#define U_MILES
Definition gis.h:106
#define U_KILOMETERS
Definition gis.h:104
#define _(str)
Definition glocale.h:10
const char * name
Definition named_colr.c:6
const char * G_database_epsg_code(void)
Get EPGS code for the current location.
Definition proj3.c:234
double G_database_units_to_meters_factor(void)
Conversion to meters.
Definition proj3.c:144
const char * G_database_datum_name(void)
Get datum name for the current location.
Definition proj3.c:184
const char * G_database_ellipse_name(void)
Get ellipsoid name for the current location.
Definition proj3.c:210
int G_database_unit(void)
Get units id for the current location.
Definition proj3.c:64
const char * G_database_unit_name(int plural)
Get units (localized) name for the current location.
Definition proj3.c:51
const char * G_database_projection_name(void)
Query cartographic projection for the current location.
Definition proj3.c:116
double b
Definition r_raster.c:37
#define strcasecmp
Definition strings.h:8