[libshumate] Fix zoom formula
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate] Fix zoom formula
- Date: Thu, 26 Aug 2021 06:58:38 +0000 (UTC)
commit 01e3df83ae8be58bedd4c9c9d60942d608576e45
Author: James Westman <james jwestman net>
Date: Fri Aug 20 00:50:03 2021 -0500
Fix zoom formula
The formula for calculating zoom between integer levels was
incorrect--it was linear, rather than exponential like the overall
function. This change makes zooming smoother and more consistent.
Also, added shumate_map_source_get_tile_size_at_zoom to reduce code
duplication.
shumate/shumate-map-layer.c | 4 ++--
shumate/shumate-map-source.c | 27 ++++++++++++++++++++++++++-
shumate/shumate-map-source.h | 2 ++
shumate/shumate-map.c | 2 +-
shumate/shumate-viewport.c | 2 +-
5 files changed, 32 insertions(+), 5 deletions(-)
---
diff --git a/shumate/shumate-map-layer.c b/shumate/shumate-map-layer.c
index a7cd28b..0fd0786 100644
--- a/shumate/shumate-map-layer.c
+++ b/shumate/shumate-map-layer.c
@@ -506,7 +506,7 @@ shumate_map_layer_measure (GtkWidget *widget,
viewport = shumate_layer_get_viewport (SHUMATE_LAYER (self));
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);
+ tile_size = shumate_map_source_get_tile_size_at_zoom (self->map_source, zoom_level);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
count = shumate_map_source_get_column_count (self->map_source, zoom_level);
else
@@ -522,7 +522,7 @@ 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;
+ double extra_zoom = pow (2.0, fmod (zoom_level, 1.0));
int width = gtk_widget_get_width (GTK_WIDGET (self));
int height = gtk_widget_get_height (GTK_WIDGET (self));
double rotation = shumate_viewport_get_rotation (viewport);
diff --git a/shumate/shumate-map-source.c b/shumate/shumate-map-source.c
index 364b2cb..422b108 100644
--- a/shumate/shumate-map-source.c
+++ b/shumate/shumate-map-source.c
@@ -295,7 +295,7 @@ shumate_map_source_class_init (ShumateMapSourceClass *klass)
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);
+ return shumate_map_source_get_column_count (self, zoom_level) * shumate_map_source_get_tile_size_at_zoom
(self, zoom_level);
}
@@ -572,6 +572,31 @@ shumate_map_source_get_tile_size (ShumateMapSource *map_source)
return priv->tile_size;
}
+/**
+ * shumate_map_source_get_tile_size_at_zoom:
+ * @map_source: a #ShumateMapSource
+ * @zoom_level: a zoom level
+ *
+ * Gets the apparent size of the map tiles at the given fractional zoom level.
+ *
+ * As the map is zoomed in, a tile gets bigger and bigger until, at the next
+ * integer zoom level, it "splits" into four tiles at the next zoom level.
+ * Thus, the size increase follows an exponential curve, base 2.
+ *
+ * Returns: the tile's size (width and height) in pixels for this map source
+ * at this zoom level
+ */
+double
+shumate_map_source_get_tile_size_at_zoom (ShumateMapSource *map_source,
+ double zoom_level)
+{
+ ShumateMapSourcePrivate *priv = shumate_map_source_get_instance_private (map_source);
+
+ g_return_val_if_fail (SHUMATE_IS_MAP_SOURCE (map_source), 0);
+
+ return priv->tile_size * pow (2.0, fmod (zoom_level, 1.0));
+}
+
/**
* shumate_map_source_set_tile_size:
* @map_source: a #ShumateMapSource
diff --git a/shumate/shumate-map-source.h b/shumate/shumate-map-source.h
index c359f0c..b29aebc 100644
--- a/shumate/shumate-map-source.h
+++ b/shumate/shumate-map-source.h
@@ -79,6 +79,8 @@ guint shumate_map_source_get_max_zoom_level (ShumateMapSource *map_source);
void shumate_map_source_set_max_zoom_level (ShumateMapSource *map_source,
guint zoom_level);
guint shumate_map_source_get_tile_size (ShumateMapSource *map_source);
+double shumate_map_source_get_tile_size_at_zoom (ShumateMapSource *map_source,
+ double zoom_level);
void shumate_map_source_set_tile_size (ShumateMapSource *map_source,
guint tile_size);
ShumateMapProjection shumate_map_source_get_projection (ShumateMapSource *map_source);
diff --git a/shumate/shumate-map.c b/shumate/shumate-map.c
index d39729e..b3a57cf 100644
--- a/shumate/shumate-map.c
+++ b/shumate/shumate-map.c
@@ -194,7 +194,7 @@ move_location_to_coords (ShumateMap *self,
if (map_source == NULL)
return;
- tile_size = shumate_map_source_get_tile_size (map_source) * (fmod (zoom_level, 1.0) + 1.0);
+ tile_size = shumate_map_source_get_tile_size_at_zoom (map_source, zoom_level);
map_width = tile_size * shumate_map_source_get_column_count (map_source, zoom_level);
map_height = tile_size * shumate_map_source_get_row_count (map_source, zoom_level);
diff --git a/shumate/shumate-viewport.c b/shumate/shumate-viewport.c
index 9774c14..770e205 100644
--- a/shumate/shumate-viewport.c
+++ b/shumate/shumate-viewport.c
@@ -598,7 +598,7 @@ shumate_viewport_widget_coords_to_location (ShumateViewport *self,
height = gtk_widget_get_height (widget);
rotate_around_center (&x, &y, width, height, -self->rotation);
- tile_size = shumate_map_source_get_tile_size (self->ref_map_source) * (fmod (self->zoom_level, 1.0) + 1);
+ tile_size = shumate_map_source_get_tile_size_at_zoom (self->ref_map_source, self->zoom_level);
map_width = tile_size * shumate_map_source_get_column_count (self->ref_map_source, self->zoom_level);
map_height = tile_size * shumate_map_source_get_row_count (self->ref_map_source, self->zoom_level);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]