proj3.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #include <string.h>
  2. #include <grass/gis.h>
  3. #include <grass/glocale.h>
  4. static const char *lookup_proj(const char *);
  5. static const char *lookup_units(const char *);
  6. static int equal(const char *, const char *);
  7. static int lower(char);
  8. static int initialized;
  9. static struct Key_Value *proj_info, *proj_units;
  10. static void init(void)
  11. {
  12. if (G_is_initialized(&initialized))
  13. return;
  14. proj_info = G_get_projinfo();
  15. proj_units = G_get_projunits();
  16. G_initialize_done(&initialized);
  17. }
  18. /*!
  19. * \brief database units
  20. *
  21. * Returns a
  22. * string describing the database grid units. It returns a plural form (eg. feet)
  23. * if <b>plural</b> is true. Otherwise it returns a singular form (eg. foot).
  24. *
  25. * \param plural
  26. * \return char *
  27. */
  28. const char *G_database_unit_name(int plural)
  29. {
  30. int n;
  31. const char *name;
  32. switch (n = G_projection()) {
  33. case PROJECTION_XY:
  34. case PROJECTION_UTM:
  35. case PROJECTION_LL:
  36. case PROJECTION_SP:
  37. return G__unit_name(G__projection_units(n), plural);
  38. }
  39. name = lookup_units(plural ? "units" : "unit");
  40. if (!name)
  41. return plural ? "units" : "unit";
  42. return name;
  43. }
  44. /*!
  45. * \brief query cartographic projection
  46. *
  47. * Returns a pointer to a string which is a printable name for
  48. * projection code <b>proj</b> (as returned by <i>G_projection</i>). Returns
  49. * NULL if <b>proj</b> is not a valid projection.
  50. *
  51. * \param proj
  52. * \return char *
  53. */
  54. const char *G_database_projection_name(void)
  55. {
  56. int n;
  57. const char *name;
  58. switch (n = G_projection()) {
  59. case PROJECTION_XY:
  60. case PROJECTION_UTM:
  61. case PROJECTION_LL:
  62. case PROJECTION_SP:
  63. return G__projection_name(n);
  64. }
  65. name = lookup_proj("name");
  66. if (!name)
  67. return _("Unknown projection");
  68. return name;
  69. }
  70. /*!
  71. * \brief conversion to meters
  72. *
  73. * Returns a factor which converts the grid unit to meters (by
  74. * multiplication). If the database is not metric (eg. imagery) then 0.0 is
  75. * returned.
  76. *
  77. * \param void
  78. * \return double
  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. * G_database_datum_name(void)
  113. *
  114. * return name of datum of current database
  115. *
  116. * returns pointer to valid name if ok
  117. * NULL otherwise
  118. ***********************************************************************/
  119. /*!
  120. * \brief get datum name for database
  121. *
  122. * Returns a pointer to the name of the map datum of the current database. If
  123. * there is no map datum explicitely associated with the acutal database, the
  124. * standard map datum WGS84 is returned, on error a NULL pointer is returned.
  125. *
  126. * \return char *
  127. */
  128. const char *G_database_datum_name(void)
  129. {
  130. const char *name;
  131. char buf[256], params[256];
  132. int datumstatus;
  133. name = lookup_proj("datum");
  134. if (name)
  135. return name;
  136. else if (!proj_info)
  137. return NULL;
  138. else
  139. datumstatus = G_get_datumparams_from_projinfo(proj_info, buf, params);
  140. if (datumstatus == 2)
  141. return G_store(params);
  142. else
  143. return NULL;
  144. }
  145. /***********************************************************************
  146. * G_database_ellipse_name(void)
  147. *
  148. * return name of ellipsoid of current database
  149. *
  150. * returns pointer to valid name if ok
  151. * NULL otherwise
  152. ***********************************************************************/
  153. const char *G_database_ellipse_name(void)
  154. {
  155. const char *name;
  156. name = lookup_proj("ellps");
  157. if (!name) {
  158. char buf[256];
  159. double a, es;
  160. G_get_ellipsoid_parameters(&a, &es);
  161. sprintf(buf, "a=%.16g es=%.16g", a, es);
  162. name = G_store(buf);
  163. }
  164. /* strcpy (name, "Unknown ellipsoid"); */
  165. return name;
  166. }
  167. static const char *lookup_proj(const char *key)
  168. {
  169. init();
  170. return G_find_key_value(key, proj_info);
  171. }
  172. static const char *lookup_units(const char *key)
  173. {
  174. init();
  175. return G_find_key_value(key, proj_units);
  176. }
  177. static int equal(const char *a, const char *b)
  178. {
  179. if (a == NULL || b == NULL)
  180. return a == b;
  181. while (*a && *b)
  182. if (lower(*a++) != lower(*b++))
  183. return 0;
  184. if (*a || *b)
  185. return 0;
  186. return 1;
  187. }
  188. static int lower(char c)
  189. {
  190. if (c >= 'A' && c <= 'Z')
  191. c += 'a' - 'A';
  192. return c;
  193. }