output.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  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) 2003-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 <unistd.h>
  18. #include <string.h>
  19. #include <grass/gis.h>
  20. #include <grass/gprojects.h>
  21. #include <grass/glocale.h>
  22. #include <grass/config.h>
  23. #include "local_proto.h"
  24. static int check_xy(int shell);
  25. /* print projection information gathered from one of the possible inputs
  26. * in GRASS format */
  27. void print_projinfo(int shell)
  28. {
  29. int i;
  30. if (check_xy(shell))
  31. return;
  32. if (!shell)
  33. fprintf(stdout,
  34. "-PROJ_INFO-------------------------------------------------\n");
  35. for (i = 0; i < projinfo->nitems; i++) {
  36. if (strcmp(projinfo->key[i], "init") == 0)
  37. continue;
  38. if (shell)
  39. fprintf(stdout, "%s=%s\n", projinfo->key[i], projinfo->value[i]);
  40. else
  41. fprintf(stdout, "%-11s: %s\n", projinfo->key[i], projinfo->value[i]);
  42. }
  43. /* TODO: use projsrid instead */
  44. if (projsrid) {
  45. if (!shell) {
  46. fprintf(stdout,
  47. "-PROJ_SRID-------------------------------------------------\n");
  48. fprintf(stdout, "%-11s: %s\n", "SRID", projsrid);
  49. }
  50. else
  51. fprintf(stdout, "%s=%s\n", "srid", projsrid);
  52. }
  53. if (projunits) {
  54. if (!shell)
  55. fprintf(stdout,
  56. "-PROJ_UNITS------------------------------------------------\n");
  57. for (i = 0; i < projunits->nitems; i++) {
  58. if (shell)
  59. fprintf(stdout, "%s=%s\n",
  60. projunits->key[i], projunits->value[i]);
  61. else
  62. fprintf(stdout, "%-11s: %s\n",
  63. projunits->key[i], projunits->value[i]);
  64. }
  65. }
  66. return;
  67. }
  68. /* DEPRECATED: datum transformation is handled by PROJ */
  69. void print_datuminfo(void)
  70. {
  71. char *datum, *params;
  72. struct gpj_datum dstruct;
  73. int validdatum = 0;
  74. if (check_xy(FALSE))
  75. return;
  76. GPJ__get_datum_params(projinfo, &datum, &params);
  77. if (datum)
  78. validdatum = GPJ_get_datum_by_name(datum, &dstruct);
  79. if (validdatum > 0)
  80. fprintf(stdout, "GRASS datum code: %s\nWKT Name: %s\n",
  81. dstruct.name, dstruct.longname);
  82. else if (datum)
  83. fprintf(stdout, "Invalid datum code: %s\n", datum);
  84. else
  85. fprintf(stdout, "Datum name not present\n");
  86. if (params)
  87. fprintf(stdout,
  88. "Datum transformation parameters (PROJ.4 format):\n"
  89. "\t%s\n", params);
  90. else if (validdatum > 0) {
  91. char *defparams;
  92. GPJ_get_default_datum_params_by_name(dstruct.name, &defparams);
  93. fprintf(stdout,
  94. "Datum parameters not present; default for %s is:\n"
  95. "\t%s\n", dstruct.name, defparams);
  96. G_free(defparams);
  97. }
  98. else
  99. fprintf(stdout, "Datum parameters not present\n");
  100. if (validdatum > 0)
  101. GPJ_free_datum(&dstruct);
  102. return;
  103. }
  104. /* print input projection information in PROJ format */
  105. void print_proj4(int dontprettify)
  106. {
  107. struct pj_info pjinfo;
  108. char *i, *projstrmod;
  109. const char *projstr;
  110. const char *unfact;
  111. if (check_xy(FALSE))
  112. return;
  113. projstr = NULL;
  114. projstrmod = NULL;
  115. #if PROJ_VERSION_MAJOR >= 6
  116. /* PROJ6+: create a PJ object from wkt or srid,
  117. * then get PROJ string using PROJ API */
  118. {
  119. PJ *obj = NULL;
  120. if (projwkt) {
  121. obj = proj_create_from_wkt(NULL, projwkt, NULL, NULL, NULL);
  122. }
  123. if (!obj && projsrid) {
  124. obj = proj_create(NULL, projsrid);
  125. }
  126. if (obj) {
  127. projstr = proj_as_proj_string(NULL, obj, PJ_PROJ_5, NULL);
  128. if (projstr)
  129. projstr = G_store(projstr);
  130. proj_destroy(obj);
  131. }
  132. }
  133. #endif
  134. if (!projstr) {
  135. if (pj_get_kv(&pjinfo, projinfo, projunits) == -1)
  136. G_fatal_error(_("Unable to convert projection information to PROJ format"));
  137. projstr = pjinfo.def;
  138. #if PROJ_VERSION_MAJOR >= 5
  139. proj_destroy(pjinfo.pj);
  140. #else
  141. pj_free(pjinfo.pj);
  142. #endif
  143. /* GRASS-style PROJ.4 strings don't include a unit factor as this is
  144. * handled separately in GRASS - must include it here though */
  145. unfact = G_find_key_value("meters", projunits);
  146. if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0))
  147. G_asprintf(&projstrmod, "%s +to_meter=%s", projstr, unfact);
  148. else
  149. projstrmod = G_store(projstr);
  150. }
  151. if (!projstrmod)
  152. projstrmod = G_store(projstr);
  153. for (i = projstrmod; *i; i++) {
  154. /* Don't print the first space */
  155. if (i == projstrmod && *i == ' ')
  156. continue;
  157. if (*i == ' ' && *(i + 1) == '+' && !(dontprettify))
  158. fputc('\n', stdout);
  159. else
  160. fputc(*i, stdout);
  161. }
  162. fputc('\n', stdout);
  163. G_free(projstrmod);
  164. return;
  165. }
  166. #ifdef HAVE_OGR
  167. void print_wkt(int esristyle, int dontprettify)
  168. {
  169. char *outwkt;
  170. if (check_xy(FALSE))
  171. return;
  172. outwkt = NULL;
  173. #if PROJ_VERSION_MAJOR >= 6
  174. /* print WKT2 using GDAL OSR interface */
  175. {
  176. OGRSpatialReferenceH hSRS;
  177. const char *tmpwkt;
  178. char **papszOptions = NULL;
  179. papszOptions = G_calloc(3, sizeof(char *));
  180. if (dontprettify)
  181. papszOptions[0] = G_store("MULTILINE=NO");
  182. else
  183. papszOptions[0] = G_store("MULTILINE=YES");
  184. if (esristyle)
  185. papszOptions[1] = G_store("FORMAT=WKT1_ESRI");
  186. else
  187. papszOptions[1] = G_store("FORMAT=WKT2");
  188. papszOptions[2] = NULL;
  189. hSRS = NULL;
  190. if (projsrid) {
  191. PJ *obj;
  192. obj = proj_create(NULL, projsrid);
  193. if (!obj)
  194. G_fatal_error(_("Unable to create PROJ definition from srid <%s>"), projsrid);
  195. tmpwkt = proj_as_wkt(NULL, obj, PJ_WKT2_LATEST, NULL);
  196. hSRS = OSRNewSpatialReference(tmpwkt);
  197. OSRExportToWktEx(hSRS, &outwkt, (const char **)papszOptions);
  198. }
  199. if (!outwkt && projwkt) {
  200. hSRS = OSRNewSpatialReference(projwkt);
  201. OSRExportToWktEx(hSRS, &outwkt, (const char **)papszOptions);
  202. }
  203. if (!outwkt && projepsg) {
  204. int epsg_num;
  205. epsg_num = atoi(G_find_key_value("epsg", projepsg));
  206. hSRS = OSRNewSpatialReference(NULL);
  207. OSRImportFromEPSG(hSRS, epsg_num);
  208. OSRExportToWktEx(hSRS, &outwkt, (const char **)papszOptions);
  209. }
  210. if (!outwkt) {
  211. /* use GRASS proj info + units */
  212. projwkt = GPJ_grass_to_wkt2(projinfo, projunits, projepsg, esristyle,
  213. !(dontprettify));
  214. hSRS = OSRNewSpatialReference(projwkt);
  215. OSRExportToWktEx(hSRS, &outwkt, (const char **)papszOptions);
  216. }
  217. G_free(papszOptions[0]);
  218. G_free(papszOptions[1]);
  219. G_free(papszOptions);
  220. if (hSRS)
  221. OSRDestroySpatialReference(hSRS);
  222. }
  223. #else
  224. outwkt = GPJ_grass_to_wkt2(projinfo, projunits, projepsg, esristyle,
  225. !(dontprettify));
  226. #endif
  227. if (outwkt != NULL) {
  228. fprintf(stdout, "%s\n", outwkt);
  229. G_free(outwkt);
  230. }
  231. else
  232. G_warning(_("Unable to convert to WKT"));
  233. return;
  234. }
  235. #endif
  236. static int check_xy(int shell)
  237. {
  238. if (cellhd.proj == PROJECTION_XY) {
  239. if (shell)
  240. fprintf(stdout, "name=xy_location_unprojected\n");
  241. else
  242. fprintf(stdout, "XY location (unprojected)\n");
  243. return 1;
  244. }
  245. else
  246. return 0;
  247. }