123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- /*!
- \file gis/proj3.c
- \brief GIS Library - Projection support (database)
-
- (C) 2001-2010 by the GRASS Development Team
-
- This program is free software under the GNU General Public License
- (>=v2). Read the file COPYING that comes with GRASS for details.
-
- \author Original author CERL
- */
- #include <string.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- static const char *lookup_proj(const char *);
- static const char *lookup_units(const char *);
- static int equal(const char *, const char *);
- static int lower(char);
- static int initialized;
- static struct Key_Value *proj_info, *proj_units;
- static void init(void)
- {
- if (G_is_initialized(&initialized))
- return;
- proj_info = G_get_projinfo();
- proj_units = G_get_projunits();
- G_initialize_done(&initialized);
- }
- /*!
- \brief Get database units (localized) name
-
- Returns a string describing the database grid units. It returns a
- plural form (eg. 'feet') if <i>plural</i> is non-zero. Otherwise it
- returns a singular form (eg. 'foot').
-
- \param plural plural form if non-zero
-
- \return localized units name
- */
- const char *G_database_unit_name(int plural)
- {
- int units;
- const char *name;
-
- units = G__projection_units(G_projection());
-
- if (units == U_UNDEFINED) {
- name = lookup_units(plural ? "units" : "unit");
- if (!name)
- return plural ? _("units") : _("unit");
-
- if (strcasecmp(name, "meter") == 0 || strcasecmp(name, "meters") == 0)
- units = U_METERS;
- else if (strcasecmp(name, "kilometer") == 0 || strcasecmp(name, "kilometers") == 0)
- units = U_KILOMETERS;
- else if (strcasecmp(name, "acre") == 0 || strcasecmp(name, "acres") == 0)
- units = U_ACRES;
- else if (strcasecmp(name, "hectare") == 0 || strcasecmp(name, "hectares") == 0)
- units = U_HECTARES;
- else if (strcasecmp(name, "mile") == 0 || strcasecmp(name, "miles") == 0)
- units = U_MILES;
- else if (strcasecmp(name, "foot") == 0 || strcasecmp(name, "feet") == 0)
- units = U_FEET;
- else if (strcasecmp(name, "degree") == 0 || strcasecmp(name, "degrees") == 0)
- units = U_DEGREES;
- else
- units = U_UNDEFINED;
- }
-
- return G_get_units_name(units, plural, FALSE);
- }
- /*!
- \brief Query cartographic projection
-
- Returns a pointer to a string which is a printable name for
- projection code <i>proj</i> (as returned by G_projection). Returns
- NULL if <i>proj</i> is not a valid projection.
-
- \return projection name
- */
- const char *G_database_projection_name(void)
- {
- int n;
- const char *name;
- switch (n = G_projection()) {
- case PROJECTION_XY:
- case PROJECTION_UTM:
- case PROJECTION_LL:
- case PROJECTION_SP:
- return G__projection_name(n);
- }
- name = lookup_proj("name");
- if (!name)
- return _("Unknown projection");
- return name;
- }
- /*!
- \brief Conversion to meters
-
- Returns a factor which converts the grid unit to meters (by
- multiplication). If the database is not metric (eg. imagery) then
- 0.0 is returned.
-
- \return value
- */
- double G_database_units_to_meters_factor(void)
- {
- const char *unit;
- const char *buf;
- double factor;
- int n;
- static const struct
- {
- char *unit;
- double factor;
- } table[] = {
- {"unit", 1.0},
- {"meter", 1.0},
- {"foot", .3048},
- {"inch", .0254},
- {NULL, 0.0}
- };
- factor = 0.0;
- buf = lookup_units("meters");
- if (buf)
- sscanf(buf, "%lf", &factor);
- if (factor <= 0.0) {
- unit = G_database_unit_name(0);
- for (n = 0; table[n].unit; n++)
- if (equal(unit, table[n].unit)) {
- factor = table[n].factor;
- break;
- }
- }
- return factor;
- }
- /*!
- \brief Get datum name for database
-
- Returns a pointer to the name of the map datum of the current
- database. If there is no map datum explicitely associated with the
- acutal database, the standard map datum WGS84 is returned, on error
- a NULL pointer is returned.
-
- \return datum name
- */
- const char *G_database_datum_name(void)
- {
- const char *name;
- char buf[256], params[256];
- int datumstatus;
- name = lookup_proj("datum");
- if (name)
- return name;
- else if (!proj_info)
- return NULL;
- else
- datumstatus = G_get_datumparams_from_projinfo(proj_info, buf, params);
- if (datumstatus == 2)
- return G_store(params);
- else
- return NULL;
- }
- /*!
- \brief Get ellipsoid name of current database
-
- \return pointer to valid name if ok
- \return NULL on error
- */
- const char *G_database_ellipse_name(void)
- {
- const char *name;
- name = lookup_proj("ellps");
- if (!name) {
- char buf[256];
- double a, es;
- G_get_ellipsoid_parameters(&a, &es);
- sprintf(buf, "a=%.16g es=%.16g", a, es);
- name = G_store(buf);
- }
- /* strcpy (name, "Unknown ellipsoid"); */
- return name;
- }
- static const char *lookup_proj(const char *key)
- {
- init();
- return G_find_key_value(key, proj_info);
- }
- static const char *lookup_units(const char *key)
- {
- init();
- return G_find_key_value(key, proj_units);
- }
- static int equal(const char *a, const char *b)
- {
- if (a == NULL || b == NULL)
- return a == b;
- while (*a && *b)
- if (lower(*a++) != lower(*b++))
- return 0;
- if (*a || *b)
- return 0;
- return 1;
- }
- static int lower(char c)
- {
- if (c >= 'A' && c <= 'Z')
- c += 'a' - 'A';
- return c;
- }
|