[libshumate] Fix zoom formula



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]