123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <grass/gis.h>
- #include <grass/display.h>
- #include "local_proto.h"
- static double round_to(double in, int sd)
- {
- double mult = 1, out;
- while (rint(in * mult) < pow(10, sd - 1))
- mult *= 10.0;
- out = rint(in * mult);
- out = out / mult;
- return out;
- }
- int set_win(struct Cell_head *window, double ux1, double uy1, double ux2,
- double uy2, int hand)
- {
- struct Cell_head defwin;
- double north, south, east, west;
- double tnorth, tsouth, teast, twest, td;
- double ncol, nrow, ew, ns, nsr, ewr;
- int resetres, resetwin, limit;
- int screen_x, screen_y, button;
- resetwin = 1;
- G_get_default_window(&defwin);
- north = uy1 > uy2 ? uy1 : uy2;
- south = uy1 < uy2 ? uy1 : uy2;
- west = ux1 < ux2 ? ux1 : ux2;
- east = ux1 > ux2 ? ux1 : ux2;
- G_limit_south(&south, window->proj);
- G_limit_north(&north, window->proj);
- G_limit_east(&east, window->proj);
- G_limit_west(&west, window->proj);
- if (window->proj == PROJECTION_LL) {
- if ((east - west) > 360) {
- fprintf(stderr, "(longitude range > 360) -> resetting\n");
- td = (east + west) / 2;
- east = td + 180;
- west = td - 180;
- }
- }
- resetres = 1;
- while (resetres) {
- nsr = round_to(window->ns_res, 3);
- ewr = round_to(window->ew_res, 3);
- td = ceil(north / nsr);
- tnorth = td * nsr;
- td = floor(south / nsr);
- tsouth = td * nsr;
- td = rint(east / ewr);
- teast = td * ewr;
- td = rint(west / ewr);
- twest = td * ewr;
- ns = tnorth - tsouth;
- ew = teast - twest;
- if ((ns < 2 * window->ns_res || ew < 2 * window->ew_res) && !hand) {
- nsr = round_to(nsr / 10.0, 3);
- ewr = round_to(ewr / 10.0, 3);
- if (nsr < 0.00000001 || ewr < 0.00000001) {
- fprintf(stderr,
- "Minimum resolution supported by d.zoom reached.\n");
- resetwin = 0;
- break;
- }
- fprintf(stderr, "\nResolution is too low for selected region.\n");
- fprintf(stderr, "Buttons:\n");
- fprintf(stderr,
- "Left: Increase resolution to n-s = %g e-w = %g\n", nsr,
- ewr);
- fprintf(stderr, "Middle: Cancel (keep previous region)\n");
- fprintf(stderr, "Right: Cancel (keep previous region)\n");
- R_get_location_with_pointer(&screen_x, &screen_y, &button);
- if (button == 1) {
- window->ns_res = nsr;
- window->ns_res3 = nsr;
- window->ew_res = ewr;
- window->ew_res3 = ewr;
- }
- else {
- resetres = 0;
- resetwin = 0;
- }
- }
- else {
- resetres = 0;
- }
- }
- nrow = (tnorth - tsouth) / window->ns_res;
- ncol = (teast - twest) / window->ew_res;
- if ((nrow > 10000000 || ncol > 10000000) && !hand) {
- nsr = round_to(window->ns_res * 10, 3);
- ewr = round_to(window->ew_res * 10, 3);
- fprintf(stderr, "\nResolution is too high for selected region.\n");
- fprintf(stderr, "Buttons:\n");
- fprintf(stderr,
- "Left: Decrease resolution to n-s = %.20f e-w = %.20f\n",
- nsr, ewr);
- fprintf(stderr, "Middle: Keep current resolution\n");
- fprintf(stderr, "Right: Keep current resolution\n");
- R_get_location_with_pointer(&screen_x, &screen_y, &button);
- if (button == 1) {
- window->ns_res = nsr;
- window->ns_res3 = nsr;
- window->ew_res = ewr;
- window->ew_res3 = ewr;
- td = rint(tnorth / nsr);
- tnorth = td * nsr;
- td = rint(tsouth / nsr);
- tsouth = td * nsr;
- td = rint(teast / ewr);
- teast = td * ewr;
- td = rint(twest / ewr);
- twest = td * ewr;
- }
- }
- if (window->proj == PROJECTION_LL) {
- if (tnorth > 90)
- tnorth = 90;
- if (tsouth < -90)
- tsouth = -90;
- if (teast > 360)
- teast -= 360; /* allow 0->360 as easting (e.g. Mars) */
- if (twest > 360)
- twest -= 360;
- if (teast < -180)
- teast += 360;
- if (twest < -180)
- twest += 360;
- }
- if (tnorth == tsouth)
- tnorth += window->ns_res;
- if (window->proj != PROJECTION_LL) {
- if (teast == twest)
- teast += window->ew_res;
- }
- else {
- if ((fabs(teast - twest) <= window->ew_res) ||
- (fabs(teast - 360 - twest) <= window->ew_res)) {
- teast -= window->ew_res;
- }
- }
- if (resetwin) {
- /* favour resolution over bounds; round inwards to protect lat/lon */
- window->north = floor(tnorth / window->ns_res) * window->ns_res;
- window->south = ceil(tsouth / window->ns_res) * window->ns_res;
- window->east = floor(teast / window->ew_res) * window->ew_res;
- window->west = ceil(twest / window->ew_res) * window->ew_res;
- if (!hand) {
- fprintf(stderr, "\n");
- print_win(window, north, south, east, west);
- fprintf(stderr, "\n");
- }
- limit = print_limit(window, &defwin);
- G_adjust_Cell_head3(window, 0, 0, 0);
- G_put_window(window);
- Rast_set_window(window);
- redraw();
- }
- return 1;
- }
|