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