From 08520776349b1fe40814f5192badd3bb1371ca2c Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 14 Dec 2023 15:34:45 +0100 Subject: [PATCH] Use bounds instead of center when zooming to Polyline/Polygon Here is the initial issue: - when using defaultView=latest (means latest element of the default layer) - when map loads, we find the element, call getCenter to center the map on it - but Polygon/Polyline needs the element to be already on the map to call this method (at least because the map CRS is needed) So while trying to fix that issue, I also found that using a centroid for a complex geometry was not very friendly: the map zoom on a part of this geometry, while it seems to be that it's better to have a full view of it. Now that we highlight the selected element, it's also easier to get which element is focused when there are a lot close one to the others. --- umap/static/umap/js/umap.features.js | 12 ++++ umap/tests/base.py | 2 +- umap/tests/integration/test_export_map.py | 4 +- umap/tests/integration/test_map.py | 73 ++++++++++++++++++++++- umap/tests/test_map_views.py | 2 +- 5 files changed, 87 insertions(+), 6 deletions(-) diff --git a/umap/static/umap/js/umap.features.js b/umap/static/umap/js/umap.features.js index 46b611c8..98fa1c80 100644 --- a/umap/static/umap/js/umap.features.js +++ b/umap/static/umap/js/umap.features.js @@ -959,6 +959,18 @@ L.U.PathMixin = { bounds = bounds || this.map.getBounds() return bounds.overlaps(this.getBounds()) }, + + zoomTo: function (e) { + // Use bounds instead of centroid for paths. + e = e || {} + const easing = e.easing !== undefined ? e.easing : this.map.options.easing + if (easing) { + this.map.flyToBounds(this.getBounds(), this.getBestZoom()) + } else { + this.map.fitBounds(this.getBounds(), this.getBestZoom() || this.map.getZoom()) + } + if (e.callback) e.callback.call(this) + }, } L.U.Polyline = L.Polyline.extend({ diff --git a/umap/tests/base.py b/umap/tests/base.py index bbcaa043..3109f568 100644 --- a/umap/tests/base.py +++ b/umap/tests/base.py @@ -18,7 +18,7 @@ DATALAYER_DATA = { "type": "Feature", "geometry": { "type": "Point", - "coordinates": [13.68896484375, 48.55297816440071], + "coordinates": [14.68896484375, 48.55297816440071], }, "properties": { "_umap_options": {"color": "DarkCyan", "iconClass": "Ball"}, diff --git a/umap/tests/integration/test_export_map.py b/umap/tests/integration/test_export_map.py index a7f7f9d0..ef15dc70 100644 --- a/umap/tests/integration/test_export_map.py +++ b/umap/tests/integration/test_export_map.py @@ -34,7 +34,7 @@ def test_umap_export(map, live_server, datalayer, page): "features": [ { "geometry": { - "coordinates": [13.68896484375, 48.55297816440071], + "coordinates": [14.68896484375, 48.55297816440071], "type": "Point", }, "properties": { @@ -85,5 +85,5 @@ def test_csv_export(map, live_server, datalayer, page): assert ( path.read_text() == """name,description,Latitude,Longitude -Here,Da place anonymous again 755,48.55297816440071,13.68896484375""" +Here,Da place anonymous again 755,48.55297816440071,14.68896484375""" ) diff --git a/umap/tests/integration/test_map.py b/umap/tests/integration/test_map.py index c964fae8..3bcbb2f8 100644 --- a/umap/tests/integration/test_map.py +++ b/umap/tests/integration/test_map.py @@ -17,11 +17,80 @@ def test_default_view_latest_without_datalayer_should_use_default_center( ): datalayer.settings["displayOnLoad"] = False datalayer.save() - map.settings["defaultView"] = "latest" + map.settings["properties"]["defaultView"] = "latest" map.save() page.goto(f"{live_server.url}{map.get_absolute_url()}") # Hash is defined, so map is initialized - expect(page).to_have_url(re.compile(".*#7/.*")) + expect(page).to_have_url(re.compile(r".*#7/48\..+/13\..+")) + layers = page.locator(".umap-browse-datalayers li") + expect(layers).to_have_count(1) + + +def test_default_view_latest_with_marker(map, live_server, datalayer, page): + map.settings["properties"]["defaultView"] = "latest" + map.save() + page.goto(f"{live_server.url}{map.get_absolute_url()}") + # Hash is defined, so map is initialized + expect(page).to_have_url(re.compile(r".*#7/48\..+/14\..+")) + layers = page.locator(".umap-browse-datalayers li") + expect(layers).to_have_count(1) + + +def test_default_view_latest_with_line(map, live_server, page): + data = { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {"name": "a line"}, + "geometry": { + "type": "LineString", + "coordinates": [ + [2.12, 49.57], + [3.19, 48.77], + [2.51, 47.55], + [1.08, 49.02], + ], + }, + } + ], + } + DataLayerFactory(map=map, data=data) + map.settings["properties"]["defaultView"] = "latest" + map.save() + page.goto(f"{live_server.url}{map.get_absolute_url()}") + expect(page).to_have_url(re.compile(r".*#8/48\..+/2\..+")) + layers = page.locator(".umap-browse-datalayers li") + expect(layers).to_have_count(1) + + +def test_default_view_latest_with_polygon(map, live_server, page): + data = { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {"name": "a polygon"}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [2.12, 49.57], + [1.08, 49.02], + [2.51, 47.55], + [3.19, 48.77], + [2.12, 49.57], + ] + ], + }, + } + ], + } + DataLayerFactory(map=map, data=data) + map.settings["properties"]["defaultView"] = "latest" + map.save() + page.goto(f"{live_server.url}{map.get_absolute_url()}") + expect(page).to_have_url(re.compile(r".*#8/48\..+/2\..+")) layers = page.locator(".umap-browse-datalayers li") expect(layers).to_have_count(1) diff --git a/umap/tests/test_map_views.py b/umap/tests/test_map_views.py index d86b925f..f56b316e 100644 --- a/umap/tests/test_map_views.py +++ b/umap/tests/test_map_views.py @@ -640,7 +640,7 @@ def test_download(client, map, datalayer): "features": [ { "geometry": { - "coordinates": [13.68896484375, 48.55297816440071], + "coordinates": [14.68896484375, 48.55297816440071], "type": "Point", }, "properties": {