proj3.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*!
  2. \file gis/proj3.c
  3. \brief GIS Library - Projection support (database)
  4. (C) 2001-2010 by the GRASS Development Team
  5. This program is free software under the GNU General Public License
  6. (>=v2). Read the file COPYING that comes with GRASS for details.
  7. \author Original author CERL
  8. */
  9. #include <string.h>
  10. #include <grass/gis.h>
  11. #include <grass/glocale.h>
  12. static const char *lookup_proj(const char *);
  13. static const char *lookup_units(const char *);
  14. static int equal(const char *, const char *);
  15. static int lower(char);
  16. static int initialized;
  17. static struct Key_Value *proj_info, *proj_units;
  18. static void init(void)
  19. {
  20. if (G_is_initialized(&initialized))
  21. return;
  22. proj_info = G_get_projinfo();
  23. proj_units = G_get_projunits();
  24. G_initialize_done(&initialized);
  25. }
  26. /*!
  27. \brief Get database units name
  28. Returns a string describing the database grid units. It returns a
  29. plural form (eg. 'feet') if <i>plural</i> is true. Otherwise it
  30. returns a singular form (eg. 'foot').
  31. \param plural plural form if true
  32. \return units name
  33. */
  34. const char *G_database_unit_name(int plural)
  35. {
  36. int n;
  37. const char *name;
  38. switch (n = G_projection()) {
  39. case PROJECTION_XY:
  40. case PROJECTION_UTM:
  41. case PROJECTION_LL:
  42. case PROJECTION_SP:
  43. return G_get_units_name(G__projection_units(n), plural, 0);
  44. }
  45. name = lookup_units(plural ? "units" : "unit");
  46. if (!name)
  47. return plural ? "units" : "unit";
  48. return name;
  49. }
  50. /*!
  51. \brief Query cartographic projection
  52. Returns a pointer to a string which is a printable name for
  53. projection code <i>proj</i> (as returned by G_projection). Returns
  54. NULL if <i>proj</i> is not a valid projection.
  55. \return projection name
  56. */
  57. const char *G_database_projection_name(void)
  58. {
  59. int n;
  60. const char *name;
  61. switch (n = G_projection()) {
  62. case PROJECTION_XY:
  63. case PROJECTION_UTM:
  64. case PROJECTION_LL:
  65. case PROJECTION_SP:
  66. return G__projection_name(n);
  67. }
  68. name = lookup_proj("name");
  69. if (!name)
  70. return _("Unknown projection");
  71. return name;
  72. }
  73. /*!
  74. \brief Conversion to meters
  75. Returns a factor which converts the grid unit to meters (by
  76. multiplication). If the database is not metric (eg. imagery) then
  77. 0.0 is returned.
  78. \return value
  79. */
  80. double G_database_units_to_meters_factor(void)
  81. {
  82. const char *unit;
  83. const char *buf;
  84. double factor;
  85. int n;
  86. static const struct
  87. {
  88. char *unit;
  89. double factor;
  90. } table[] = {
  91. {"unit", 1.0},
  92. {"meter", 1.0},
  93. {"foot", .3048},
  94. {"inch", .0254},
  95. {NULL, 0.0}
  96. };
  97. factor = 0.0;
  98. buf = lookup_units("meters");
  99. if (buf)
  100. sscanf(buf, "%lf", &factor);
  101. if (factor <= 0.0) {
  102. unit = G_database_unit_name(0);
  103. for (n = 0; table[n].unit; n++)
  104. if (equal(unit, table[n].unit)) {
  105. factor = table[n].factor;
  106. break;
  107. }
  108. }
  109. return factor;
  110. }
  111. /*!
  112. \brief Get datum name for database
  113. Returns a pointer to the name of the map datum of the current
  114. database. If there is no map datum explicitely associated with the
  115. acutal database, the standard map datum WGS84 is returned, on error
  116. a NULL pointer is returned.
  117. \return datum name
  118. */
  119. const char *G_database_datum_name(void)
  120. {
  121. const char *name;
  122. char buf[256], params[256];
  123. int datumstatus;
  124. name = lookup_proj("datum");
  125. if (name)
  126. return name;
  127. else if (!proj_info)
  128. return NULL;
  129. else
  130. datumstatus = G_get_datumparams_from_projinfo(proj_info, buf, params);
  131. if (datumstatus == 2)
  132. return G_store(params);
  133. else
  134. return NULL;
  135. }
  136. /*!
  137. \brief Get ellipsoid name of current database
  138. \return pointer to valid name if ok
  139. \return NULL on error
  140. */
  141. const char *G_database_ellipse_name(void)
  142. {
  143. const char *name;
  144. name = lookup_proj("ellps");
  145. if (!name) {
  146. char buf[256];
  147. double a, es;
  148. G_get_ellipsoid_parameters(&a, &es);
  149. sprintf(buf, "a=%.16g es=%.16g", a, es);
  150. name = G_store(buf);
  151. }
  152. /* strcpy (name, "Unknown ellipsoid"); */
  153. return name;
  154. }
  155. static const char *lookup_proj(const char *key)
  156. {
  157. init();
  158. return G_find_key_value(key, proj_info);
  159. }
  160. static const char *lookup_units(const char *key)
  161. {
  162. init();
  163. return G_find_key_value(key, proj_units);
  164. }
  165. static int equal(const char *a, const char *b)
  166. {
  167. if (a == NULL || b == NULL)
  168. return a == b;
  169. while (*a && *b)
  170. if (lower(*a++) != lower(*b++))
  171. return 0;
  172. if (*a || *b)
  173. return 0;
  174. return 1;
  175. }
  176. static int lower(char c)
  177. {
  178. if (c >= 'A' && c <= 'Z')
  179. c += 'a' - 'A';
  180. return c;
  181. }