Verified Commit 0ac1e79b authored by James Westman's avatar James Westman
Browse files

map-layer: Implement continuous zoom

The map layer now accepts fractional zoom levels by scaling the entire
map layer with gtk_snapshot_scale().
parent 59815d08
Pipeline #280044 passed with stage
in 3 minutes and 8 seconds
......@@ -489,7 +489,7 @@ shumate_map_layer_size_allocate (GtkWidget *widget,
ShumateViewport *viewport;
GtkAllocation child_allocation;
guint tile_size;
double zoom_level;
guint zoom_level;
double latitude, longitude;
guint longitude_x, latitude_y;
int x_offset, y_offset;
......@@ -499,7 +499,7 @@ shumate_map_layer_size_allocate (GtkWidget *widget,
viewport = shumate_layer_get_viewport (SHUMATE_LAYER (self));
tile_size = shumate_map_source_get_tile_size (self->map_source);
zoom_level = shumate_viewport_get_zoom_level (viewport);
zoom_level = (guint) shumate_viewport_get_zoom_level (viewport);
latitude = shumate_location_get_latitude (SHUMATE_LOCATION (viewport));
longitude = shumate_location_get_longitude (SHUMATE_LOCATION (viewport));
source_rows = shumate_map_source_get_row_count (self->map_source, zoom_level);
......@@ -604,13 +604,13 @@ shumate_map_layer_measure (GtkWidget *widget,
if (natural)
{
ShumateViewport *viewport;
guint tile_size;
double tile_size;
guint zoom_level;
guint count;
viewport = shumate_layer_get_viewport (SHUMATE_LAYER (self));
tile_size = shumate_map_source_get_tile_size (self->map_source);
zoom_level = shumate_viewport_get_zoom_level (viewport);
tile_size = shumate_map_source_get_tile_size (self->map_source) * (fmod (zoom_level, 1.0) + 1.0);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
count = shumate_map_source_get_column_count (self->map_source, zoom_level);
else
......@@ -620,6 +620,23 @@ shumate_map_layer_measure (GtkWidget *widget,
}
}
static void
shumate_map_layer_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
{
ShumateMapLayer *self = SHUMATE_MAP_LAYER (widget);
ShumateViewport *viewport = shumate_layer_get_viewport (SHUMATE_LAYER (self));
double zoom_level = shumate_viewport_get_zoom_level (viewport);
double extra_zoom = fmod (zoom_level, 1.0) + 1.0;
int width = gtk_widget_get_width (GTK_WIDGET (self));
int height = gtk_widget_get_height (GTK_WIDGET (self));
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (width / 2.0, height / 2.0));
gtk_snapshot_scale (snapshot, extra_zoom, extra_zoom);
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (-width / 2.0, -height / 2.0));
GTK_WIDGET_CLASS (shumate_map_layer_parent_class)->snapshot (widget, snapshot);
}
static void
shumate_map_layer_class_init (ShumateMapLayerClass *klass)
{
......@@ -632,6 +649,7 @@ shumate_map_layer_class_init (ShumateMapLayerClass *klass)
object_class->constructed = shumate_map_layer_constructed;
widget_class->size_allocate = shumate_map_layer_size_allocate;
widget_class->snapshot = shumate_map_layer_snapshot;
widget_class->measure = shumate_map_layer_measure;
obj_properties[PROP_MAP_SOURCE] =
......
......@@ -52,6 +52,12 @@ shumate_map_source_class_init (ShumateMapSourceClass *klass)
klass->fill_tile_async = NULL;
}
static double
map_size (ShumateMapSource *self, double zoom_level)
{
return shumate_map_source_get_column_count (self, zoom_level) * shumate_map_source_get_tile_size (self) * (fmod (zoom_level, 1.0) + 1.0);
}
static void
shumate_map_source_init (ShumateMapSource *map_source)
......@@ -215,7 +221,7 @@ shumate_map_source_get_x (ShumateMapSource *map_source,
longitude = CLAMP (longitude, SHUMATE_MIN_LONGITUDE, SHUMATE_MAX_LONGITUDE);
/* FIXME: support other projections */
return ((longitude + 180.0) / 360.0) * shumate_map_source_get_tile_size (map_source) * pow (2.0, zoom_level);
return ((longitude + 180.0) / 360.0) * map_size (map_source, zoom_level);
}
......@@ -242,7 +248,7 @@ shumate_map_source_get_y (ShumateMapSource *map_source,
latitude = CLAMP (latitude, SHUMATE_MIN_LATITUDE, SHUMATE_MAX_LATITUDE);
/* FIXME: support other projections */
sin_latitude = sin (latitude * G_PI / 180.0);
return (0.5 - log ((1.0 + sin_latitude) / (1.0 - sin_latitude)) / (4.0 * G_PI)) * shumate_map_source_get_tile_size (map_source) * pow (2.0, zoom_level);
return (0.5 - log ((1.0 + sin_latitude) / (1.0 - sin_latitude)) / (4.0 * G_PI)) * map_size (map_source, zoom_level);
}
......@@ -265,9 +271,9 @@ shumate_map_source_get_longitude (ShumateMapSource *map_source,
double longitude;
g_return_val_if_fail (SHUMATE_IS_MAP_SOURCE (map_source), 0.0);
/* FIXME: support other projections */
double dx = x / (double) shumate_map_source_get_tile_size (map_source);
longitude = dx / pow (2.0, zoom_level) * 360.0 - 180.0;
longitude = x / map_size (map_source, zoom_level) * 360.0 - 180.0;
return CLAMP (longitude, SHUMATE_MIN_LONGITUDE, SHUMATE_MAX_LONGITUDE);
}
......@@ -289,12 +295,11 @@ shumate_map_source_get_latitude (ShumateMapSource *map_source,
double zoom_level,
double y)
{
double latitude, map_size, dy;
double latitude, dy;
g_return_val_if_fail (SHUMATE_IS_MAP_SOURCE (map_source), 0.0);
/* FIXME: support other projections */
map_size = shumate_map_source_get_tile_size (map_source) * shumate_map_source_get_row_count (map_source, zoom_level);
dy = 0.5 - y / map_size;
dy = 0.5 - y / map_size (map_source, zoom_level);
latitude = 90.0 - 360.0 / G_PI * atan (exp (-dy * 2.0 * G_PI));
return CLAMP (latitude, SHUMATE_MIN_LATITUDE, SHUMATE_MAX_LATITUDE);
......@@ -368,9 +373,8 @@ shumate_map_source_get_meters_per_pixel (ShumateMapSource *map_source,
* radius_at_latitude = 2pi * k * sin (pi/2-theta)
*/
double map_size = shumate_map_source_get_tile_size (map_source) * shumate_map_source_get_row_count (map_source, zoom_level);
/* FIXME: support other projections */
return 2.0 * G_PI * EARTH_RADIUS * sin (G_PI / 2.0 - G_PI / 180.0 * latitude) / map_size;
return 2.0 * G_PI * EARTH_RADIUS * sin (G_PI / 2.0 - G_PI / 180.0 * latitude) / map_size (map_source, zoom_level);
}
......
......@@ -91,7 +91,7 @@ shumate_scale_compute_length (ShumateScale *self,
gboolean *out_is_small_unit)
{
ShumateMapSource *map_source;
int zoom_level;
double zoom_level;
double lat, lon;
float scale_width;
float base;
......
......@@ -248,7 +248,7 @@ move_viewport_from_pixel_offset (ShumateView *self,
ShumateMapSource *map_source;
double x, y;
double lat, lon;
guint zoom_level;
double zoom_level;
guint tile_size, max_x, max_y;
g_assert (SHUMATE_IS_VIEW (self));
......@@ -261,7 +261,7 @@ move_viewport_from_pixel_offset (ShumateView *self,
x = shumate_map_source_get_x (map_source, zoom_level, longitude) - offset_x;
y = shumate_map_source_get_y (map_source, zoom_level, latitude) - offset_y;
tile_size = shumate_map_source_get_tile_size (map_source);
tile_size = shumate_map_source_get_tile_size (map_source) * (fmod (zoom_level, 1.0) + 1.0);
max_x = shumate_map_source_get_column_count (map_source, zoom_level) * tile_size;
max_y = shumate_map_source_get_row_count (map_source, zoom_level) * tile_size;
......@@ -544,7 +544,7 @@ on_scroll_controller_scroll (ShumateView *self,
double scroll_map_x, scroll_map_y;
double view_center_x, view_center_y;
double x_offset, y_offset;
guint zoom_level;
double zoom_level;
scroll_map_x = shumate_viewport_longitude_to_widget_x (priv->viewport, GTK_WIDGET (self), scroll_longitude);
scroll_map_y = shumate_viewport_latitude_to_widget_y (priv->viewport, GTK_WIDGET (self), scroll_latitude);
......
......@@ -417,7 +417,7 @@ void shumate_viewport_zoom_in (ShumateViewport *self)
{
g_return_if_fail (SHUMATE_IS_VIEWPORT (self));
shumate_viewport_set_zoom_level (self, self->zoom_level + 1);
shumate_viewport_set_zoom_level (self, self->zoom_level + 0.2);
}
/**
......@@ -433,7 +433,7 @@ void shumate_viewport_zoom_out (ShumateViewport *self)
if (self->zoom_level == 0)
return;
shumate_viewport_set_zoom_level (self, self->zoom_level - 1);
shumate_viewport_set_zoom_level (self, self->zoom_level - 0.2);
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment