datum.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  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/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. char *name; /* Short Name / acronym of map datum */
  26. char *descr; /* Long Name for map datum */
  27. char *ellps; /* acronym for ellipsoid used with this datum */
  28. double dx; /* delta x */
  29. double dy; /* delta y */
  30. double dz; /* delta z */
  31. } *table;
  32. static int size;
  33. static int count = -1;
  34. static int compare_table_names(const void *, const void *);
  35. static void read_datum_table(void);
  36. int G_get_datum_by_name(const char *name)
  37. {
  38. int i;
  39. read_datum_table();
  40. for (i = 0; i < count; i++)
  41. if (G_strcasecmp(name, table[i].name) == 0)
  42. return i;
  43. return -1;
  44. }
  45. char *G_datum_name(int n)
  46. {
  47. read_datum_table();
  48. if (n < 0 || n >= count)
  49. return NULL;
  50. return table[n].name;
  51. }
  52. char *G_datum_description(int n)
  53. {
  54. read_datum_table();
  55. if (n < 0 || n >= count)
  56. return NULL;
  57. return table[n].descr;
  58. }
  59. char *G_datum_ellipsoid(int n)
  60. {
  61. read_datum_table();
  62. if (n < 0 || n >= count)
  63. return NULL;
  64. return table[n].ellps;
  65. }
  66. /***********************************************************
  67. * G_get_datumparams_from_projinfo(projinfo, datumname, params)
  68. * struct Key_Value *projinfo Set of key_value pairs containing
  69. * projection information in PROJ_INFO file
  70. * format
  71. * char *datumname Pointer into which a string containing
  72. * the datum name (if present) will be
  73. * placed.
  74. * char *params Pointer into which a string containing
  75. * the datum parameters (if present) will
  76. * be placed.
  77. *
  78. * Extract the datum transformation-related parameters from a
  79. * set of general PROJ_INFO parameters.
  80. * This function can be used to test if a location set-up
  81. * supports datum transformation.
  82. *
  83. * returns: -1 error or no datum information found,
  84. * 1 only datum name found, 2 params found
  85. ************************************************************/
  86. int G_get_datumparams_from_projinfo(const struct Key_Value *projinfo,
  87. char *datumname, char *params)
  88. {
  89. int returnval = -1;
  90. if (NULL != G_find_key_value("datum", projinfo)) {
  91. sprintf(datumname, G_find_key_value("datum", projinfo));
  92. returnval = 1;
  93. }
  94. if (G_find_key_value("datumparams", projinfo) != NULL) {
  95. sprintf(params, G_find_key_value("datumparams", projinfo));
  96. returnval = 2;
  97. }
  98. else if (G_find_key_value("nadgrids", projinfo) != NULL) {
  99. sprintf(params, "nadgrids=%s",
  100. G_find_key_value("nadgrids", projinfo));
  101. returnval = 2;
  102. }
  103. else if (G_find_key_value("towgs84", projinfo) != NULL) {
  104. sprintf(params, "towgs84=%s", G_find_key_value("towgs84", projinfo));
  105. returnval = 2;
  106. }
  107. else if (G_find_key_value("dx", projinfo) != NULL
  108. && G_find_key_value("dy", projinfo) != NULL
  109. && G_find_key_value("dz", projinfo) != NULL) {
  110. sprintf(params, "towgs84=%s,%s,%s",
  111. G_find_key_value("dx", projinfo),
  112. G_find_key_value("dy", projinfo),
  113. G_find_key_value("dz", projinfo));
  114. returnval = 2;
  115. }
  116. return returnval;
  117. }
  118. static void read_datum_table(void)
  119. {
  120. FILE *fd;
  121. char file[1024];
  122. char buf[1024];
  123. int line;
  124. if (count >= 0)
  125. return;
  126. count = 0;
  127. sprintf(file, "%s%s", G_gisbase(), DATUMTABLE);
  128. fd = fopen(file, "r");
  129. if (!fd) {
  130. G_warning(_("unable to open datum table file: %s"), file);
  131. return;
  132. }
  133. for (line = 1; G_getl2(buf, sizeof(buf), fd); line++) {
  134. char name[100], descr[100], ellps[100];
  135. struct table *t;
  136. G_strip(buf);
  137. if (*buf == '\0' || *buf == '#')
  138. continue;
  139. if (count >= size) {
  140. size += 50;
  141. table = G_realloc(table, size * sizeof(struct table));
  142. }
  143. t = &table[count];
  144. if (sscanf(buf, "%s \"%99[^\"]\" %s dx=%lf dy=%lf dz=%lf",
  145. name, descr, ellps, &t->dx, &t->dy, &t->dz) != 6) {
  146. G_warning(_("error in datum table file, line %d"), line);
  147. continue;
  148. }
  149. t->name = G_store(name);
  150. t->descr = G_store(descr);
  151. t->ellps = G_store(ellps);
  152. count++;
  153. }
  154. qsort(table, count, sizeof(struct table), compare_table_names);
  155. }
  156. static int compare_table_names(const void *aa, const void *bb)
  157. {
  158. const struct table *a = aa;
  159. const struct table *b = bb;
  160. return G_strcasecmp(a->name, b->name);
  161. }