main.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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-2015 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. const char *epsg = NULL;
  51. G_set_program_name(argv[0]);
  52. G_no_gisinit(); /* We don't call G_gisinit() here because it validates the
  53. * mapset, whereas this module may legitmately be used
  54. * (to create a new location) when none exists */
  55. module = G_define_module();
  56. G_add_keyword(_("general"));
  57. G_add_keyword(_("projection"));
  58. G_add_keyword(_("create location"));
  59. #ifdef HAVE_OGR
  60. module->label =
  61. _("Prints or modifies GRASS projection information files "
  62. "(in various co-ordinate system descriptions).");
  63. module->description =
  64. _("Can also be used to create new GRASS locations.");
  65. #else
  66. module->description =
  67. _("Prints and manipulates GRASS projection information files.");
  68. #endif
  69. printinfo = G_define_flag();
  70. printinfo->key = 'p';
  71. printinfo->guisection = _("Print");
  72. printinfo->description =
  73. _("Print projection information in conventional GRASS format");
  74. shellinfo = G_define_flag();
  75. shellinfo->key = 'g';
  76. shellinfo->guisection = _("Print");
  77. shellinfo->description =
  78. _("Print projection information in shell script style");
  79. datuminfo = G_define_flag();
  80. datuminfo->key = 'd';
  81. datuminfo->guisection = _("Print");
  82. datuminfo->description =
  83. _("Verify datum information and print transformation parameters");
  84. printproj4 = G_define_flag();
  85. printproj4->key = 'j';
  86. printproj4->guisection = _("Print");
  87. printproj4->description =
  88. _("Print projection information in PROJ.4 format");
  89. dontprettify = G_define_flag();
  90. dontprettify->key = 'f';
  91. dontprettify->guisection = _("Print");
  92. dontprettify->description =
  93. _("Print 'flat' output with no linebreaks (applies to "
  94. #ifdef HAVE_OGR
  95. "WKT and "
  96. #endif
  97. "PROJ.4 output)");
  98. #ifdef HAVE_OGR
  99. printwkt = G_define_flag();
  100. printwkt->key = 'w';
  101. printwkt->guisection = _("Print");
  102. printwkt->description = _("Print projection information in WKT format");
  103. esristyle = G_define_flag();
  104. esristyle->key = 'e';
  105. esristyle->guisection = _("Print");
  106. esristyle->description =
  107. _("Use ESRI-style format (applies to WKT output only)");
  108. ingeo = G_define_option();
  109. ingeo->key = "georef";
  110. ingeo->type = TYPE_STRING;
  111. ingeo->key_desc = "file";
  112. ingeo->required = NO;
  113. ingeo->guisection = _("Specification");
  114. ingeo->description = _("Name of georeferenced data file to read projection "
  115. "information from");
  116. inwkt = G_define_option();
  117. inwkt->key = "wkt";
  118. inwkt->type = TYPE_STRING;
  119. inwkt->key_desc = "file";
  120. inwkt->required = NO;
  121. inwkt->guisection = _("Specification");
  122. inwkt->label = _("Name of ASCII file containing a WKT projection "
  123. "description");
  124. inwkt->description = _("'-' for standard input");
  125. inproj4 = G_define_option();
  126. inproj4->key = "proj4";
  127. inproj4->type = TYPE_STRING;
  128. inproj4->key_desc = "params";
  129. inproj4->required = NO;
  130. inproj4->guisection = _("Specification");
  131. inproj4->label = _("PROJ.4 projection description");
  132. inproj4->description = _("'-' for standard input");
  133. inepsg = G_define_option();
  134. inepsg->key = "epsg";
  135. inepsg->type = TYPE_INTEGER;
  136. inepsg->key_desc = "code";
  137. inepsg->required = NO;
  138. inepsg->options = "1-1000000";
  139. inepsg->guisection = _("Specification");
  140. inepsg->description = _("EPSG projection code");
  141. #endif
  142. datum = G_define_option();
  143. datum->key = "datum";
  144. datum->type = TYPE_STRING;
  145. datum->key_desc = "name";
  146. datum->required = NO;
  147. datum->guisection = _("Datum");
  148. datum->label =
  149. _("Datum (overrides any datum specified in input co-ordinate system)");
  150. datum->description =
  151. _("Accepts standard GRASS datum codes, or \"list\" to list and exit");
  152. dtrans = G_define_option();
  153. dtrans->key = "datum_trans";
  154. dtrans->type = TYPE_INTEGER;
  155. dtrans->key_desc = "index";
  156. dtrans->required = NO;
  157. dtrans->options = "-1-100";
  158. dtrans->answer = "0";
  159. dtrans->guisection = _("Datum");
  160. dtrans->label = _("Index number of datum transform parameters");
  161. dtrans->description = _("\"0\" for unspecified or \"-1\" to list and exit");
  162. forcedatumtrans = G_define_flag();
  163. forcedatumtrans->key = 't';
  164. forcedatumtrans->guisection = _("Datum");
  165. forcedatumtrans->description =
  166. _("Force override of datum transformation information in input "
  167. "co-ordinate system");
  168. create = G_define_flag();
  169. create->key = 'c';
  170. create->guisection = _("Modify");
  171. create->description = _("Modify current location projection files");
  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. epsg = inepsg->answer;
  203. /* Input */
  204. /* We can only have one input source, hence if..else construct */
  205. if (formats == 0)
  206. #endif
  207. /* Input is projection of current location */
  208. input_currloc();
  209. #ifdef HAVE_OGR
  210. else if (inwkt->answer)
  211. /* Input in WKT format */
  212. input_wkt(inwkt->answer);
  213. else if (inproj4->answer)
  214. /* Input in PROJ.4 format */
  215. input_proj4(inproj4->answer);
  216. else if (epsg)
  217. /* Input from EPSG code */
  218. input_epsg(atoi(epsg));
  219. else
  220. /* Input from georeferenced file */
  221. input_georef(ingeo->answer);
  222. #endif
  223. /* Consistency Check */
  224. if ((cellhd.proj != PROJECTION_XY)
  225. && (projinfo == NULL || projunits == NULL))
  226. G_fatal_error(_("Projection files missing"));
  227. /* Override input datum if requested */
  228. if(datum->answer)
  229. set_datum(datum->answer);
  230. /* Set Datum Parameters if necessary or requested */
  231. set_datumtrans(atoi(dtrans->answer), forcedatumtrans->answer);
  232. /* Output */
  233. /* Only allow one output format at a time, to reduce confusion */
  234. formats = ((printinfo->answer ? 1 : 0) + (shellinfo->answer ? 1 : 0) +
  235. (datuminfo->answer ? 1 : 0) +
  236. (printproj4->answer ? 1 : 0) +
  237. #ifdef HAVE_OGR
  238. (printwkt->answer ? 1 : 0) +
  239. #endif
  240. (create->answer ? 1 : 0));
  241. if (formats > 1)
  242. G_fatal_error(_("Only one of -%c, -%c, -%c, -%c"
  243. #ifdef HAVE_OGR
  244. ", -%c"
  245. #endif
  246. " or -%c flags may be specified"),
  247. printinfo->key, shellinfo->key, datuminfo->key, printproj4->key,
  248. #ifdef HAVE_OGR
  249. printwkt->key,
  250. #endif
  251. create->key);
  252. if (printinfo->answer || shellinfo->answer)
  253. print_projinfo(shellinfo->answer, epsg);
  254. else if (datuminfo->answer)
  255. print_datuminfo();
  256. else if (printproj4->answer)
  257. print_proj4(dontprettify->answer);
  258. #ifdef HAVE_OGR
  259. else if (printwkt->answer)
  260. print_wkt(esristyle->answer, dontprettify->answer);
  261. #endif
  262. else if (location->answer)
  263. create_location(location->answer, epsg);
  264. else if (create->answer)
  265. modify_projinfo();
  266. else
  267. #ifdef HAVE_OGR
  268. G_fatal_error(_("No output format specified, define one "
  269. "of flags -%c, -%c, -%c, or -%c"),
  270. printinfo->key, shellinfo->key, printproj4->key, printwkt->key);
  271. #else
  272. G_fatal_error(_("No output format specified, define one "
  273. "of flags -%c, -%c, or -%c"),
  274. printinfo->key, shellinfo->key, printproj4->key);
  275. #endif
  276. #ifdef HAVE_OGR
  277. if (create->answer && epsg) {
  278. #else
  279. if (create->answer){
  280. #endif
  281. /* preserve epsg code for user records only (not used by grass's pj routines) */
  282. create_epsg(location->answer, epsg);
  283. }
  284. /* Tidy Up */
  285. if (projinfo != NULL)
  286. G_free_key_value(projinfo);
  287. if (projunits != NULL)
  288. G_free_key_value(projunits);
  289. exit(EXIT_SUCCESS);
  290. }