From 003b25d5e0ac6e6447b201f8d6d03afe663ddcff Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 11 Mar 2025 15:23:58 +0100 Subject: [PATCH] fix: import iconUrl as absolute when possible This will only cover the cases where the icon is set at the map or at the layer level, not the one of the marker itself. cf #2552 --- umap/static/umap/js/modules/umap.js | 14 +- .../test_upload_data_with_iconurl.umap | 122 ++++++++++++++++++ umap/tests/integration/test_import.py | 17 +++ 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 umap/tests/fixtures/test_upload_data_with_iconurl.umap diff --git a/umap/static/umap/js/modules/umap.js b/umap/static/umap/js/modules/umap.js index 1648f1fe..e181c3fb 100644 --- a/umap/static/umap/js/modules/umap.js +++ b/umap/static/umap/js/modules/umap.js @@ -1630,7 +1630,16 @@ export default class Umap extends ServerStored { importRaw(rawData) { const importedData = JSON.parse(rawData) - + let remoteOrigin = '' + if (importedData.uri) { + const uri = new URL(importedData.uri) + if (uri.origin !== window.location.origin) { + remoteOrigin = uri.origin + } + } + if (importedData.properties?.iconUrl?.startsWith('/')) { + importedData.properties.iconUrl = remoteOrigin + importedData.properties.iconUrl + } this.setProperties(importedData.properties) if (importedData.geometry) { @@ -1642,6 +1651,9 @@ export default class Umap extends ServerStored { delete geojson._storage } delete geojson._umap_options?.id // Never trust an id at this stage + if (geojson._umap_options?.iconUrl?.startsWith('/')) { + geojson._umap_options.iconUrl = remoteOrigin + geojson._umap_options.iconUrl + } const dataLayer = this.createDirtyDataLayer(geojson._umap_options) dataLayer.fromUmapGeoJSON(geojson) } diff --git a/umap/tests/fixtures/test_upload_data_with_iconurl.umap b/umap/tests/fixtures/test_upload_data_with_iconurl.umap new file mode 100644 index 00000000..a5a5b18f --- /dev/null +++ b/umap/tests/fixtures/test_upload_data_with_iconurl.umap @@ -0,0 +1,122 @@ +{ + "type": "umap", + "uri": "https://umap.incubateur.anct.gouv.fr/fr/map/aires-de-covoiturage-du-departement-de-la-nievre_42", + "properties": { + "easing": false, + "embedControl": true, + "fullscreenControl": true, + "searchControl": true, + "datalayersControl": true, + "zoomControl": true, + "permanentCreditBackground": true, + "sortKey": "com_lieu", + "slideshow": {}, + "captionMenus": true, + "captionBar": false, + "limitBounds": {}, + "overlay": {}, + "tilelayer": { + "tms": false, + "name": "OpenStreetMap", + "maxZoom": 19, + "minZoom": 0, + "attribution": "map data © [[http://osm.org/copyright|OpenStreetMap contributors]] under ODbL", + "url_template": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" + }, + "licence": "", + "description": "", + "name": "Aires de covoiturage du département de la Nièvre", + "defaultView": "data", + "onLoadPanel": "none", + "displayPopupFooter": false, + "miniMap": false, + "moreControl": true, + "scaleControl": true, + "scrollWheelZoom": true, + "zoom": 9 + }, + "geometry": { + "type": "Point", + "coordinates": [ + 3.4552001953125004, + 47.12527904224337 + ] + }, + "layers": [ + { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "id_lieu": "58004-C-001", + "id_local": "", + "nom_lieu": "Maison du Bazois", + "ad_lieu": "Bois de Seigne", + "com_lieu": "ALLUY", + "insee": "58004", + "type": "Parking", + "date_maj": "29/08/2019", + "ouvert": "true", + "source": "225800010", + "nbre_pl": "4", + "nbre_pmr": "", + "duree": "", + "horaires": "", + "proprio": "", + "lumiere": "", + "comm": "" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 3.634832, + 47.043123 + ] + } + }, + { + "type": "Feature", + "properties": { + "id_lieu": "58012-C-001", + "id_local": "", + "nom_lieu": "Mairie", + "ad_lieu": "28 route de Saint-Amand", + "com_lieu": "ARQUIAN", + "insee": "58012", + "type": "Auto-stop", + "date_maj": "19/05/2021", + "ouvert": "true", + "source": "810157982", + "nbre_pl": "", + "nbre_pmr": "", + "duree": "", + "horaires": "", + "proprio": "", + "lumiere": "true", + "comm": "" + }, + "geometry": { + "type": "Point", + "coordinates": [ + 2.99163, + 47.5407 + ] + } + } + ], + "_umap_options": { + "displayOnLoad": true, + "browsable": false, + "editMode": "disabled", + "remoteData": {}, + "popupContentTemplate": "# {nom_lieu}\nAdresse : {ad_lieu} {com_lieu}\nType : {type}\nNombre de places : {nbre_pl}\n", + "color": "SpringGreen", + "iconUrl": "/uploads/pictogram/car-24.png", + "labelKey": "com_lieu", + "id": 73, + "name": "Liste des aires de covoiturage" + } + } + ] +} diff --git a/umap/tests/integration/test_import.py b/umap/tests/integration/test_import.py index 86440a3a..095b2da6 100644 --- a/umap/tests/integration/test_import.py +++ b/umap/tests/integration/test_import.py @@ -870,3 +870,20 @@ def test_import_from_multiple_files(live_server, page, tilelayer): page.get_by_role("button", name="Import data", exact=True).click() # Two in one file, one in the other expect(markers).to_have_count(3) + + +def test_umap_import_with_iconurl(live_server, tilelayer, page): + page.goto(f"{live_server.url}/map/new/") + page.get_by_title("Import data").click() + file_input = page.locator("input[type='file']") + with page.expect_file_chooser() as fc_info: + file_input.click() + file_chooser = fc_info.value + path = Path(__file__).parent.parent / "fixtures/test_upload_data_with_iconurl.umap" + file_chooser.set_files(path) + page.get_by_role("button", name="Import data", exact=True).click() + expect( + page.locator( + 'img[src="https://umap.incubateur.anct.gouv.fr/uploads/pictogram/car-24.png"]' + ) + ).to_have_count(2)