main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: g.proj
  5. * AUTHOR(S): Paul Kelly - paul-grass@stjohnspoint.co.uk
  6. * Shell script style by Martin Landa <landa.martin gmail.com>
  7. * PURPOSE: Provides a means of reporting the contents of GRASS
  8. * projection information files and creating
  9. * new projection information files.
  10. * COPYRIGHT: (C) 2003-2014 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General
  13. * Public License (>=v2). Read the file COPYING that
  14. * comes with GRASS for details.
  15. *
  16. *****************************************************************************/
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <grass/gis.h>
  20. #include <grass/glocale.h>
  21. #include <grass/config.h>
  22. #include "local_proto.h"
  23. struct Key_Value *projinfo, *projunits;
  24. struct Cell_head cellhd;
  25. int main(int argc, char *argv[])
  26. {
  27. struct Flag *printinfo, /* Print contents of PROJ_INFO & PROJ_UNITS */
  28. *shellinfo, /* Print in shell script style */
  29. *printproj4, /* Print projection in PROJ.4 format */
  30. *datuminfo, /* Check if datum information is present */
  31. *create, /* Create new projection files */
  32. #ifdef HAVE_OGR
  33. *printwkt, /* Print projection in WKT format */
  34. *esristyle, /* Use ESRI-style WKT format */
  35. #endif
  36. *dontprettify, /* Print 'flat' output (no linebreaks) */
  37. *forcedatumtrans; /* Force override of datumtrans parameters */
  38. struct Option *location, /* Name of new location to create */
  39. #ifdef HAVE_OGR
  40. *inepsg, /* EPSG projection code */
  41. *inwkt, /* Input file with projection in WKT format */
  42. *inproj4, /* Projection in PROJ.4 format */
  43. *ingeo, /* Input geo-referenced file readable by
  44. * GDAL or OGR */
  45. #endif
  46. *datum, /* datum to add (or replace existing datum) */
  47. *dtrans; /* index to datum transform option */
  48. struct GModule *module;
  49. int formats;
  50. G_set_program_name(argv[0]);
  51. G_no_gisinit(); /* We don't call G_gisinit() here because it validates the
  52. * mapset, whereas this module may legitmately be used
  53. * (to create a new location) when none exists */
  54. module = G_define_module();
  55. G_add_keyword(_("general"));
  56. G_add_keyword(_("projection"));
  57. G_add_keyword(_("create location"));
  58. #ifdef HAVE_OGR
  59. module->label =
  60. _("Prints or modifies GRASS projection information files "
  61. "(in various co-ordinate system descriptions).");
  62. module->description =
  63. _("Can also be used to create new GRASS locations.");
  64. #else
  65. module->description =
  66. _("Prints and manipulates GRASS projection information files.");
  67. #endif
  68. printinfo = G_define_flag();
  69. printinfo->key = 'p';
  70. printinfo->guisection = _("Print");
  71. printinfo->description =
  72. _("Print projection information in conventional GRASS format");
  73. shellinfo = G_define_flag();
  74. shellinfo->key = 'g';
  75. shellinfo->guisection = _("Print");
  76. shellinfo->description =
  77. _("Print projection information in shell script style");
  78. datuminfo = G_define_flag();
  79. datuminfo->key = 'd';
  80. datuminfo->guisection = _("Print");
  81. datuminfo->description =
  82. _("Verify datum information and print transformation parameters");
  83. printproj4 = G_define_flag();
  84. printproj4->key = 'j';
  85. printproj4->guisection = _("Print");
  86. printproj4->description =
  87. _("Print projection information in PROJ.4 format");
  88. dontprettify = G_define_flag();
  89. dontprettify->key = 'f';
  90. dontprettify->guisection = _("Print");
  91. dontprettify->description =
  92. _("Print 'flat' output with no linebreaks (applies to "
  93. #ifdef HAVE_OGR
  94. "WKT and "
  95. #endif
  96. "PROJ.4 output)");
  97. #ifdef HAVE_OGR
  98. printwkt = G_define_flag();
  99. printwkt->key = 'w';
  100. printwkt->guisection = _("Print");
  101. printwkt->description = _("Print projection information in WKT format");
  102. esristyle = G_define_flag();
  103. esristyle->key = 'e';
  104. esristyle->guisection = _("Print");
  105. esristyle->description =
  106. _("Use ESRI-style format (applies to WKT output only)");
  107. ingeo = G_define_option();
  108. ingeo->key = "georef";
  109. ingeo->type = TYPE_STRING;
  110. ingeo->key_desc = "file";
  111. ingeo->required = NO;
  112. ingeo->guisection = _("Specification");
  113. ingeo->description = _("Name of georeferenced data file to read projection "
  114. "information from");
  115. inwkt = G_define_option();
  116. inwkt->key = "wkt";
  117. inwkt->type = TYPE_STRING;
  118. inwkt->key_desc = "file";
  119. inwkt->required = NO;
  120. inwkt->guisection = _("Specification");
  121. inwkt->label = _("Name of ASCII file containing a WKT projection "
  122. "description");
  123. inwkt->description = _("'-' for standard input");
  124. inproj4 = G_define_option();
  125. inproj4->key = "proj4";
  126. inproj4->type = TYPE_STRING;
  127. inproj4->key_desc = "params";
  128. inproj4->required = NO;
  129. inproj4->guisection = _("Specification");
  130. inproj4->label = _("PROJ.4 projection description");
  131. inproj4->description = _("'-' for standard input");
  132. inepsg = G_define_option();
  133. inepsg->key = "epsg";
  134. inepsg->type = TYPE_INTEGER;
  135. inepsg->key_desc = "code";
  136. inepsg->required = NO;
  137. inepsg->options = "1-1000000";
  138. inepsg->guisection = _("Specification");
  139. inepsg->description = _("EPSG projection code");
  140. #endif
  141. datum = G_define_option();
  142. datum->key = "datum";
  143. datum->type = TYPE_STRING;
  144. datum->key_desc = "name";
  145. datum->required = NO;
  146. datum->guisection = _("Datum");
  147. datum->label =
  148. _("Datum (overrides any datum specified in input co-ordinate system)");
  149. datum->description =
  150. _("Accepts standard GRASS datum codes, or \"list\" to list and exit");
  151. dtrans = G_define_option();
  152. dtrans->key = "datum_trans";
  153. dtrans->type = TYPE_INTEGER;
  154. dtrans->key_desc = "index";
  155. dtrans->required = NO;
  156. dtrans->options = "-1-100";
  157. dtrans->answer = "0";
  158. dtrans->guisection = _("Datum");
  159. dtrans->label = _("Index number of datum transform parameters");
  160. dtrans->description = _("\"0\" for unspecified or \"-1\" to list and exit");
  161. forcedatumtrans = G_define_flag();
  162. forcedatumtrans->key = 't';
  163. forcedatumtrans->guisection = _("Datum");
  164. forcedatumtrans->description =
  165. _("Force override of datum transformation information in input "
  166. "co-ordinate system");
  167. create = G_define_flag();
  168. create->key = 'c';
  169. create->guisection = _("Modify");
  170. create->description = _("Modify current location projection files");
  171. location = G_define_option();
  172. location->key = "location";
  173. location->type = TYPE_STRING;
  174. location->key_desc = "name";
  175. location->required = NO;
  176. location->guisection = _("Create");
  177. location->description = _("Name of new location to create");
  178. if (G_parser(argc, argv))
  179. exit(EXIT_FAILURE);
  180. /* Initialisation & Validation */
  181. #ifdef HAVE_OGR
  182. /* -e implies -w */
  183. if (esristyle->answer && !printwkt->answer)
  184. printwkt->answer = 1;
  185. formats = ((ingeo->answer ? 1 : 0) + (inwkt->answer ? 1 : 0) +
  186. (inproj4->answer ? 1 : 0) + (inepsg->answer ? 1 : 0));
  187. if (formats > 1)
  188. G_fatal_error(_("Only one of '%s', '%s', '%s' or '%s' options may be specified"),
  189. ingeo->key, inwkt->key, inproj4->key, inepsg->key);
  190. /* List supported datums if requested; code originally
  191. * from G_ask_datum_name() (formerly in libgis) */
  192. if (datum->answer && strcmp(datum->answer, "list") == 0) {
  193. const char *dat;
  194. int i;
  195. for (i = 0; (dat = G_datum_name(i)); i++) {
  196. fprintf(stdout, "---\n%d\n%s\n%s\n%s ellipsoid\n",
  197. i, dat, G_datum_description(i), G_datum_ellipsoid(i));
  198. }
  199. exit(EXIT_SUCCESS);
  200. }
  201. /* Input */
  202. /* We can only have one input source, hence if..else construct */
  203. if (formats == 0)
  204. #endif
  205. /* Input is projection of current location */
  206. input_currloc();
  207. #ifdef HAVE_OGR
  208. else if (inwkt->answer)
  209. /* Input in WKT format */
  210. input_wkt(inwkt->answer);
  211. else if (inproj4->answer)
  212. /* Input in PROJ.4 format */
  213. input_proj4(inproj4->answer);
  214. else if (inepsg->answer)
  215. /* Input from EPSG code */
  216. input_epsg(atoi(inepsg->answer));
  217. else
  218. /* Input from georeferenced file */
  219. input_georef(ingeo->answer);
  220. #endif
  221. /* Consistency Check */
  222. if ((cellhd.proj != PROJECTION_XY)
  223. && (projinfo == NULL || projunits == NULL))
  224. G_fatal_error(_("Projection files missing"));
  225. /* Override input datum if requested */
  226. if(datum->answer)
  227. set_datum(datum->answer);
  228. /* Set Datum Parameters if necessary or requested */
  229. set_datumtrans(atoi(dtrans->answer), forcedatumtrans->answer);
  230. /* Output */
  231. /* Only allow one output format at a time, to reduce confusion */
  232. formats = ((printinfo->answer ? 1 : 0) + (shellinfo->answer ? 1 : 0) +
  233. (datuminfo->answer ? 1 : 0) +
  234. (printproj4->answer ? 1 : 0) +
  235. #ifdef HAVE_OGR
  236. (printwkt->answer ? 1 : 0) +
  237. #endif
  238. (create->answer ? 1 : 0));
  239. if (formats > 1)
  240. G_fatal_error(_("Only one of -%c, -%c, -%c, -%c"
  241. #ifdef HAVE_OGR
  242. ", -%c"
  243. #endif
  244. " or -%c flags may be specified"),
  245. printinfo->key, shellinfo->key, datuminfo->key, printproj4->key,
  246. #ifdef HAVE_OGR
  247. printwkt->key,
  248. #endif
  249. create->key);
  250. if (printinfo->answer || shellinfo->answer)
  251. print_projinfo(shellinfo->answer);
  252. else if (datuminfo->answer)
  253. print_datuminfo();
  254. else if (printproj4->answer)
  255. print_proj4(dontprettify->answer);
  256. #ifdef HAVE_OGR
  257. else if (printwkt->answer)
  258. print_wkt(esristyle->answer, dontprettify->answer);
  259. #endif
  260. else if (location->answer)
  261. create_location(location->answer);
  262. else if (create->answer)
  263. modify_projinfo();
  264. else
  265. #ifdef HAVE_OGR
  266. G_fatal_error(_("No output format specified, define one "
  267. "of flags -%c, -%c, -%c, or -%c"),
  268. printinfo->key, shellinfo->key, printproj4->key, printwkt->key);
  269. #else
  270. G_fatal_error(_("No output format specified, define one "
  271. "of flags -%c, -%c, or -%c"),
  272. printinfo->key, shellinfo->key, printproj4->key);
  273. #endif
  274. #ifdef HAVE_OGR
  275. if (create->answer && inepsg->answer) {
  276. #else
  277. if (create->answer){
  278. #endif
  279. /* preserve epsg code for user records only (not used by grass's pj routines) */
  280. FILE *fp;
  281. char path[GPATH_MAX];
  282. /* if inputs were not clean it should of failed by now */
  283. if (location->answer) {
  284. snprintf(path, sizeof(path), "%s/%s/%s/%s", G_gisdbase(),
  285. location->answer, "PERMANENT", "PROJ_EPSG");
  286. path[sizeof(path)-1] = '\0';
  287. }
  288. else
  289. G_file_name(path, "", "PROJ_EPSG", "PERMANENT");
  290. fp = fopen(path, "w");
  291. #ifdef HAVE_OGR
  292. fprintf(fp, "epsg: %s\n", inepsg->answer);
  293. #endif
  294. fclose(fp);
  295. }
  296. /* Tidy Up */
  297. if (projinfo != NULL)
  298. G_free_key_value(projinfo);
  299. if (projunits != NULL)
  300. G_free_key_value(projunits);
  301. exit(EXIT_SUCCESS);
  302. }