set.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <math.h>
  4. #include <grass/gis.h>
  5. #include <grass/display.h>
  6. #include "local_proto.h"
  7. static double round_to(double in, int sd)
  8. {
  9. double mult = 1, out;
  10. while (rint(in * mult) < pow(10, sd - 1))
  11. mult *= 10.0;
  12. out = rint(in * mult);
  13. out = out / mult;
  14. return out;
  15. }
  16. int set_win(struct Cell_head *window, double ux1, double uy1, double ux2,
  17. double uy2, int hand)
  18. {
  19. struct Cell_head defwin;
  20. double north, south, east, west;
  21. double tnorth, tsouth, teast, twest, td;
  22. double ncol, nrow, ew, ns, nsr, ewr;
  23. int resetres, resetwin, limit;
  24. int screen_x, screen_y, button;
  25. resetwin = 1;
  26. G_get_default_window(&defwin);
  27. north = uy1 > uy2 ? uy1 : uy2;
  28. south = uy1 < uy2 ? uy1 : uy2;
  29. west = ux1 < ux2 ? ux1 : ux2;
  30. east = ux1 > ux2 ? ux1 : ux2;
  31. G_limit_south(&south, window->proj);
  32. G_limit_north(&north, window->proj);
  33. G_limit_east(&east, window->proj);
  34. G_limit_west(&west, window->proj);
  35. if (window->proj == PROJECTION_LL) {
  36. if ((east - west) > 360) {
  37. fprintf(stderr, "(longitude range > 360) -> resetting\n");
  38. td = (east + west) / 2;
  39. east = td + 180;
  40. west = td - 180;
  41. }
  42. }
  43. resetres = 1;
  44. while (resetres) {
  45. nsr = round_to(window->ns_res, 3);
  46. ewr = round_to(window->ew_res, 3);
  47. td = ceil(north / nsr);
  48. tnorth = td * nsr;
  49. td = floor(south / nsr);
  50. tsouth = td * nsr;
  51. td = rint(east / ewr);
  52. teast = td * ewr;
  53. td = rint(west / ewr);
  54. twest = td * ewr;
  55. ns = tnorth - tsouth;
  56. ew = teast - twest;
  57. if ((ns < 2 * window->ns_res || ew < 2 * window->ew_res) && !hand) {
  58. nsr = round_to(nsr / 10.0, 3);
  59. ewr = round_to(ewr / 10.0, 3);
  60. if (nsr < 0.00000001 || ewr < 0.00000001) {
  61. fprintf(stderr,
  62. "Minimum resolution supported by d.zoom reached.\n");
  63. resetwin = 0;
  64. break;
  65. }
  66. fprintf(stderr, "\nResolution is too low for selected region.\n");
  67. fprintf(stderr, "Buttons:\n");
  68. fprintf(stderr,
  69. "Left: Increase resolution to n-s = %g e-w = %g\n", nsr,
  70. ewr);
  71. fprintf(stderr, "Middle: Cancel (keep previous region)\n");
  72. fprintf(stderr, "Right: Cancel (keep previous region)\n");
  73. R_get_location_with_pointer(&screen_x, &screen_y, &button);
  74. if (button == 1) {
  75. window->ns_res = nsr;
  76. window->ns_res3 = nsr;
  77. window->ew_res = ewr;
  78. window->ew_res3 = ewr;
  79. }
  80. else {
  81. resetres = 0;
  82. resetwin = 0;
  83. }
  84. }
  85. else {
  86. resetres = 0;
  87. }
  88. }
  89. nrow = (tnorth - tsouth) / window->ns_res;
  90. ncol = (teast - twest) / window->ew_res;
  91. if ((nrow > 10000000 || ncol > 10000000) && !hand) {
  92. nsr = round_to(window->ns_res * 10, 3);
  93. ewr = round_to(window->ew_res * 10, 3);
  94. fprintf(stderr, "\nResolution is too high for selected region.\n");
  95. fprintf(stderr, "Buttons:\n");
  96. fprintf(stderr,
  97. "Left: Decrease resolution to n-s = %.20f e-w = %.20f\n",
  98. nsr, ewr);
  99. fprintf(stderr, "Middle: Keep current resolution\n");
  100. fprintf(stderr, "Right: Keep current resolution\n");
  101. R_get_location_with_pointer(&screen_x, &screen_y, &button);
  102. if (button == 1) {
  103. window->ns_res = nsr;
  104. window->ns_res3 = nsr;
  105. window->ew_res = ewr;
  106. window->ew_res3 = ewr;
  107. td = rint(tnorth / nsr);
  108. tnorth = td * nsr;
  109. td = rint(tsouth / nsr);
  110. tsouth = td * nsr;
  111. td = rint(teast / ewr);
  112. teast = td * ewr;
  113. td = rint(twest / ewr);
  114. twest = td * ewr;
  115. }
  116. }
  117. if (window->proj == PROJECTION_LL) {
  118. if (tnorth > 90)
  119. tnorth = 90;
  120. if (tsouth < -90)
  121. tsouth = -90;
  122. if (teast > 360)
  123. teast -= 360; /* allow 0->360 as easting (e.g. Mars) */
  124. if (twest > 360)
  125. twest -= 360;
  126. if (teast < -180)
  127. teast += 360;
  128. if (twest < -180)
  129. twest += 360;
  130. }
  131. if (tnorth == tsouth)
  132. tnorth += window->ns_res;
  133. if (window->proj != PROJECTION_LL) {
  134. if (teast == twest)
  135. teast += window->ew_res;
  136. }
  137. else {
  138. if ((fabs(teast - twest) <= window->ew_res) ||
  139. (fabs(teast - 360 - twest) <= window->ew_res)) {
  140. teast -= window->ew_res;
  141. }
  142. }
  143. if (resetwin) {
  144. /* favour resolution over bounds; round inwards to protect lat/lon */
  145. window->north = floor(tnorth / window->ns_res) * window->ns_res;
  146. window->south = ceil(tsouth / window->ns_res) * window->ns_res;
  147. window->east = floor(teast / window->ew_res) * window->ew_res;
  148. window->west = ceil(twest / window->ew_res) * window->ew_res;
  149. if (!hand) {
  150. fprintf(stderr, "\n");
  151. print_win(window, north, south, east, west);
  152. fprintf(stderr, "\n");
  153. }
  154. limit = print_limit(window, &defwin);
  155. G_adjust_Cell_head3(window, 0, 0, 0);
  156. G_put_window(window);
  157. Rast_set_window(window);
  158. redraw();
  159. }
  160. return 1;
  161. }