datum.c 5.1 KB

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