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