datumtrans.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: g.proj
  5. * AUTHOR(S): Paul Kelly - paul-grass@stjohnspoint.co.uk
  6. * PURPOSE: Provides a means of reporting the contents of GRASS
  7. * projection information files and creating
  8. * new projection information files.
  9. * COPYRIGHT: (C) 2007 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. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <grass/gis.h>
  20. #include <grass/glocale.h>
  21. #include <grass/gprojects.h>
  22. #include "local_proto.h"
  23. /**
  24. *
  25. * \brief Add or replace datum to the current co-ordinate system definition
  26. *
  27. * \param datum Use this datum (overrides any datum found in the
  28. * current co-ordinate system definition).
  29. *
  30. * \return 1 if a change was made, 0 if not.
  31. **/
  32. int set_datum(char *datum)
  33. {
  34. struct gpj_datum dstruct;
  35. struct Key_Value *temp_projinfo;
  36. int i;
  37. if (cellhd.proj == PROJECTION_XY)
  38. return 0;
  39. if (!datum || GPJ_get_datum_by_name(datum, &dstruct) < 0)
  40. {
  41. G_fatal_error(_("Invalid datum code <%s>"), datum);
  42. return 0;
  43. }
  44. temp_projinfo = G_create_key_value();
  45. /* Copy old PROJ_INFO, skipping out any keys related
  46. * to datum or ellipsoid parameters */
  47. for (i = 0; i < projinfo->nitems; i++) {
  48. if (strcmp(projinfo->key[i], "datum") == 0
  49. || strcmp(projinfo->key[i], "dx") == 0
  50. || strcmp(projinfo->key[i], "dy") == 0
  51. || strcmp(projinfo->key[i], "dz") == 0
  52. || strcmp(projinfo->key[i], "datumparams") == 0
  53. || strcmp(projinfo->key[i], "nadgrids") == 0
  54. || strcmp(projinfo->key[i], "towgs84") == 0
  55. || strcmp(projinfo->key[i], "ellps") == 0
  56. || strcmp(projinfo->key[i], "a") == 0
  57. || strcmp(projinfo->key[i], "b") == 0
  58. || strcmp(projinfo->key[i], "es") == 0
  59. || strcmp(projinfo->key[i], "f") == 0
  60. || strcmp(projinfo->key[i], "rf") == 0)
  61. continue;
  62. G_set_key_value(projinfo->key[i], projinfo->value[i],
  63. temp_projinfo);
  64. }
  65. /* Finally add datum and ellipsoid names */
  66. G_set_key_value("datum", dstruct.name, temp_projinfo);
  67. G_message(_("Datum set to <%s>"), dstruct.name);
  68. G_set_key_value("ellps", dstruct.ellps, temp_projinfo);
  69. G_message(_("Ellipsoid set to <%s>"), dstruct.ellps);
  70. /* Destroy original key/value structure and replace with new one */
  71. G_free_key_value(projinfo);
  72. projinfo = temp_projinfo;
  73. return 1;
  74. }
  75. /**
  76. *
  77. * \brief Add or replace datum transformation parameters to the current
  78. * co-ordinate system definition
  79. *
  80. * \param datumtrans Index number of parameter set to use, 0 to leave
  81. * unspecified (or remove specific parameters, leaving just
  82. * the datum name), -1 to list the available parameter
  83. * sets for this datum and exit.
  84. *
  85. * \param force Force editing of parameters even if current co-ordinate
  86. * system already contains fully specified parameters.
  87. *
  88. * \return 1 if a change was made, 0 if not.
  89. **/
  90. int set_datumtrans(int datumtrans, int force)
  91. {
  92. char *params, *datum = NULL;
  93. int paramsets, status;
  94. if (cellhd.proj == PROJECTION_XY)
  95. return 0;
  96. status = GPJ__get_datum_params(projinfo, &datum, &params);
  97. G_debug(3, "set_datumtrans(): GPJ__get_datum_params() status=%d", status);
  98. G_free(params);
  99. if (datum) {
  100. /* A datum name is specified; need to determine if
  101. * there are parameters to choose from for this datum */
  102. struct gpj_datum dstruct;
  103. if (GPJ_get_datum_by_name(datum, &dstruct) > 0) {
  104. char *defparams;
  105. paramsets =
  106. GPJ_get_default_datum_params_by_name(dstruct.name,
  107. &defparams);
  108. G_free(defparams);
  109. GPJ_free_datum(&dstruct);
  110. G_debug(3, "set_datumtrans(): datum transform terms found "
  111. "with %d options", paramsets);
  112. if (paramsets > 1 && (status == 1 || datumtrans != 0))
  113. /* Parameters are missing and there is a choice to be
  114. made / or / user asked to print datum
  115. transformation parameters */
  116. force = 1;
  117. }
  118. else {
  119. /* Datum name not found in table; can't do anything. */
  120. G_debug(3, "set_datumtrans(): Datum name not found in table.");
  121. force = 0;
  122. }
  123. }
  124. else {
  125. /* No datum name; can't do anything. */
  126. G_debug(3, "set_datumtrans(): Datum name either invalid or not supplied.");
  127. force = 0;
  128. }
  129. if (force) {
  130. char *chosenparams = NULL;
  131. char *paramkey, *paramvalue;
  132. struct Key_Value *temp_projinfo;
  133. int i;
  134. /* First of all obtain the new parameters
  135. * through the supplied transform number index */
  136. {
  137. struct gpj_datum_transform_list *list;
  138. if (datumtrans > paramsets)
  139. G_fatal_error
  140. ("Invalid transformation number %d; valid range is 1 to %d",
  141. datumtrans, paramsets);
  142. G_debug(3, "set_datumtrans(): looking up available datum "
  143. "transforms for <%s>", datum);
  144. list = GPJ_get_datum_transform_by_name(datum);
  145. if (list != NULL) {
  146. if (datumtrans == -1) {
  147. do {
  148. struct gpj_datum_transform_list *old = list;
  149. fprintf(stdout, "---\n%d\nUsed in %s\n%s\n%s\n",
  150. list->count, list->where_used,
  151. list->params, list->comment);
  152. list = list->next;
  153. GPJ_free_datum_transform(old);
  154. } while (list != NULL);
  155. exit(EXIT_SUCCESS);
  156. }
  157. else {
  158. do {
  159. struct gpj_datum_transform_list *old = list;
  160. if (list->count == datumtrans)
  161. chosenparams = G_store(list->params);
  162. list = list->next;
  163. GPJ_free_datum_transform(old);
  164. } while (list != NULL);
  165. }
  166. }
  167. }
  168. temp_projinfo = G_create_key_value();
  169. /* Copy old PROJ_INFO, skipping out any keys related
  170. * to datum parameters */
  171. for (i = 0; i < projinfo->nitems; i++) {
  172. if (strcmp(projinfo->key[i], "dx") == 0
  173. || strcmp(projinfo->key[i], "dy") == 0
  174. || strcmp(projinfo->key[i], "dz") == 0
  175. || strcmp(projinfo->key[i], "datumparams") == 0
  176. || strcmp(projinfo->key[i], "nadgrids") == 0
  177. || strcmp(projinfo->key[i], "towgs84") == 0)
  178. continue;
  179. G_set_key_value(projinfo->key[i], projinfo->value[i],
  180. temp_projinfo);
  181. }
  182. /* Finally add new parameters (if we have them) */
  183. if (chosenparams != NULL) {
  184. /* Now split 'chosenparams' into key/value format */
  185. paramkey = strtok(chosenparams, "=");
  186. paramvalue = chosenparams + strlen(paramkey) + 1;
  187. G_set_key_value(paramkey, paramvalue, temp_projinfo);
  188. G_free(chosenparams);
  189. }
  190. /* Destroy original key/value structure and replace with new one */
  191. G_free_key_value(projinfo);
  192. projinfo = temp_projinfo;
  193. }
  194. G_free(datum);
  195. return force;
  196. }