mirror of
https://github.com/subsurface/subsurface.git
synced 2025-01-31 21:03:23 +00:00
Modify map zoom to keep the point under the mouse cursor constant
The idea is that while zooming the map the point under the mouse would stay as close to constant as possible (given that we use integer coordinates). This version uses some algebra to figure out the correct new parameters for the mercator projection used in osm-gps-map. Occasionally (and we haven't figured out what triggers it) zooming out suddenly resets your position to 0,0. [Dirk Hohndel: switched this to using the correct interface to get the object properties and did some serious whitespace cleanup] Signed-off-by: Robert C. Helling <helling@atdotde.de> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
546fecd850
commit
ae64abfbca
1 changed files with 45 additions and 2 deletions
47
gps.c
47
gps.c
|
@ -30,10 +30,53 @@ static void on_close(GtkWidget *widget, gpointer user_data)
|
||||||
static gboolean scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data)
|
static gboolean scroll_cb(GtkWidget *widget, GdkEventScroll *event, gpointer data)
|
||||||
{
|
{
|
||||||
OsmGpsMap *map = (OsmGpsMap *)widget;
|
OsmGpsMap *map = (OsmGpsMap *)widget;
|
||||||
if (event->direction == GDK_SCROLL_UP)
|
OsmGpsMapPoint *pt, *lt, *rb, *target;
|
||||||
|
float target_lat, target_lon;
|
||||||
|
gint ltx, lty, rbx, rby, target_x, target_y;
|
||||||
|
gint zoom, max_zoom, min_zoom;
|
||||||
|
|
||||||
|
g_object_get(widget, "max-zoom", &max_zoom, "zoom", &zoom, "min-zoom", &min_zoom, NULL);
|
||||||
|
|
||||||
|
pt = osm_gps_map_point_new_degrees(0.0, 0.0);
|
||||||
|
lt = osm_gps_map_point_new_degrees(0.0, 0.0);
|
||||||
|
rb = osm_gps_map_point_new_degrees(0.0, 0.0);
|
||||||
|
target = osm_gps_map_point_new_degrees(0.0, 0.0);
|
||||||
|
|
||||||
|
osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, pt);
|
||||||
|
|
||||||
|
osm_gps_map_get_bbox(map, lt, rb);
|
||||||
|
osm_gps_map_convert_geographic_to_screen(map, lt, <x, <y);
|
||||||
|
osm_gps_map_convert_geographic_to_screen(map, rb, &rbx, &rby);
|
||||||
|
|
||||||
|
if (event->direction == GDK_SCROLL_UP) {
|
||||||
|
if (zoom == max_zoom)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
target_x = event->x + ((ltx + rbx) / 2.0 - (gint)(event->x)) / 2;
|
||||||
|
target_y = event->y + ((lty + rby) / 2.0 - (gint)(event->y)) / 2;
|
||||||
|
|
||||||
|
osm_gps_map_convert_screen_to_geographic(map, target_x, target_y, target);
|
||||||
|
osm_gps_map_point_get_degrees(target, &target_lat, &target_lon);
|
||||||
|
|
||||||
osm_gps_map_zoom_in(map);
|
osm_gps_map_zoom_in(map);
|
||||||
else if (event->direction == GDK_SCROLL_DOWN)
|
} else if (event->direction == GDK_SCROLL_DOWN) {
|
||||||
|
if(zoom == min_zoom)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
target_x = event->x + ((ltx + rbx) / 2.0 - (gint)(event->x)) * 2;
|
||||||
|
target_y = event->y + ((lty + rby) / 2.0 - (gint)(event->y)) * 2;
|
||||||
|
|
||||||
|
osm_gps_map_convert_screen_to_geographic(map, target_x, target_y, target);
|
||||||
|
osm_gps_map_point_get_degrees(target, &target_lat, &target_lon);
|
||||||
|
|
||||||
osm_gps_map_zoom_out(map);
|
osm_gps_map_zoom_out(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* There is no OSM interface to do this afaik. Hack something together */
|
||||||
|
/* set_map_pt_at_xy(map, pt, event->x, event->y); */
|
||||||
|
|
||||||
|
osm_gps_map_set_center(map, target_lat, target_lon);
|
||||||
|
|
||||||
/* don't allow the insane default handler to get its hands on this event */
|
/* don't allow the insane default handler to get its hands on this event */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue