datumtrans.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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/gprojects.h>
  21. #include "local_proto.h"
  22. /**
  23. *
  24. * \brief Add or replace datum transformation parameters to the current
  25. * co-ordinate system definition
  26. *
  27. * \param datumtrans Index number of parameter set to use, 0 to leave
  28. * unspecifed (or remove specific parameters, leaving just
  29. * the datum name), -1 to list the available parameter
  30. * sets for this datum and exit.
  31. *
  32. * \param force Force editing of parameters even if current co-ordinate
  33. * system already contains fully specified parameters.
  34. *
  35. * \return 1 if a change was made, 0 if not.
  36. **/
  37. int set_datumtrans(int datumtrans, int force)
  38. {
  39. char *params, *datum = NULL;
  40. int paramsets, status;
  41. if (cellhd.proj == PROJECTION_XY)
  42. return 0;
  43. status = GPJ__get_datum_params(projinfo, &datum, &params);
  44. G_free(params);
  45. if (datum) {
  46. /* A datum name is specified; need to determine if
  47. * there are parameters to choose from for this datum */
  48. struct gpj_datum dstruct;
  49. if (GPJ_get_datum_by_name(datum, &dstruct) > 0) {
  50. char *defparams;
  51. paramsets =
  52. GPJ_get_default_datum_params_by_name(dstruct.name,
  53. &defparams);
  54. G_free(defparams);
  55. GPJ_free_datum(&dstruct);
  56. if (status == 1 && paramsets > 1)
  57. /* Parameters are missing and there is a choice to be made */
  58. force = 1;
  59. }
  60. else
  61. /* Datum name not found in table; can't do anything. */
  62. force = 0;
  63. }
  64. else
  65. /* No datum name; can't do anything. */
  66. force = 0;
  67. if (force) {
  68. char *chosenparams = NULL;
  69. char *paramkey, *paramvalue;
  70. struct Key_Value *temp_projinfo;
  71. int i;
  72. /* First of all obtain the new parameters
  73. * through the supplied transform number index */
  74. {
  75. struct gpj_datum_transform_list *list;
  76. if (datumtrans > paramsets)
  77. G_fatal_error
  78. ("Invalid transformation number %d; valid range is 1 to %d",
  79. datumtrans, paramsets);
  80. list = GPJ_get_datum_transform_by_name(datum);
  81. if (list != NULL) {
  82. if (datumtrans == -1) {
  83. do {
  84. struct gpj_datum_transform_list *old = list;
  85. fprintf(stdout, "---\n%d\nUsed in %s\n%s\n%s\n",
  86. list->count, list->where_used,
  87. list->params, list->comment);
  88. list = list->next;
  89. GPJ_free_datum_transform(old);
  90. } while (list != NULL);
  91. exit(EXIT_SUCCESS);
  92. }
  93. else {
  94. do {
  95. struct gpj_datum_transform_list *old = list;
  96. if (list->count == datumtrans)
  97. chosenparams = G_store(list->params);
  98. list = list->next;
  99. GPJ_free_datum_transform(old);
  100. } while (list != NULL);
  101. }
  102. }
  103. }
  104. temp_projinfo = G_create_key_value();
  105. /* Copy old PROJ_INFO, skipping out any keys related
  106. * to datum parameters */
  107. for (i = 0; i < projinfo->nitems; i++) {
  108. if (strcmp(projinfo->key[i], "dx") == 0
  109. || strcmp(projinfo->key[i], "dy") == 0
  110. || strcmp(projinfo->key[i], "dz") == 0
  111. || strcmp(projinfo->key[i], "datumparams") == 0
  112. || strcmp(projinfo->key[i], "nadgrids") == 0
  113. || strcmp(projinfo->key[i], "towgs84") == 0)
  114. continue;
  115. G_set_key_value(projinfo->key[i], projinfo->value[i],
  116. temp_projinfo);
  117. }
  118. /* Finally add new parameters (if we have them) */
  119. if (chosenparams != NULL) {
  120. /* Now split 'chosenparams' into key/value format */
  121. paramkey = strtok(chosenparams, "=");
  122. paramvalue = chosenparams + strlen(paramkey) + 1;
  123. G_set_key_value(paramkey, paramvalue, temp_projinfo);
  124. G_free(chosenparams);
  125. }
  126. /* Destroy original key/value structure and replace with new one */
  127. G_free_key_value(projinfo);
  128. projinfo = temp_projinfo;
  129. }
  130. G_free(datum);
  131. return force;
  132. }