main.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  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-2007, 2011 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 and manipulates 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 = _("Create new projection files (modifies current "
  171. "location)");
  172. location = G_define_option();
  173. location->key = "location";
  174. location->type = TYPE_STRING;
  175. location->key_desc = "name";
  176. location->required = NO;
  177. location->guisection = _("Create");
  178. location->description = _("Name of new location to create");
  179. if (G_parser(argc, argv))
  180. exit(EXIT_FAILURE);
  181. /* Initialisation & Validation */
  182. #ifdef HAVE_OGR
  183. /* -e implies -w */
  184. if (esristyle->answer && !printwkt->answer)
  185. printwkt->answer = 1;
  186. formats = ((ingeo->answer ? 1 : 0) + (inwkt->answer ? 1 : 0) +
  187. (inproj4->answer ? 1 : 0) + (inepsg->answer ? 1 : 0));
  188. if (formats > 1)
  189. G_fatal_error(_("Only one of '%s', '%s', '%s' or '%s' options may be specified"),
  190. ingeo->key, inwkt->key, inproj4->key, inepsg->key);
  191. /* List supported datums if requested; code originally
  192. * from G_ask_datum_name() (formerly in libgis) */
  193. if (datum->answer && strcmp(datum->answer, "list") == 0) {
  194. const char *dat;
  195. int i;
  196. for (i = 0; (dat = G_datum_name(i)); i++) {
  197. fprintf(stdout, "---\n%d\n%s\n%s\n%s ellipsoid\n",
  198. i, dat, G_datum_description(i), G_datum_ellipsoid(i));
  199. }
  200. exit(EXIT_SUCCESS);
  201. }
  202. /* Input */
  203. /* We can only have one input source, hence if..else construct */
  204. if (formats == 0)
  205. #endif
  206. /* Input is projection of current location */
  207. input_currloc();
  208. #ifdef HAVE_OGR
  209. else if (inwkt->answer)
  210. /* Input in WKT format */
  211. input_wkt(inwkt->answer);
  212. else if (inproj4->answer)
  213. /* Input in PROJ.4 format */
  214. input_proj4(inproj4->answer);
  215. else if (inepsg->answer)
  216. /* Input from EPSG code */
  217. input_epsg(atoi(inepsg->answer));
  218. else
  219. /* Input from georeferenced file */
  220. input_georef(ingeo->answer);
  221. #endif
  222. /* Consistency Check */
  223. if ((cellhd.proj != PROJECTION_XY)
  224. && (projinfo == NULL || projunits == NULL))
  225. G_fatal_error(_("Projection files missing"));
  226. /* Override input datum if requested */
  227. if(datum->answer)
  228. set_datum(datum->answer);
  229. /* Set Datum Parameters if necessary or requested */
  230. set_datumtrans(atoi(dtrans->answer), forcedatumtrans->answer);
  231. /* Output */
  232. /* Only allow one output format at a time, to reduce confusion */
  233. formats = ((printinfo->answer ? 1 : 0) + (shellinfo->answer ? 1 : 0) +
  234. (datuminfo->answer ? 1 : 0) +
  235. (printproj4->answer ? 1 : 0) +
  236. #ifdef HAVE_OGR
  237. (printwkt->answer ? 1 : 0) +
  238. #endif
  239. (create->answer ? 1 : 0));
  240. if (formats > 1)
  241. G_fatal_error(_("Only one of -%c, -%c, -%c, -%c"
  242. #ifdef HAVE_OGR
  243. ", -%c"
  244. #endif
  245. " or -%c flags may be specified"),
  246. printinfo->key, shellinfo->key, datuminfo->key, printproj4->key,
  247. #ifdef HAVE_OGR
  248. printwkt->key,
  249. #endif
  250. create->key);
  251. if (printinfo->answer || shellinfo->answer)
  252. print_projinfo(shellinfo->answer);
  253. else if (datuminfo->answer)
  254. print_datuminfo();
  255. else if (printproj4->answer)
  256. print_proj4(dontprettify->answer);
  257. #ifdef HAVE_OGR
  258. else if (printwkt->answer)
  259. print_wkt(esristyle->answer, dontprettify->answer);
  260. #endif
  261. else if (location->answer)
  262. create_location(location->answer);
  263. else if (create->answer)
  264. modify_projinfo();
  265. else
  266. #ifdef HAVE_OGR
  267. G_fatal_error(_("No output format specified, define one "
  268. "of flags -%c, -%c, -%c, or -%c"),
  269. printinfo->key, shellinfo->key, printproj4->key, printwkt->key);
  270. #else
  271. G_fatal_error(_("No output format specified, define one "
  272. "of flags -%c, -%c, or -%c"),
  273. printinfo->key, shellinfo->key, printproj4->key);
  274. #endif
  275. #ifdef HAVE_OGR
  276. if (create->answer && inepsg->answer) {
  277. #else
  278. if (create->answer){
  279. #endif
  280. /* preserve epsg code for user records only (not used by grass's pj routines) */
  281. FILE *fp;
  282. char path[GPATH_MAX];
  283. /* if inputs were not clean it should of failed by now */
  284. if (location->answer) {
  285. snprintf(path, sizeof(path), "%s/%s/%s/%s", G_gisdbase(),
  286. location->answer, "PERMANENT", "PROJ_EPSG");
  287. path[sizeof(path)-1] = '\0';
  288. }
  289. else
  290. G_file_name(path, "", "PROJ_EPSG", "PERMANENT");
  291. fp = fopen(path, "w");
  292. #ifdef HAVE_OGR
  293. fprintf(fp, "epsg: %s\n", inepsg->answer);
  294. #endif
  295. fclose(fp);
  296. }
  297. /* Tidy Up */
  298. if (projinfo != NULL)
  299. G_free_key_value(projinfo);
  300. if (projunits != NULL)
  301. G_free_key_value(projunits);
  302. exit(EXIT_SUCCESS);
  303. }