feat(assets): add basemap and orthophoto switcher to nature location detail map
- Include LayerSwitcherControl on the nature location detail map. - Support standard vector, aerial orthophotos, and regional basemaps from window.MAP_BACKGROUNDS. - Ensure proper z-index layer ordering so nature polygons, trees, and equipments remain above raster basemaps. - Update unit tests to verify layer switcher integration.
This commit is contained in:
parent
11e1674f73
commit
69f5e65495
3 changed files with 87 additions and 0 deletions
|
|
@ -18,6 +18,89 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
antialias: true
|
antialias: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ── Helper to place raster basemaps below nature layers ──
|
||||||
|
function getBasemapBeforeLayer(m) {
|
||||||
|
if (!m || !m.getStyle) return undefined;
|
||||||
|
if (m.getLayer('nature-location-fill')) return 'nature-location-fill';
|
||||||
|
if (m.getLayer('nature-location-outline')) return 'nature-location-outline';
|
||||||
|
if (m.getLayer('layer-surfaces-fill')) return 'layer-surfaces-fill';
|
||||||
|
if (m.getLayer('layer-surfaces-outline')) return 'layer-surfaces-outline';
|
||||||
|
if (m.getLayer('layer-shrubs')) return 'layer-shrubs';
|
||||||
|
if (m.getLayer('layer-benches')) return 'layer-benches';
|
||||||
|
if (m.getLayer('layer-trees')) return 'layer-trees';
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Ensure strict layer stacking order on top of basemaps ──
|
||||||
|
function reorderNatureLayers() {
|
||||||
|
const layerOrder = [
|
||||||
|
'nature-location-fill',
|
||||||
|
'nature-location-outline',
|
||||||
|
'layer-surfaces-fill',
|
||||||
|
'layer-surfaces-outline',
|
||||||
|
'layer-shrubs',
|
||||||
|
'layer-benches',
|
||||||
|
'layer-trees',
|
||||||
|
];
|
||||||
|
layerOrder.forEach(function (layerId) {
|
||||||
|
if (map.getLayer(layerId)) {
|
||||||
|
try {
|
||||||
|
map.moveLayer(layerId);
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add layer switcher control for basemaps / orthophotos
|
||||||
|
if (typeof LayerSwitcherControl !== 'undefined') {
|
||||||
|
const layerSwitcher = new LayerSwitcherControl({
|
||||||
|
layers: [{
|
||||||
|
id: 'basemap',
|
||||||
|
name: 'Fonds de plan & Orthophotos',
|
||||||
|
icon: 'satellite',
|
||||||
|
group: 'basemap',
|
||||||
|
beforeLayer: getBasemapBeforeLayer,
|
||||||
|
onLayerAdded: () => reorderNatureLayers(),
|
||||||
|
onVisibilityChange: () => reorderNatureLayers(),
|
||||||
|
layer: {
|
||||||
|
type: 'raster',
|
||||||
|
paint: { 'raster-opacity': 1 }
|
||||||
|
},
|
||||||
|
basemaps: (window.MAP_BACKGROUNDS && window.MAP_BACKGROUNDS.length > 0) ? window.MAP_BACKGROUNDS : undefined,
|
||||||
|
sublayers: [
|
||||||
|
{
|
||||||
|
id: 'urbis',
|
||||||
|
name: window.MAP_ORTHO_WMS_NAME || 'Urbis (Bruxelles)',
|
||||||
|
default: true,
|
||||||
|
source: {
|
||||||
|
type: 'raster',
|
||||||
|
tiles: [
|
||||||
|
window.MAP_ORTHO_WMS_URL || 'https://geoservices-urbis.irisnet.be/geoserver/urbisgrid/wms?service=WMS&version=1.3.0&request=GetMap&layers=Ortho&styles=&format=image/png&transparent=true&width=256&height=256&crs=EPSG:3857&bbox={bbox-epsg-3857}'
|
||||||
|
],
|
||||||
|
tileSize: 256,
|
||||||
|
attribution: window.MAP_ORTHO_WMS_ATTRIBUTION || '© Brussels UrbIS'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'vlaanderen',
|
||||||
|
name: 'Vlaanderen 2023',
|
||||||
|
source: {
|
||||||
|
type: 'raster',
|
||||||
|
tiles: [
|
||||||
|
'https://geo.api.vlaanderen.be/OMW/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=omwrgb23vl&STYLE=&FORMAT=image/png&TILEMATRIXSET=GoogleMapsVL&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}'
|
||||||
|
],
|
||||||
|
tileSize: 256,
|
||||||
|
attribution: '© Digitaal Vlaanderen - Orthofoto 2023'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
map.addControl(layerSwitcher, 'top-right');
|
||||||
|
}
|
||||||
|
|
||||||
// Add navigation and fullscreen controls
|
// Add navigation and fullscreen controls
|
||||||
map.addControl(new maplibregl.NavigationControl({ visualizePitch: true }), 'top-right');
|
map.addControl(new maplibregl.NavigationControl({ visualizePitch: true }), 'top-right');
|
||||||
map.addControl(new maplibregl.FullscreenControl(), 'top-right');
|
map.addControl(new maplibregl.FullscreenControl(), 'top-right');
|
||||||
|
|
@ -190,6 +273,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||||
duration: 800
|
duration: 800
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
reorderNatureLayers();
|
||||||
|
|
||||||
// 3. Interactive Popups
|
// 3. Interactive Popups
|
||||||
const interactiveLayers = [
|
const interactiveLayers = [
|
||||||
|
|
|
||||||
|
|
@ -701,5 +701,6 @@
|
||||||
const assets_geojson = JSON.parse(document.getElementById("assets_geojson_value").textContent);
|
const assets_geojson = JSON.parse(document.getElementById("assets_geojson_value").textContent);
|
||||||
</script>
|
</script>
|
||||||
<script src="{% static 'common/turf.min.js' %}"></script>
|
<script src="{% static 'common/turf.min.js' %}"></script>
|
||||||
|
<script src="{% static 'common/layer-switcher-control.js' %}"></script>
|
||||||
<script src="{% static 'assets/nature_location_detail.js' %}"></script>
|
<script src="{% static 'assets/nature_location_detail.js' %}"></script>
|
||||||
{% endblock script %}
|
{% endblock script %}
|
||||||
|
|
|
||||||
|
|
@ -5565,6 +5565,7 @@ class NatureLocationDetailViewTest(TestCase):
|
||||||
self.assertContains(response, "SHR-001")
|
self.assertContains(response, "SHR-001")
|
||||||
self.assertContains(response, "BNC-001")
|
self.assertContains(response, "BNC-001")
|
||||||
self.assertContains(response, "Quercus robur")
|
self.assertContains(response, "Quercus robur")
|
||||||
|
self.assertContains(response, "layer-switcher-control.js")
|
||||||
self.assertContains(response, "nature_location_detail.js")
|
self.assertContains(response, "nature_location_detail.js")
|
||||||
|
|
||||||
def test_nature_locations_detail_view_empty(self):
|
def test_nature_locations_detail_view_empty(self):
|
||||||
|
|
@ -5592,4 +5593,5 @@ class NatureLocationDetailViewTest(TestCase):
|
||||||
self.assertEqual(len(response.context['documents']), 0)
|
self.assertEqual(len(response.context['documents']), 0)
|
||||||
self.assertContains(response, "Aucune surface végétalisée enregistrée")
|
self.assertContains(response, "Aucune surface végétalisée enregistrée")
|
||||||
self.assertContains(response, "Aucun arbre enregistré")
|
self.assertContains(response, "Aucun arbre enregistré")
|
||||||
|
self.assertContains(response, "layer-switcher-control.js")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue