datum.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: gis library
  5. * AUTHOR(S): Andreas Lange - andreas.lange@rhein-main.de
  6. * Paul Kelly - paul-grass@stjohnspoint.co.uk
  7. * PURPOSE: provide functions for reading datum parameters from the
  8. * location database.
  9. * COPYRIGHT: (C) 2000, 2003 by the GRASS Development Team
  10. *
  11. * This program is free software under the GNU General Public
  12. * License (>=v2). Read the file COPYING that comes with GRASS
  13. * for details.
  14. *
  15. *****************************************************************************/
  16. #define DATUMTABLE "/etc/proj/datum.table"
  17. #include <unistd.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <stdlib.h>
  21. #include <grass/gis.h>
  22. #include <grass/glocale.h>
  23. static struct table
  24. {
  25. struct datum
  26. {
  27. char *name; /* Short Name / acronym of map datum */
  28. char *descr; /* Long Name for map datum */
  29. char *ellps; /* acronym for ellipsoid used with this datum */
  30. double dx; /* delta x */
  31. double dy; /* delta y */
  32. double dz; /* delta z */
  33. } *datums;
  34. int size;
  35. int count;
  36. int initialized;
  37. } table;
  38. static int compare_table_names(const void *, const void *);
  39. int G_get_datum_by_name(const char *name)
  40. {
  41. int i;
  42. G_read_datum_table();
  43. for (i = 0; i < table.count; i++)
  44. if (G_strcasecmp(name, table.datums[i].name) == 0)
  45. return i;
  46. return -1;
  47. }
  48. const char *G_datum_name(int n)
  49. {
  50. G_read_datum_table();
  51. if (n < 0 || n >= table.count)
  52. return NULL;
  53. return table.datums[n].name;
  54. }
  55. const char *G_datum_description(int n)
  56. {
  57. G_read_datum_table();
  58. if (n < 0 || n >= table.count)
  59. return NULL;
  60. return table.datums[n].descr;
  61. }
  62. const char *G_datum_ellipsoid(int n)
  63. {
  64. G_read_datum_table();
  65. if (n < 0 || n >= table.count)
  66. return NULL;
  67. return table.datums[n].ellps;
  68. }
  69. /***********************************************************
  70. * G_get_datumparams_from_projinfo(projinfo, datumname, params)
  71. * struct Key_Value *projinfo Set of key_value pairs containing
  72. * projection information in PROJ_INFO file
  73. * format
  74. * char *datumname Pointer into which a string containing
  75. * the datum name (if present) will be
  76. * placed.
  77. * char *params Pointer into which a string containing
  78. * the datum parameters (if present) will
  79. * be placed.
  80. *
  81. * Extract the datum transformation-related parameters from a
  82. * set of general PROJ_INFO parameters.
  83. * This function can be used to test if a location set-up
  84. * supports datum transformation.
  85. *
  86. * returns: -1 error or no datum information found,
  87. * 1 only datum name found, 2 params found
  88. ************************************************************/
  89. int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo,
  90. char *datumname, char *params)
  91. {
  92. int returnval = -1;
  93. if (NULL != G_find_key_value("datum", projinfo)) {
  94. sprintf(datumname, "%s", G_find_key_value("datum", projinfo));
  95. returnval = 1;
  96. }
  97. if (G_find_key_value("datumparams", projinfo) != NULL) {
  98. sprintf(params, "%s", G_find_key_value("datumparams", projinfo));
  99. returnval = 2;
  100. }
  101. else if (G_find_key_value("nadgrids", projinfo) != NULL) {
  102. sprintf(params, "nadgrids=%s",
  103. G_find_key_value("nadgrids", projinfo));
  104. returnval = 2;
  105. }
  106. else if (G_find_key_value("towgs84", projinfo) != NULL) {
  107. sprintf(params, "towgs84=%s", G_find_key_value("towgs84", projinfo));
  108. returnval = 2;
  109. }
  110. else if (G_find_key_value("dx", projinfo) != NULL
  111. && G_find_key_value("dy", projinfo) != NULL
  112. && G_find_key_value("dz", projinfo) != NULL) {
  113. sprintf(params, "towgs84=%s,%s,%s",
  114. G_find_key_value("dx", projinfo),
  115. G_find_key_value("dy", projinfo),
  116. G_find_key_value("dz", projinfo));
  117. returnval = 2;
  118. }
  119. return returnval;
  120. }
  121. void G_read_datum_table(void)
  122. {
  123. FILE *fd;
  124. char file[GPATH_MAX];
  125. char buf[1024];
  126. int line;
  127. if (G_is_initialized(&table.initialized))
  128. return;
  129. sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
  130. fd = fopen(file, "r");
  131. if (!fd) {
  132. G_warning(_("unable to open datum table file: %s"), file);
  133. G_initialize_done(&table.initialized);
  134. return;
  135. }
  136. for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
  137. char name[100], descr[100], ellps[100];
  138. struct datum *t;
  139. G_strip(buf);
  140. if (*buf == '\0' || *buf == '#')
  141. continue;
  142. if (table.count >= table.size) {
  143. table.size += 50;
  144. table.datums = G_realloc(table.datums, table.size * sizeof(struct datum));
  145. }
  146. t = &table.datums[table.count];
  147. if (sscanf(buf, "%s \"%99[^\"]\" %s dx=%lf dy=%lf dz=%lf",
  148. name, descr, ellps, &t->dx, &t->dy, &t->dz) != 6) {
  149. G_warning(_("error in datum table file, line %d"), line);
  150. continue;
  151. }
  152. t->name = G_store(name);
  153. t->descr = G_store(descr);
  154. t->ellps = G_store(ellps);
  155. table.count++;
  156. }
  157. qsort(table.datums, table.count, sizeof(struct datum), compare_table_names);
  158. G_initialize_done(&table.initialized);
  159. }
  160. static int compare_table_names(const void *aa, const void *bb)
  161. {
  162. const struct datum *a = aa;
  163. const struct datum *b = bb;
  164. return G_strcasecmp(a->name, b->name);
  165. }