printwindow.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. #include <string.h>
  2. #include <stdlib.h>
  3. #include <grass/gis.h>
  4. #include <grass/gprojects.h>
  5. #include <grass/glocale.h>
  6. #include "local_proto.h"
  7. #define DEG2RAD(a) ((a) * M_PI / 180.0)
  8. #define RAD2DEG(a) ((a) * 180.0 / M_PI)
  9. static double get_shift(double east)
  10. {
  11. double shift;
  12. shift = 0;
  13. while (east + shift > 180)
  14. shift -= 360;
  15. while (east + shift < -180)
  16. shift += 360;
  17. return shift;
  18. }
  19. void print_window(struct Cell_head *window, int print_flag, int flat_flag)
  20. {
  21. const char *prj, *datum, *ellps;
  22. int x, width = 11;
  23. char north[30], south[30], east[30], west[30], nsres[30], ewres[30],
  24. nsres3[30], ewres3[30], tbres[30];
  25. char buf[50];
  26. char *sep = "\n";
  27. double ew_dist1, ew_dist2, ns_dist1, ns_dist2;
  28. double longitude, latitude;
  29. if (print_flag & PRINT_SH)
  30. x = G_projection() == PROJECTION_LL ? -1 : 0;
  31. else
  32. x = window->proj;
  33. G_format_northing(window->north, north, x);
  34. G_format_northing(window->south, south, x);
  35. G_format_easting(window->east, east, x);
  36. G_format_easting(window->west, west, x);
  37. G_format_resolution(window->ew_res, ewres, x);
  38. G_format_resolution(window->ew_res3, ewres3, x);
  39. G_format_resolution(window->ns_res, nsres, x);
  40. G_format_resolution(window->ns_res3, nsres3, x);
  41. G_format_resolution(window->tb_res, tbres, -1);
  42. G_begin_distance_calculations();
  43. /* EW Dist at North edge */
  44. ew_dist1 =
  45. G_distance(window->east, window->north, window->west, window->north);
  46. /* EW Dist at South Edge */
  47. ew_dist2 =
  48. G_distance(window->east, window->south, window->west, window->south);
  49. /* NS Dist at East edge */
  50. ns_dist1 =
  51. G_distance(window->east, window->north, window->east, window->south);
  52. /* NS Dist at West edge */
  53. ns_dist2 =
  54. G_distance(window->west, window->north, window->west, window->south);
  55. /* width */
  56. if (print_flag & PRINT_REG)
  57. width = 11;
  58. if (print_flag & PRINT_CENTER || print_flag & PRINT_MBBOX)
  59. width = 16;
  60. if (print_flag & PRINT_LL || print_flag & PRINT_NANGLE)
  61. width = 18;
  62. if (print_flag & PRINT_EXTENT)
  63. width = 19;
  64. /* flag.dist_res */
  65. if (print_flag & PRINT_METERS) {
  66. sprintf(ewres, "%.8f", ((ew_dist1 + ew_dist2) / 2) / window->cols);
  67. G_trim_decimal(ewres);
  68. sprintf(ewres3, "%.8f", ((ew_dist1 + ew_dist2) / 2) / window->cols3);
  69. G_trim_decimal(ewres3);
  70. sprintf(nsres, "%.8f", ((ns_dist1 + ns_dist2) / 2) / window->rows);
  71. G_trim_decimal(nsres);
  72. sprintf(nsres3, "%.8f", ((ns_dist1 + ns_dist2) / 2) / window->rows3);
  73. G_trim_decimal(nsres3);
  74. sprintf(tbres, "%.8f",
  75. (window->top - window->bottom) / window->depths);
  76. G_trim_decimal(tbres);
  77. }
  78. /* flag.print & flag.gprint */
  79. if (print_flag & PRINT_REG) {
  80. prj = G_database_projection_name();
  81. if (!prj)
  82. prj = "** unknown **";
  83. if (print_flag & PRINT_SH) {
  84. fprintf(stdout, "projection=%d\n", window->proj);
  85. fprintf(stdout, "zone=%d\n", window->zone);
  86. }
  87. else {
  88. fprintf(stdout, "%-*s %d (%s)\n", width, "projection:",
  89. window->proj, prj);
  90. fprintf(stdout, "%-*s %d\n", width, "zone:", window->zone);
  91. }
  92. /* don't print datum/ellipsoid in XY-Locations */
  93. if (window->proj != 0) {
  94. datum = G_database_datum_name();
  95. if (!datum)
  96. datum = "** unknown (default: WGS84) **";
  97. ellps = G_database_ellipse_name();
  98. if (!ellps)
  99. ellps = "** unknown (default: WGS84) **";
  100. /*
  101. please remove before GRASS 7 released
  102. backward compatibility issue
  103. if (print_flag & PRINT_SH)
  104. {
  105. if (datum[0] != '*')
  106. fprintf(stdout, "datum=%s\n", datum);
  107. else
  108. fprintf(stdout, "datum=wgs84\n");
  109. if (ellps[0] != '*')
  110. fprintf(stdout, "ellipsoid=%s\n", ellps);
  111. else
  112. fprintf(stdout, "ellipsoid=wgs84\n");
  113. }
  114. else
  115. {
  116. fprintf(stdout, "%-*s %s\n", width, "datum:", datum);
  117. fprintf(stdout, "%-*s %s\n", width, "ellipsoid:", ellps);
  118. }
  119. */
  120. if (!(print_flag & PRINT_SH)) {
  121. fprintf(stdout, "%-*s %s\n", width, "datum:", datum);
  122. fprintf(stdout, "%-*s %s\n", width, "ellipsoid:", ellps);
  123. }
  124. }
  125. if (print_flag & PRINT_SH) {
  126. if (flat_flag)
  127. sep=" ";
  128. fprintf(stdout, "n=%s%s", north, sep);
  129. fprintf(stdout, "s=%s%s", south, sep);
  130. fprintf(stdout, "w=%s%s", west, sep);
  131. fprintf(stdout, "e=%s%s", east, sep);
  132. if (print_flag & PRINT_3D) {
  133. fprintf(stdout, "t=%g%s", window->top, sep);
  134. fprintf(stdout, "b=%g%s", window->bottom, sep);
  135. }
  136. fprintf(stdout, "nsres=%s%s", nsres, sep);
  137. if (print_flag & PRINT_3D) {
  138. fprintf(stdout, "nsres3=%s%s", nsres3, sep);
  139. }
  140. fprintf(stdout, "ewres=%s%s", ewres, sep);
  141. if (print_flag & PRINT_3D) {
  142. fprintf(stdout, "ewres3=%s%s", ewres3, sep);
  143. fprintf(stdout, "tbres=%s%s", tbres, sep);
  144. }
  145. fprintf(stdout, "rows=%d%s", window->rows, sep);
  146. if (print_flag & PRINT_3D)
  147. fprintf(stdout, "rows3=%d%s", window->rows3, sep);
  148. fprintf(stdout, "cols=%d%s", window->cols, sep);
  149. if (print_flag & PRINT_3D) {
  150. fprintf(stdout, "cols3=%d%s", window->cols3, sep);
  151. fprintf(stdout, "depths=%d%s", window->depths, sep);
  152. }
  153. #ifdef HAVE_LONG_LONG_INT
  154. fprintf(stdout, "cells=%lld%s",
  155. (long long)window->rows * window->cols, sep);
  156. if (print_flag & PRINT_3D)
  157. fprintf(stdout, "cells3=%lld%s",
  158. (long long)window->rows3 * window->cols3 *
  159. window->depths, sep);
  160. #else
  161. fprintf(stdout, "cells=%ld%s", (long)window->rows * window->cols, sep);
  162. if (print_flag & PRINT_3D)
  163. fprintf(stdout, "cells3=%ld%s",
  164. (long)window->rows3 * window->cols3 * window->depths, sep);
  165. #endif
  166. if (flat_flag)
  167. fprintf(stdout, "\n");
  168. }
  169. else {
  170. fprintf(stdout, "%-*s %s\n", width, "north:", north);
  171. fprintf(stdout, "%-*s %s\n", width, "south:", south);
  172. fprintf(stdout, "%-*s %s\n", width, "west:", west);
  173. fprintf(stdout, "%-*s %s\n", width, "east:", east);
  174. if (print_flag & PRINT_3D) {
  175. fprintf(stdout, "%-*s %.8f\n", width, "top:", window->top);
  176. fprintf(stdout, "%-*s %.8f\n", width, "bottom:",
  177. window->bottom);
  178. }
  179. fprintf(stdout, "%-*s %s\n", width, "nsres:", nsres);
  180. if (print_flag & PRINT_3D) {
  181. fprintf(stdout, "%-*s %s\n", width, "nsres3:", nsres3);
  182. }
  183. fprintf(stdout, "%-*s %s\n", width, "ewres:", ewres);
  184. if (print_flag & PRINT_3D) {
  185. fprintf(stdout, "%-*s %s\n", width, "ewres3:", ewres3);
  186. fprintf(stdout, "%-*s %s\n", width, "tbres:", tbres);
  187. }
  188. fprintf(stdout, "%-*s %d\n", width, "rows:", window->rows);
  189. if (print_flag & PRINT_3D) {
  190. fprintf(stdout, "%-*s %d\n", width, "rows3:", window->rows3);
  191. }
  192. fprintf(stdout, "%-*s %d\n", width, "cols:", window->cols);
  193. if (print_flag & PRINT_3D) {
  194. fprintf(stdout, "%-*s %d\n", width, "cols3:", window->cols3);
  195. fprintf(stdout, "%-*s %d\n", width, "depths:",
  196. window->depths);
  197. }
  198. #ifdef HAVE_LONG_LONG_INT
  199. fprintf(stdout, "%-*s %lld\n", width, "cells:",
  200. (long long)window->rows * window->cols);
  201. if (print_flag & PRINT_3D)
  202. fprintf(stdout, "%-*s %lld\n", width, "cells3:",
  203. (long long)window->rows3 * window->cols3 *
  204. window->depths);
  205. #else
  206. fprintf(stdout, "%-*s %ld\n", width, "cells:",
  207. (long)window->rows * window->cols);
  208. if (print_flag & PRINT_3D)
  209. fprintf(stdout, "%-*s %ld\n", width, "cells3:",
  210. (long)window->rows3 * window->cols3 * window->depths);
  211. #endif
  212. }
  213. }
  214. /* flag.lprint: show corners and center in lat/long MN 2001 */
  215. if (print_flag & PRINT_LL) {
  216. double lo1, la1, lo2, la2, lo3, la3, lo4, la4, loc, lac;
  217. /* if coordinates are not in lat/long format, transform them: */
  218. if ((G_projection() != PROJECTION_LL) && window->proj != 0) {
  219. /* projection information of input map */
  220. struct Key_Value *in_proj_info, *in_unit_info;
  221. struct pj_info iproj, oproj, tproj; /* proj parameters */
  222. /* read current projection info */
  223. if ((in_proj_info = G_get_projinfo()) == NULL)
  224. G_fatal_error(_("Can't get projection info of current location"));
  225. if ((in_unit_info = G_get_projunits()) == NULL)
  226. G_fatal_error(_("Can't get projection units of current location"));
  227. if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
  228. G_fatal_error(_("Can't get projection key values of current location"));
  229. G_free_key_value(in_proj_info);
  230. G_free_key_value(in_unit_info);
  231. oproj.pj = NULL;
  232. tproj.def = NULL;
  233. if (GPJ_init_transform(&iproj, &oproj, &tproj) < 0)
  234. G_fatal_error(_("Unable to initialize coordinate transformation"));
  235. /*
  236. * 1 ------ 2
  237. * | | map corners
  238. * | |
  239. * 4--------3
  240. */
  241. latitude = window->north;
  242. longitude = window->west;
  243. /* get lat/long w/ same datum/ellipsoid as input */
  244. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  245. &longitude, &latitude, NULL) < 0)
  246. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  247. "GPJ_transform()");
  248. lo1 = longitude;
  249. la1 = latitude;
  250. latitude = window->north;
  251. longitude = window->east;
  252. /* get lat/long w/ same datum/ellipsoid as input */
  253. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  254. &longitude, &latitude, NULL) < 0)
  255. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  256. "GPJ_transform()");
  257. lo2 = longitude;
  258. la2 = latitude;
  259. latitude = window->south;
  260. longitude = window->east;
  261. /* get lat/long w/ same datum/ellipsoid as input */
  262. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  263. &longitude, &latitude, NULL) < 0)
  264. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  265. "GPJ_transform()");
  266. lo3 = longitude;
  267. la3 = latitude;
  268. latitude = window->south;
  269. longitude = window->west;
  270. /* get lat/long w/ same datum/ellipsoid as input */
  271. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  272. &longitude, &latitude, NULL) < 0)
  273. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  274. "GPJ_transform()");
  275. lo4 = longitude;
  276. la4 = latitude;
  277. /* center coordinates of the current region,
  278. * not average of the projected corner coordinates */
  279. latitude = (window->north + window->south) / 2.;
  280. longitude = (window->west + window->east) / 2.;
  281. /* get lat/long w/ same datum/ellipsoid as input */
  282. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  283. &longitude, &latitude, NULL) < 0)
  284. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  285. "GPJ_transform()");
  286. loc = longitude;
  287. lac = latitude;
  288. if (print_flag & PRINT_SH) {
  289. fprintf(stdout, "nw_long=%.8f\nnw_lat=%.8f\n", lo1, la1);
  290. fprintf(stdout, "ne_long=%.8f\nne_lat=%.8f\n", lo2, la2);
  291. fprintf(stdout, "se_long=%.8f\nse_lat=%.8f\n", lo3, la3);
  292. fprintf(stdout, "sw_long=%.8f\nsw_lat=%.8f\n", lo4, la4);
  293. fprintf(stdout, "center_long=%.8f\n", loc);
  294. fprintf(stdout, "center_lat=%.8f\n", lac);
  295. }
  296. else {
  297. G_format_easting(lo1, buf, PROJECTION_LL);
  298. fprintf(stdout, "%-*s long: %s ", width, "north-west corner:",
  299. buf);
  300. G_format_northing(la1, buf, PROJECTION_LL);
  301. fprintf(stdout, "lat: %s\n", buf);
  302. G_format_easting(lo2, buf, PROJECTION_LL);
  303. fprintf(stdout, "%-*s long: %s ", width, "north-east corner:",
  304. buf);
  305. G_format_northing(la2, buf, PROJECTION_LL);
  306. fprintf(stdout, "lat: %s\n", buf);
  307. G_format_easting(lo3, buf, PROJECTION_LL);
  308. fprintf(stdout, "%-*s long: %s ", width, "south-east corner:",
  309. buf);
  310. G_format_northing(la3, buf, PROJECTION_LL);
  311. fprintf(stdout, "lat: %s\n", buf);
  312. G_format_easting(lo4, buf, PROJECTION_LL);
  313. fprintf(stdout, "%-*s long: %s ", width, "south-west corner:",
  314. buf);
  315. G_format_northing(la4, buf, PROJECTION_LL);
  316. fprintf(stdout, "lat: %s\n", buf);
  317. G_format_easting(loc, buf, PROJECTION_LL);
  318. fprintf(stdout, "%-*s %11s\n", width, "center longitude:",
  319. buf);
  320. G_format_northing(lac, buf, PROJECTION_LL);
  321. fprintf(stdout, "%-*s %11s\n", width, "center latitude:",
  322. buf);
  323. }
  324. if (!(print_flag & PRINT_REG)) {
  325. if (print_flag & PRINT_SH) {
  326. fprintf(stdout, "rows=%d\n", window->rows);
  327. fprintf(stdout, "cols=%d\n", window->cols);
  328. }
  329. else {
  330. fprintf(stdout, "%-*s %d\n", width, "rows:",
  331. window->rows);
  332. fprintf(stdout, "%-*s %d\n", width, "cols:",
  333. window->cols);
  334. }
  335. }
  336. }
  337. else { /* in lat/long already */
  338. if (window->proj != 0)
  339. G_message(_("You are already in Lat/Long. Use the -p flag instead."));
  340. else
  341. G_message(_("You are in a simple XY location, projection to Lat/Lon "
  342. "is not possible. Use the -p flag instead."));
  343. }
  344. }
  345. /* flag.eprint */
  346. if (print_flag & PRINT_EXTENT) {
  347. if (print_flag & PRINT_SH) {
  348. fprintf(stdout, "ns_extent=%f\n", window->north - window->south);
  349. fprintf(stdout, "ew_extent=%f\n", window->east - window->west);
  350. }
  351. else {
  352. if (G_projection() != PROJECTION_LL) {
  353. fprintf(stdout, "%-*s %f\n", width, "north-south extent:",
  354. window->north - window->south);
  355. fprintf(stdout, "%-*s %f\n", width, "east-west extent:",
  356. window->east - window->west);
  357. }
  358. else {
  359. G_format_northing(window->north - window->south, buf,
  360. PROJECTION_LL);
  361. fprintf(stdout, "%-*s %s\n", width, "north-south extent:",
  362. buf);
  363. G_format_easting(window->east - window->west, buf,
  364. PROJECTION_LL);
  365. fprintf(stdout, "%-*s %s\n", width, "east-west extent:", buf);
  366. }
  367. }
  368. }
  369. /* flag.center */
  370. if (print_flag & PRINT_CENTER) {
  371. if (print_flag & PRINT_SH) {
  372. fprintf(stdout, "center_easting=%f\n",
  373. (window->west + window->east) / 2.);
  374. fprintf(stdout, "center_northing=%f\n",
  375. (window->north + window->south) / 2.);
  376. }
  377. else {
  378. if (G_projection() != PROJECTION_LL) {
  379. fprintf(stdout, "%-*s %f\n", width, "center easting:",
  380. (window->west + window->east) / 2.);
  381. fprintf(stdout, "%-*s %f\n", width, "center northing:",
  382. (window->north + window->south) / 2.);
  383. }
  384. else {
  385. G_format_northing((window->north + window->south) / 2.,
  386. buf, PROJECTION_LL);
  387. fprintf(stdout, "%-*s %s\n", width, "north-south center:",
  388. buf);
  389. G_format_easting((window->west + window->east) / 2.,
  390. buf, PROJECTION_LL);
  391. fprintf(stdout, "%-*s %s\n", width, "east-west center:", buf);
  392. }
  393. }
  394. }
  395. /* flag.gmt_style */
  396. if (print_flag & PRINT_GMT)
  397. fprintf(stdout, "%s/%s/%s/%s\n", west, east, south, north);
  398. /* flag.wms_style */
  399. if (print_flag & PRINT_WMS) {
  400. G_format_northing(window->north, north, -1);
  401. G_format_northing(window->south, south, -1);
  402. G_format_easting(window->east, east, -1);
  403. G_format_easting(window->west, west, -1);
  404. fprintf(stdout, "bbox=%s,%s,%s,%s\n", west, south, east, north);
  405. }
  406. /* flag.nangle */
  407. if (print_flag & PRINT_NANGLE) {
  408. double convergence;
  409. if (G_projection() == PROJECTION_XY)
  410. convergence = 0./0.;
  411. else if (G_projection() == PROJECTION_LL)
  412. convergence = 0.0;
  413. else {
  414. struct Key_Value *in_proj_info, *in_unit_info;
  415. /* proj parameters */
  416. struct pj_info iproj, oproj, tproj;
  417. #ifdef HAVE_PROJ_H
  418. PJ_COORD c;
  419. PJ_FACTORS fact;
  420. #else
  421. struct FACTORS fact;
  422. LP lp;
  423. #endif
  424. /* read current projection info */
  425. if ((in_proj_info = G_get_projinfo()) == NULL)
  426. G_fatal_error(_("Can't get projection info of current location"));
  427. if ((in_unit_info = G_get_projunits()) == NULL)
  428. G_fatal_error(_("Can't get projection units of current location"));
  429. if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
  430. G_fatal_error(_("Can't get projection key values of current location"));
  431. G_free_key_value(in_proj_info);
  432. G_free_key_value(in_unit_info);
  433. oproj.pj = NULL;
  434. tproj.def = NULL;
  435. if (GPJ_init_transform(&iproj, &oproj, &tproj) < 0)
  436. G_fatal_error(_("Unable to initialize coordinate transformation"));
  437. /* center coordinates of the current region,
  438. * not average of the projected corner coordinates */
  439. latitude = (window->north + window->south) / 2.;
  440. longitude = (window->west + window->east) / 2.;
  441. /* get lat/long w/ same datum/ellipsoid as input */
  442. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  443. &longitude, &latitude, NULL) < 0)
  444. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  445. "GPJ_transform()");
  446. #ifdef HAVE_PROJ_H
  447. c.lpzt.lam = DEG2RAD(longitude);
  448. c.lpzt.phi = DEG2RAD(latitude);
  449. c.lpzt.z = 0;
  450. c.lpzt.t = 0;
  451. fact = proj_factors(iproj.pj, c);
  452. convergence = RAD2DEG(fact.meridian_convergence);
  453. #else
  454. G_zero(&fact, sizeof(struct FACTORS));
  455. lp.u = DEG2RAD(longitude);
  456. lp.v = DEG2RAD(latitude);
  457. pj_factors(lp, iproj.pj, 0.0, &fact);
  458. convergence = RAD2DEG(fact.conv);
  459. #endif
  460. }
  461. if (print_flag & PRINT_SH)
  462. fprintf(stdout, "converge_angle=%f\n", convergence);
  463. else
  464. fprintf(stdout, "%-*s %f\n", width, "convergence angle:",
  465. convergence);
  466. }
  467. /* flag.bbox
  468. Calculate the largest bounding box in lat-lon coordinates
  469. and print it to stdout
  470. */
  471. if (print_flag & PRINT_MBBOX) {
  472. double sh_ll_w, sh_ll_e, sh_ll_n, sh_ll_s, loc;
  473. /* Needed to calculate the LL bounding box */
  474. if ((G_projection() != PROJECTION_XY)) {
  475. /* projection information of input and output map */
  476. struct Key_Value *in_proj_info, *in_unit_info, *out_proj_info,
  477. *out_unit_info;
  478. struct pj_info iproj; /* input map proj parameters */
  479. struct pj_info oproj; /* output map proj parameters */
  480. struct pj_info tproj; /* transformation parameters */
  481. char buff[100], dum[100];
  482. int r, c;
  483. /* read current projection info */
  484. if ((in_proj_info = G_get_projinfo()) == NULL)
  485. G_fatal_error(_("Can't get projection info of current location"));
  486. /* do not wrap to -180, 180, otherwise east can be < west */
  487. /* TODO: for PROJ 6+, the +over switch must be added to the
  488. * transformation pipeline if authority:name or WKt are used
  489. * as crs definition */
  490. G_set_key_value("over", "defined", in_proj_info);
  491. if ((in_unit_info = G_get_projunits()) == NULL)
  492. G_fatal_error(_("Can't get projection units of current location"));
  493. if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
  494. G_fatal_error(_("Can't get projection key values of current location"));
  495. /* output projection to lat/long and wgs84 ellipsoid */
  496. out_proj_info = G_create_key_value();
  497. out_unit_info = G_create_key_value();
  498. G_set_key_value("proj", "ll", out_proj_info);
  499. #if PROJ_VERSION_MAJOR < 6
  500. /* PROJ6+ has its own datum transformation parameters */
  501. if (G_get_datumparams_from_projinfo(in_proj_info, buff, dum) < 0)
  502. G_fatal_error(_("WGS84 output not possible as this location does not contain "
  503. "datum transformation parameters. Try running g.setproj."));
  504. else
  505. #endif
  506. G_set_key_value("datum", "wgs84", out_proj_info);
  507. G_set_key_value("unit", "degree", out_unit_info);
  508. G_set_key_value("units", "degrees", out_unit_info);
  509. G_set_key_value("meters", "1.0", out_unit_info);
  510. if (pj_get_kv(&oproj, out_proj_info, out_unit_info) < 0)
  511. G_fatal_error(_("Unable to update lat/long projection parameters"));
  512. G_free_key_value(in_proj_info);
  513. G_free_key_value(in_unit_info);
  514. G_free_key_value(out_proj_info);
  515. G_free_key_value(out_unit_info);
  516. tproj.def = NULL;
  517. if (GPJ_init_transform(&iproj, &oproj, &tproj) < 0)
  518. G_fatal_error(_("Unable to initialize coordinate transformation"));
  519. /*Calculate the largest bounding box */
  520. /* center */
  521. latitude = (window->north + window->south) / 2.;
  522. longitude = (window->west + window->east) / 2.;
  523. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  524. &longitude, &latitude, NULL) < 0)
  525. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  526. "GPJ_transform()");
  527. sh_ll_w = sh_ll_e = longitude;
  528. sh_ll_n = sh_ll_s = latitude;
  529. /* western and eastern border */
  530. for (r = 0; r <= window->rows; r++) {
  531. latitude = window->north - r * window->ns_res;
  532. if (r == window->rows)
  533. latitude = window->south;
  534. longitude = window->west;
  535. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  536. &longitude, &latitude, NULL) < 0)
  537. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  538. "GPJ_transform()");
  539. if (sh_ll_n < latitude)
  540. sh_ll_n = latitude;
  541. if (sh_ll_s > latitude)
  542. sh_ll_s = latitude;
  543. if (sh_ll_e < longitude)
  544. sh_ll_e = longitude;
  545. if (sh_ll_w > longitude)
  546. sh_ll_w = longitude;
  547. latitude = window->north - r * window->ns_res;
  548. if (r == window->rows)
  549. latitude = window->south;
  550. longitude = window->east;
  551. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  552. &longitude, &latitude, NULL) < 0)
  553. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  554. "GPJ_transform()");
  555. if (sh_ll_n < latitude)
  556. sh_ll_n = latitude;
  557. if (sh_ll_s > latitude)
  558. sh_ll_s = latitude;
  559. if (sh_ll_e < longitude)
  560. sh_ll_e = longitude;
  561. if (sh_ll_w > longitude)
  562. sh_ll_w = longitude;
  563. }
  564. /* northern and southern border */
  565. for (c = 1; c < window->cols; c++) {
  566. latitude = window->north;
  567. longitude = window->west + c * window->ew_res;
  568. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  569. &longitude, &latitude, NULL) < 0)
  570. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  571. "GPJ_transform()");
  572. if (sh_ll_n < latitude)
  573. sh_ll_n = latitude;
  574. if (sh_ll_s > latitude)
  575. sh_ll_s = latitude;
  576. if (sh_ll_e < longitude)
  577. sh_ll_e = longitude;
  578. if (sh_ll_w > longitude)
  579. sh_ll_w = longitude;
  580. latitude = window->south;
  581. longitude = window->west + c * window->ew_res;
  582. if (GPJ_transform(&iproj, &oproj, &tproj, PJ_FWD,
  583. &longitude, &latitude, NULL) < 0)
  584. G_fatal_error(_("Error in %s (projection of input coordinate pair)"),
  585. "GPJ_transform()");
  586. if (sh_ll_n < latitude)
  587. sh_ll_n = latitude;
  588. if (sh_ll_s > latitude)
  589. sh_ll_s = latitude;
  590. if (sh_ll_e < longitude)
  591. sh_ll_e = longitude;
  592. if (sh_ll_w > longitude)
  593. sh_ll_w = longitude;
  594. }
  595. loc = (sh_ll_e + sh_ll_w) / 2.;
  596. loc += get_shift(loc);
  597. sh_ll_w += get_shift(sh_ll_w);
  598. sh_ll_e += get_shift(sh_ll_e);
  599. /* print the largest bounding box */
  600. if (print_flag & PRINT_SH) {
  601. fprintf(stdout, "ll_n=%.8f\n", sh_ll_n);
  602. fprintf(stdout, "ll_s=%.8f\n", sh_ll_s);
  603. fprintf(stdout, "ll_w=%.8f\n", sh_ll_w);
  604. fprintf(stdout, "ll_e=%.8f\n", sh_ll_e);
  605. /* center of the largest bounding box */
  606. fprintf(stdout, "ll_clon=%.8f\n", loc);
  607. fprintf(stdout, "ll_clat=%.8f\n",
  608. (sh_ll_n + sh_ll_s) / 2.);
  609. }
  610. else {
  611. G_format_northing(sh_ll_n, buf, PROJECTION_LL);
  612. fprintf(stdout, "%-*s %s\n", width, "north latitude:", buf);
  613. G_format_northing(sh_ll_s, buf, PROJECTION_LL);
  614. fprintf(stdout, "%-*s %s\n", width, "south latitude:", buf);
  615. G_format_easting(sh_ll_w, buf, PROJECTION_LL);
  616. fprintf(stdout, "%-*s %s\n", width, "west longitude:", buf);
  617. G_format_easting(sh_ll_e, buf, PROJECTION_LL);
  618. fprintf(stdout, "%-*s %s\n", width, "east longitude:", buf);
  619. /* center of the largest bounding box */
  620. G_format_easting(loc, buf, PROJECTION_LL);
  621. fprintf(stdout, "%-*s %s\n", width, "center longitude:", buf);
  622. G_format_northing((sh_ll_n + sh_ll_s) / 2., buf,
  623. PROJECTION_LL);
  624. fprintf(stdout, "%-*s %s\n", width, "center latitude:", buf);
  625. }
  626. /*It should be calculated which number of rows and cols we have in LL */
  627. /*
  628. fprintf (stdout, "LL_ROWS=%f \n",sh_ll_rows);
  629. fprintf (stdout, "LL_COLS=%f \n",sh_ll_cols);
  630. */
  631. }
  632. else {
  633. G_warning(_("Lat/Long calculations are not possible from a simple XY system"));
  634. }
  635. }
  636. }