main.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. /*
  2. ****************************************************************************
  3. *
  4. * MODULE: g.setproj
  5. * AUTHOR(S): M. L. Holko - Soil Conservation Service, USDA
  6. * Morten Hulden - morten@untamo.net
  7. * Andreas Lange - andreas.lange@rhein-main.de
  8. * PURPOSE: Provides a means of creating a new projection information
  9. * file (productivity tool).
  10. * COPYRIGHT: (C) 2000 by the GRASS Development Team
  11. *
  12. * This program is free software under the GNU General Public
  13. * License (>=v2). Read the file COPYING that comes with GRASS
  14. * for details.
  15. *
  16. *****************************************************************************/
  17. /* old log retained for information */
  18. /* main.c
  19. * 1.1 05/16/91 GRASS4.0
  20. * Created by : M.L.Holko , Soil Conservation Service, USDA
  21. * Purpose: Productivity tool
  22. * Provides a means of creating a new projection
  23. * information file
  24. *
  25. * ------Rev 4.+ arguments --------------------------------------
  26. * Input arguments:
  27. * m.setproj set=mapset for output project info file
  28. * proj=projection of the output project info file
  29. *
  30. * 1.2 Changed by Morten Hulden 10/10/99 to add support for more projections
  31. * morten@untamo.net
  32. *
  33. * 1.3 Changed by Andreas Lange 07/25/00 to add datum support
  34. * Andreas.Lange@Rhein-Main.de
  35. */
  36. #include <stdio.h>
  37. #include <string.h>
  38. #include <unistd.h>
  39. #include <stdlib.h>
  40. #include <grass/gis.h>
  41. #include <grass/glocale.h>
  42. #include "local_proto.h"
  43. /* some global variables */
  44. int ier, zone;
  45. double radius;
  46. int main(int argc, char *argv[])
  47. {
  48. struct GModule *module;
  49. int Out_proj;
  50. int out_stat;
  51. int old_zone, old_proj;
  52. int i;
  53. int stat;
  54. char cmnd2[500];
  55. char proj_out[20], proj_name[50], set_name[20];
  56. char path[1024], buffa[1024], buffb[1024], answer[200], answer1[200];
  57. char answer2[200], buff[1024];
  58. char tmp_buff[20], *buf;
  59. struct Key_Value *old_proj_keys, *out_proj_keys, *in_unit_keys;
  60. double aa, e2;
  61. double f;
  62. FILE *FPROJ;
  63. int exist = 0;
  64. char spheroid[100];
  65. int j, k, sph_check;
  66. struct Cell_head cellhd;
  67. char datum[100], dat_ellps[100], dat_params[100];
  68. struct proj_parm *proj_parms;
  69. G_gisinit(argv[0]);
  70. module = G_define_module();
  71. G_add_keyword(_("general"));
  72. G_add_keyword(_("projection"));
  73. module->description =
  74. _("Interactively reset the location's projection settings.");
  75. if (G_parser(argc, argv))
  76. exit(EXIT_FAILURE);
  77. if (strcmp(G_mapset(), "PERMANENT") != 0)
  78. G_fatal_error(_("You must be in the PERMANENT mapset to run g.setproj"));
  79. /***
  80. * no longer necessary, table is a static struct
  81. * init_unit_table();
  82. ***/
  83. sprintf(set_name, "PERMANENT");
  84. G_file_name(path, "", PROJECTION_FILE, set_name);
  85. /* get the output projection parameters, if existing */
  86. /* Check for ownership here */
  87. stat = G_mapset_permissions(set_name);
  88. if (stat == 0) {
  89. G_fatal_error(_("PERMANENT: permission denied"));
  90. }
  91. G_get_default_window(&cellhd);
  92. if (-1 == G_set_window(&cellhd))
  93. G_fatal_error(_("Current region cannot be set"));
  94. if (G_get_set_window(&cellhd) == -1)
  95. G_fatal_error(_("Retrieving and setting region failed"));
  96. Out_proj = cellhd.proj;
  97. old_zone = cellhd.zone;
  98. old_proj = cellhd.proj;
  99. if (access(path, 0) == 0) {
  100. exist = 1;
  101. FPROJ = fopen(path, "r");
  102. old_proj_keys = G_fread_key_value(FPROJ);
  103. fclose(FPROJ);
  104. buf = G_find_key_value("name", old_proj_keys);
  105. fprintf(stderr,
  106. "\nWARNING: A projection file already exists for this location\n(Filename '%s')\n",
  107. path);
  108. fprintf(stderr,
  109. "\nThis file contains all the parameters for the location's projection:\n %s\n",
  110. buf);
  111. fprintf(stderr,
  112. "\n Overriding this information implies that the old projection parameters\n"
  113. " were incorrect. If you change the parameters, all existing data will\n"
  114. " be interpreted differently by the projection software.\n%c%c%c",
  115. 7, 7, 7);
  116. fprintf(stderr,
  117. " GRASS will not re-project your data automatically.\n\n");
  118. if (!G_yes
  119. (_("Would you still like to change some of the parameters?"),
  120. 0)) {
  121. G_message(_("The projection information will not be updated"));
  122. leave(SP_NOCHANGE);
  123. }
  124. }
  125. out_proj_keys = G_create_key_value();
  126. if (exist) {
  127. buf = G_find_key_value("zone", old_proj_keys);
  128. if (buf != NULL)
  129. sscanf(buf, "%d", &zone);
  130. if (zone != old_zone) {
  131. G_warning(_("Zone in default geographic region definition: %d\n"
  132. " is different from zone in PROJ_INFO file: %d"),
  133. old_zone, zone);
  134. old_zone = zone;
  135. }
  136. }
  137. switch (Out_proj) {
  138. case 0: /* No projection/units */
  139. if (!exist) {
  140. /* leap frog over code, and just make sure we remove the file */
  141. G_warning(_("XY-location cannot be projected"));
  142. goto write_file;
  143. break;
  144. }
  145. case PROJECTION_UTM:
  146. if (!exist) {
  147. sprintf(proj_name, "%s", G_projection_name(PROJECTION_UTM));
  148. sprintf(proj_out, "utm");
  149. break;
  150. }
  151. case PROJECTION_SP:
  152. if (!exist) {
  153. sprintf(proj_name, "%s", G_projection_name(PROJECTION_SP));
  154. sprintf(proj_out, "stp");
  155. break;
  156. }
  157. case PROJECTION_LL:
  158. if (!exist) {
  159. sprintf(proj_name, "%s", G_projection_name(PROJECTION_LL));
  160. sprintf(proj_out, "ll");
  161. break;
  162. }
  163. case PROJECTION_OTHER:
  164. if (G_ask_proj_name(proj_out, proj_name) < 0)
  165. leave(SP_NOCHANGE);
  166. if (G_strcasecmp(proj_out, "LL") == 0)
  167. Out_proj = PROJECTION_LL;
  168. else if (G_strcasecmp(proj_out, "UTM") == 0)
  169. Out_proj = PROJECTION_UTM;
  170. else if (G_strcasecmp(proj_out, "STP") == 0)
  171. Out_proj = PROJECTION_SP;
  172. break;
  173. default:
  174. G_fatal_error(_("Unknown projection"));
  175. }
  176. cellhd.proj = Out_proj;
  177. proj_parms = get_proj_parms(proj_out);
  178. if (!proj_parms)
  179. G_fatal_error(_("Projection %s is not specified in the file 'proj-parms.table'"),
  180. proj_out);
  181. G_set_key_value("name", proj_name, out_proj_keys);
  182. sph_check = 0;
  183. if (G_yes
  184. (_("Do you wish to specify a geodetic datum for this location?"),
  185. 1)) {
  186. char lbuf[100], lbufa[100];
  187. if (exist &&
  188. (G_get_datumparams_from_projinfo(old_proj_keys, lbuf, lbufa) ==
  189. 2)) {
  190. G_strip(lbuf);
  191. if ((i = G_get_datum_by_name(lbuf)) > 0) {
  192. G_message(_("The current datum is %s (%s)"),
  193. G_datum_name(i), G_datum_description(i));
  194. if (G_yes
  195. (_("Do you wish to change the datum (or datum transformation parameters)?"),
  196. 0))
  197. sph_check = ask_datum(datum, dat_ellps, dat_params);
  198. else {
  199. sprintf(datum, lbuf);
  200. sprintf(dat_params, lbufa);
  201. sprintf(dat_ellps, G_datum_ellipsoid(i));
  202. sph_check = 1;
  203. G_message(_("The datum information has not been changed"));
  204. }
  205. }
  206. else
  207. sph_check = ask_datum(datum, dat_ellps, dat_params);
  208. }
  209. else
  210. sph_check = ask_datum(datum, dat_ellps, dat_params);
  211. }
  212. if (sph_check > 0) {
  213. char *paramkey, *paramvalue;
  214. /* write out key/value pairs to out_proj_keys */
  215. if (G_strcasecmp(datum, "custom") != 0)
  216. G_set_key_value("datum", datum, out_proj_keys);
  217. /* G_set_key_value("datumparams", dat_params, out_proj_keys); */
  218. paramkey = strtok(dat_params, "=");
  219. paramvalue = dat_params + strlen(paramkey) + 1;
  220. G_set_key_value(paramkey, paramvalue, out_proj_keys);
  221. sprintf(spheroid, "%s", dat_ellps);
  222. }
  223. else {
  224. /***************** GET spheroid **************************/
  225. if (Out_proj != PROJECTION_SP) { /* some projections have
  226. * fixed spheroids */
  227. if (G_strcasecmp(proj_out, "ALSK") == 0 ||
  228. G_strcasecmp(proj_out, "GS48") == 0 ||
  229. G_strcasecmp(proj_out, "GS50") == 0) {
  230. sprintf(spheroid, "%s", "clark66");
  231. G_set_key_value("ellps", spheroid, out_proj_keys);
  232. sph_check = 1;
  233. }
  234. else if (G_strcasecmp(proj_out, "LABRD") == 0 ||
  235. G_strcasecmp(proj_out, "NZMG") == 0) {
  236. sprintf(spheroid, "%s", "international");
  237. G_set_key_value("ellps", spheroid, out_proj_keys);
  238. sph_check = 1;
  239. }
  240. else if (G_strcasecmp(proj_out, "SOMERC") == 0) {
  241. sprintf(spheroid, "%s", "bessel");
  242. G_set_key_value("ellps", spheroid, out_proj_keys);
  243. sph_check = 1;
  244. }
  245. else if (G_strcasecmp(proj_out, "OB_TRAN") == 0) {
  246. /* Hard coded to use "Equidistant Cylincrical"
  247. * until g.setproj has been changed to run
  248. * recurively, to allow input of options for
  249. * a second projection, MHu991010 */
  250. G_set_key_value("o_proj", "eqc", out_proj_keys);
  251. sph_check = 2;
  252. }
  253. else {
  254. if (exist &&
  255. (buf =
  256. G_find_key_value("ellps", old_proj_keys)) != NULL) {
  257. strcpy(spheroid, buf);
  258. G_strip(spheroid);
  259. if (G_get_spheroid_by_name(spheroid, &aa, &e2, &f)) {
  260. /* if legal ellips. exist, ask wether or not to change it */
  261. G_message(_("The current ellipsoid is %s"), spheroid);
  262. if (G_yes
  263. (_("Do you want to change ellipsoid parameter?"),
  264. 0))
  265. sph_check = G_ask_ellipse_name(spheroid);
  266. else {
  267. G_message(_("The ellipse information has not been changed"));
  268. sph_check = 1;
  269. }
  270. } /* the val is legal */
  271. else
  272. sph_check = G_ask_ellipse_name(spheroid);
  273. }
  274. else
  275. sph_check = G_ask_ellipse_name(spheroid);
  276. }
  277. }
  278. if (sph_check > 0) {
  279. if (sph_check == 2) { /* ask radius */
  280. if (exist) {
  281. buf = G_find_key_value("a", old_proj_keys);
  282. if ((buf != NULL) && (sscanf(buf, "%lf", &radius) == 1)) {
  283. G_message(_("The radius is currently %f"), radius);
  284. if (G_yes(_("Do you want to change the radius?"), 0))
  285. radius =
  286. prompt_num_double(_("Enter radius for the sphere in meters"),
  287. RADIUS_DEF, 1);
  288. }
  289. }
  290. else
  291. radius =
  292. prompt_num_double(_("Enter radius for the sphere in meters"),
  293. RADIUS_DEF, 1);
  294. } /* end ask radius */
  295. }
  296. }
  297. /*** END get spheroid ***/
  298. /* create the PROJ_INFO & PROJ_UNITS files, if required */
  299. if (G_strcasecmp(proj_out, "LL") == 0) ;
  300. else if (G_strcasecmp(proj_out, "STP") == 0)
  301. get_stp_proj(buffb);
  302. else if (sph_check != 2) {
  303. G_strip(spheroid);
  304. if (G_get_spheroid_by_name(spheroid, &aa, &e2, &f) == 0)
  305. G_fatal_error(_("Invalid input ellipsoid"));
  306. }
  307. write_file:
  308. /*
  309. ** NOTE the program will (hopefully) never exit abnormally
  310. ** after this point. Thus we know the file will be completely
  311. ** written out once it is opened for write
  312. */
  313. if (exist) {
  314. sprintf(buff, "%s~", path);
  315. G_rename_file(path, buff);
  316. }
  317. if (Out_proj == 0)
  318. goto write_units;
  319. /*
  320. ** Include MISC parameters for PROJ_INFO
  321. */
  322. if (G_strcasecmp(proj_out, "STP") == 0) {
  323. for (i = 0; i < strlen(buffb); i++)
  324. if (buffb[i] == ' ')
  325. buffb[i] = '\t';
  326. sprintf(cmnd2, "%s\t\n", buffb);
  327. for (i = 0; i < strlen(cmnd2); i++) {
  328. j = k = 0;
  329. if (cmnd2[i] == '+') {
  330. while (cmnd2[++i] != '=')
  331. buffa[j++] = cmnd2[i];
  332. buffa[j] = 0;
  333. while (cmnd2[++i] != '\t' && cmnd2[i] != '\n' &&
  334. cmnd2[i] != 0)
  335. buffb[k++] = cmnd2[i];
  336. buffb[k] = 0;
  337. G_set_key_value(buffa, buffb, out_proj_keys);
  338. }
  339. }
  340. }
  341. else if (G_strcasecmp(proj_out, "LL") == 0) {
  342. G_set_key_value("proj", "ll", out_proj_keys);
  343. G_set_key_value("ellps", spheroid, out_proj_keys);
  344. }
  345. else {
  346. if (sph_check != 2) {
  347. G_set_key_value("proj", proj_out, out_proj_keys);
  348. G_set_key_value("ellps", spheroid, out_proj_keys);
  349. sprintf(tmp_buff, "%.10f", aa);
  350. G_set_key_value("a", tmp_buff, out_proj_keys);
  351. sprintf(tmp_buff, "%.10f", e2);
  352. G_set_key_value("es", tmp_buff, out_proj_keys);
  353. sprintf(tmp_buff, "%.10f", f);
  354. G_set_key_value("f", tmp_buff, out_proj_keys);
  355. }
  356. else {
  357. G_set_key_value("proj", proj_out, out_proj_keys);
  358. /* G_set_key_value ("ellps", "sphere", out_proj_keys); */
  359. sprintf(tmp_buff, "%.10f", radius);
  360. G_set_key_value("a", tmp_buff, out_proj_keys);
  361. G_set_key_value("es", "0.0", out_proj_keys);
  362. G_set_key_value("f", "0.0", out_proj_keys);
  363. }
  364. for (i = 0;; i++) {
  365. struct proj_parm *parm = &proj_parms[i];
  366. struct proj_desc *desc;
  367. if (!parm->name)
  368. break;
  369. desc = get_proj_desc(parm->name);
  370. if (!desc)
  371. break;
  372. if (parm->ask) {
  373. if (G_strcasecmp(desc->type, "bool") == 0) {
  374. if (G_yes((char *)desc->desc, 0)) {
  375. G_set_key_value(desc->key, "defined", out_proj_keys);
  376. if (G_strcasecmp(parm->name, "SOUTH") == 0)
  377. cellhd.zone = -abs(cellhd.zone);
  378. }
  379. }
  380. else if (G_strcasecmp(desc->type, "lat") == 0) {
  381. double val;
  382. while (!get_LL_stuff(parm, desc, 1, &val)) ;
  383. sprintf(tmp_buff, "%.10f", val);
  384. G_set_key_value(desc->key, tmp_buff, out_proj_keys);
  385. }
  386. else if (G_strcasecmp(desc->type, "lon") == 0) {
  387. double val;
  388. while (!get_LL_stuff(parm, desc, 0, &val)) ;
  389. sprintf(tmp_buff, "%.10f", val);
  390. G_set_key_value(desc->key, tmp_buff, out_proj_keys);
  391. }
  392. else if (G_strcasecmp(desc->type, "float") == 0) {
  393. double val;
  394. while (!get_double(parm, desc, &val)) ;
  395. sprintf(tmp_buff, "%.10f", val);
  396. G_set_key_value(desc->key, tmp_buff, out_proj_keys);
  397. }
  398. else if (G_strcasecmp(desc->type, "int") == 0) {
  399. int val;
  400. while (!get_int(parm, desc, &val)) ;
  401. sprintf(tmp_buff, "%d", val);
  402. G_set_key_value(desc->key, tmp_buff, out_proj_keys);
  403. }
  404. else if (G_strcasecmp(desc->type, "zone") == 0) {
  405. if ((Out_proj == PROJECTION_UTM) && (old_zone != 0)) {
  406. G_message(_("The UTM zone is now set to %d"),
  407. old_zone);
  408. if (!G_yes
  409. (_("Do you want to change the UTM zone?"), 0)) {
  410. G_message(_("UTM zone information has not been updated"));
  411. zone = old_zone;
  412. break;
  413. }
  414. else {
  415. G_message(_("But if you change zone, all the existing "
  416. "data will be interpreted by projection software. "
  417. "GRASS will not automatically re-project or even "
  418. "change the headers for existing maps."));
  419. if (!G_yes
  420. (_("Would you still like to change the UTM zone?"),
  421. 0)) {
  422. zone = old_zone;
  423. break;
  424. }
  425. }
  426. } /* UTM */
  427. while (!get_zone()) ;
  428. sprintf(tmp_buff, "%d", zone);
  429. G_set_key_value("zone", tmp_buff, out_proj_keys);
  430. cellhd.zone = zone;
  431. }
  432. }
  433. else if (parm->def_exists) {
  434. /* don't ask, use the default */
  435. if (G_strcasecmp(desc->type, "float") == 0 ||
  436. G_strcasecmp(desc->type, "lat") == 0 ||
  437. G_strcasecmp(desc->type, "lon") == 0) {
  438. sprintf(tmp_buff, "%.10f", parm->deflt);
  439. G_set_key_value(desc->key, tmp_buff, out_proj_keys);
  440. }
  441. else if (G_strcasecmp(desc->type, "int") == 0) {
  442. sprintf(tmp_buff, "%d", (int)parm->deflt);
  443. G_set_key_value(desc->key, tmp_buff, out_proj_keys);
  444. }
  445. }
  446. } /* for OPTIONS */
  447. }
  448. /* create the PROJ_INFO & PROJ_UNITS files, if required */
  449. G_write_key_value_file(path, out_proj_keys, &out_stat);
  450. if (out_stat != 0) {
  451. G_fatal_error(_("Error writing PROJ_INFO file <%s>"), path);
  452. }
  453. G_free_key_value(out_proj_keys);
  454. if (exist)
  455. G_free_key_value(old_proj_keys);
  456. write_units:
  457. G_file_name(path, "", UNIT_FILE, set_name);
  458. /* if we got this far, the user
  459. ** already affirmed to write over old info
  460. ** so if units file is here, remove it.
  461. */
  462. if (access(path, 0) == 0) {
  463. sprintf(buff, "%s~", path);
  464. G_rename_file(path, buff);
  465. }
  466. if (Out_proj == 0)
  467. leave(0);
  468. {
  469. in_unit_keys = G_create_key_value();
  470. switch (Out_proj) {
  471. case PROJECTION_UTM:
  472. G_set_key_value("unit", "meter", in_unit_keys);
  473. G_set_key_value("units", "meters", in_unit_keys);
  474. G_set_key_value("meters", "1.0", in_unit_keys);
  475. break;
  476. case PROJECTION_SP:
  477. for (;;) {
  478. do {
  479. fprintf(stderr, "\nSpecify the correct units to use:\n");
  480. fprintf(stderr, "Enter the corresponding number\n");
  481. fprintf(stderr,
  482. "1.\tUS Survey Foot (Default for State Plane 1927)\n");
  483. fprintf(stderr, "2.\tInternational Foot\n");
  484. fprintf(stderr, "3.\tMeter\n");
  485. fprintf(stderr, ">");
  486. } while (!G_gets(answer));
  487. G_strip(answer);
  488. if (strcmp(answer, "1") == 0) {
  489. G_set_key_value("unit", "USfoot", in_unit_keys);
  490. G_set_key_value("units", "USfeet", in_unit_keys);
  491. G_set_key_value("meters", "0.30480060960121920243",
  492. in_unit_keys);
  493. break;
  494. }
  495. else if (strcmp(answer, "2") == 0) {
  496. G_set_key_value("unit", "foot", in_unit_keys);
  497. G_set_key_value("units", "feet", in_unit_keys);
  498. G_set_key_value("meters", "0.3048", in_unit_keys);
  499. break;
  500. }
  501. else if (strcmp(answer, "3") == 0) {
  502. G_set_key_value("unit", "meter", in_unit_keys);
  503. G_set_key_value("units", "meters", in_unit_keys);
  504. G_set_key_value("meters", "1.0", in_unit_keys);
  505. break;
  506. }
  507. else
  508. fprintf(stderr, "\nInvalid Entry (number 1 - 3)\n");
  509. }
  510. break;
  511. case PROJECTION_LL:
  512. G_set_key_value("unit", "degree", in_unit_keys);
  513. G_set_key_value("units", "degrees", in_unit_keys);
  514. G_set_key_value("meters", "1.0", in_unit_keys);
  515. break;
  516. default:
  517. if (G_strcasecmp(proj_out, "LL") != 0) {
  518. fprintf(stderr, _("Enter plural form of units [meters]: "));
  519. G_gets(answer);
  520. if (strlen(answer) == 0) {
  521. G_set_key_value("unit", "meter", in_unit_keys);
  522. G_set_key_value("units", "meters", in_unit_keys);
  523. G_set_key_value("meters", "1.0", in_unit_keys);
  524. }
  525. else {
  526. const struct proj_unit *unit;
  527. G_strip(answer);
  528. unit = get_proj_unit(answer);
  529. if (unit) {
  530. #ifdef FOO
  531. if (G_strcasecmp(proj_out, "STP") == 0 &&
  532. !strcmp(answer, "feet")) {
  533. fprintf(stderr,
  534. "%cPROJECTION 99 State Plane cannot be in FEET.\n",
  535. 7);
  536. remove(path); /* remove file */
  537. leave(SP_FATAL);
  538. }
  539. #endif
  540. G_set_key_value("unit", unit->unit, in_unit_keys);
  541. G_set_key_value("units", unit->units, in_unit_keys);
  542. sprintf(buffb, "%.10f", unit->fact);
  543. G_set_key_value("meters", buffb, in_unit_keys);
  544. }
  545. else {
  546. double unit_fact;
  547. while (1) {
  548. fprintf(stderr, _("Enter singular for unit: "));
  549. G_gets(answer1);
  550. G_strip(answer1);
  551. if (strlen(answer1) > 0)
  552. break;
  553. }
  554. while (1) {
  555. fprintf(stderr,
  556. _("Enter conversion factor from %s to meters: "),
  557. answer);
  558. G_gets(answer2);
  559. G_strip(answer2);
  560. if (!
  561. (strlen(answer2) == 0 ||
  562. (1 != sscanf(answer2, "%lf", &unit_fact))))
  563. break;
  564. }
  565. G_set_key_value("unit", answer1, in_unit_keys);
  566. G_set_key_value("units", answer, in_unit_keys);
  567. sprintf(buffb, "%.10f", unit_fact);
  568. G_set_key_value("meters", buffb, in_unit_keys);
  569. }
  570. }
  571. }
  572. else {
  573. G_set_key_value("unit", "degree", in_unit_keys);
  574. G_set_key_value("units", "degrees", in_unit_keys);
  575. G_set_key_value("meters", "1.0", in_unit_keys);
  576. }
  577. } /* switch */
  578. G_write_key_value_file(path, in_unit_keys, &out_stat);
  579. if (out_stat != 0)
  580. G_fatal_error(_("Error writing into UNITS output file <%s>"),
  581. path);
  582. G_free_key_value(in_unit_keys);
  583. } /* if */
  584. if (G_put_element_window(&cellhd, "", "DEFAULT_WIND") < 0)
  585. G_fatal_error(_("Unable to write to DEFAULT_WIND region file"));
  586. fprintf(stderr,
  587. _("\nProjection information has been recorded for this location\n\n"));
  588. if ((old_zone != zone) | (old_proj != cellhd.proj)) {
  589. G_message(_("The geographic region information in WIND is now obsolete"));
  590. G_message(_("Run g.region -d to update it"));
  591. }
  592. leave(0);
  593. }
  594. int min1(int a, int b)
  595. {
  596. if (a > b)
  597. return b;
  598. else
  599. return a;
  600. }
  601. int leave(int n)
  602. {
  603. exit(n);
  604. }