fix(assets): ensure asset geometry layers remain above orthophoto basemap on detail maps
This commit is contained in:
parent
34e4da64a8
commit
5ce7179c19
5 changed files with 78 additions and 10 deletions
|
|
@ -94,6 +94,9 @@
|
|||
addIntersectionAssetsLayer(container);
|
||||
addConnectionLinesLayer();
|
||||
}
|
||||
|
||||
// Ensure asset layers are stacked above basemaps
|
||||
bringAssetLayersToTop();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -224,6 +227,8 @@
|
|||
addLineLayer();
|
||||
addPointLayer();
|
||||
}
|
||||
|
||||
bringAssetLayersToTop();
|
||||
}
|
||||
|
||||
function addPointLayer() {
|
||||
|
|
@ -651,9 +656,29 @@
|
|||
'current-asset-icon',
|
||||
];
|
||||
|
||||
function getBasemapBeforeLayer(m) {
|
||||
if (!m || !m.getStyle) return undefined;
|
||||
const styleLayers = (m.getStyle() && m.getStyle().layers) || [];
|
||||
const drawLayer = styleLayers.find(l => l.id && (l.id.startsWith('gl-draw-') || l.id.startsWith('custom-draw-')));
|
||||
if (drawLayer) return drawLayer.id;
|
||||
|
||||
// Return first existing asset layer so basemap is placed below it
|
||||
for (const id of ASSET_LAYER_ORDER) {
|
||||
if (m.getLayer(id)) return id;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function bringAssetLayersToTop() {
|
||||
if (!map || typeof map.isStyleLoaded !== 'function' || !map.isStyleLoaded()) return;
|
||||
ASSET_LAYER_ORDER.forEach(id => {
|
||||
if (map.getLayer(id)) map.moveLayer(id);
|
||||
if (map.getLayer(id)) {
|
||||
try {
|
||||
map.moveLayer(id);
|
||||
} catch (e) {
|
||||
// ignore if layer cannot be moved
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -661,16 +686,25 @@
|
|||
if (typeof LayerSwitcherControl === 'undefined') return;
|
||||
|
||||
const layerSwitcher = new LayerSwitcherControl({
|
||||
onBasemapChange: function() {
|
||||
bringAssetLayersToTop();
|
||||
},
|
||||
layers: [
|
||||
{
|
||||
id: 'ortho',
|
||||
name: 'Orthophotos',
|
||||
icon: 'satellite',
|
||||
group: 'ortho',
|
||||
beforeLayer: getBasemapBeforeLayer,
|
||||
onLayerAdded: () => bringAssetLayersToTop(),
|
||||
onVisibilityChange: (layerId, isVisible) => {
|
||||
if (isVisible) bringAssetLayersToTop();
|
||||
},
|
||||
layer: {
|
||||
type: 'raster',
|
||||
paint: { 'raster-opacity': 1 }
|
||||
},
|
||||
basemaps: (window.MAP_BACKGROUNDS && window.MAP_BACKGROUNDS.length > 0) ? window.MAP_BACKGROUNDS : undefined,
|
||||
sublayers: [
|
||||
{
|
||||
id: 'urbis',
|
||||
|
|
@ -700,6 +734,12 @@
|
|||
|
||||
map.addControl(layerSwitcher, 'top-left');
|
||||
|
||||
// Listen for layer switcher events on map to keep asset layers on top
|
||||
map.on('layerswitcher:layerAdded', bringAssetLayersToTop);
|
||||
map.on('layerswitcher:visibilityChange', (e) => {
|
||||
if (e && e.visible) bringAssetLayersToTop();
|
||||
});
|
||||
|
||||
// The LayerSwitcherControl appends sublayer selectors to document.body with
|
||||
// position:fixed and hardcoded coordinates designed for fullscreen maps.
|
||||
// We move each selector into #asset-map (position:relative) and switch to
|
||||
|
|
@ -723,8 +763,9 @@
|
|||
|
||||
// After any ortho interaction, put asset layers back on top
|
||||
map.getContainer().addEventListener('click', (e) => {
|
||||
if (e.target.closest('.layer-switcher-btn') || e.target.closest('.layer-switcher-sublayer-btn')) {
|
||||
setTimeout(bringAssetLayersToTop, 150);
|
||||
if (e.target.closest('.layer-switcher-btn') || e.target.closest('.layer-switcher-sublayer-btn') || e.target.closest('.layer-switcher-item')) {
|
||||
setTimeout(bringAssetLayersToTop, 50);
|
||||
setTimeout(bringAssetLayersToTop, 200);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
|
|
@ -761,6 +802,10 @@
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
bringAssetLayersToTop();
|
||||
};
|
||||
|
||||
window.bringAssetLayersToTop = bringAssetLayersToTop;
|
||||
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -278,6 +278,10 @@
|
|||
}
|
||||
});
|
||||
|
||||
if (typeof window.bringAssetLayersToTop === 'function') {
|
||||
window.bringAssetLayersToTop();
|
||||
}
|
||||
|
||||
// Remove draw control and listeners
|
||||
if (drawInstance && drawControlAdded) {
|
||||
mapInstance.off('draw.create', handleDrawCreate);
|
||||
|
|
|
|||
|
|
@ -1852,11 +1852,11 @@
|
|||
{% block script %}
|
||||
<!-- MapLibre GL 5.7.0 -->
|
||||
<script src="{% static 'common/maplibre-gl.js' %}"></script>
|
||||
<script src="{% static 'common/layer-switcher-control.js' %}"></script>
|
||||
<script src="{% static 'common/layer-switcher-control.js' %}?v=20261010_order"></script>
|
||||
<script src="{% static 'assets/asset_cms_edit_mode.js' %}"></script>
|
||||
<script src="{% static 'assets/asset_location_edit.js' %}"></script>
|
||||
<!-- MapLibre map initialization for asset detail -->
|
||||
<script src="{% static 'assets/asset_generic_map.js' %}"></script>
|
||||
<script src="{% static 'assets/asset_generic_map.js' %}?v=20261010_order"></script>
|
||||
<!-- MapboxDraw for geometry editing (Point, LineString, Polygon) -->
|
||||
<script src="{% static 'common/mapbox-gl-draw.js' %}"></script>
|
||||
<script src="{% static 'assets/asset_geometry_edit.js' %}?v=1.1"></script>
|
||||
|
|
@ -1865,11 +1865,11 @@
|
|||
{% block extra_scripts %}
|
||||
<!-- MapLibre GL 5.7.0 -->
|
||||
<script src="{% static 'common/maplibre-gl.js' %}"></script>
|
||||
<script src="{% static 'common/layer-switcher-control.js' %}"></script>
|
||||
<script src="{% static 'common/layer-switcher-control.js' %}?v=20261010_order"></script>
|
||||
<script src="{% static 'assets/asset_cms_edit_mode.js' %}"></script>
|
||||
<script src="{% static 'assets/asset_location_edit.js' %}"></script>
|
||||
<!-- MapLibre map initialization for asset detail -->
|
||||
<script src="{% static 'assets/asset_generic_map.js' %}"></script>
|
||||
<script src="{% static 'assets/asset_generic_map.js' %}?v=20261010_order"></script>
|
||||
<!-- MapboxDraw for geometry editing (Point, LineString, Polygon) -->
|
||||
<script src="{% static 'common/mapbox-gl-draw.js' %}"></script>
|
||||
<script src="{% static 'assets/asset_geometry_edit.js' %}?v=1.1"></script>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class NatureLocationsGeoJSONTest(TestCase):
|
|||
|
||||
# Create a user
|
||||
self.user = User.objects.create_user(username="testuser", password="password123")
|
||||
self.config = UserConfig.objects.create(user=self.user)
|
||||
self.config = UserConfig.objects.create(user=self.user, is_intern=True, limit_assets_to_contracts=False)
|
||||
|
||||
# Give thematic access to user
|
||||
UserThematics.objects.create(
|
||||
|
|
@ -5720,6 +5720,8 @@ class NatureLocationDetailViewTest(TestCase):
|
|||
self.assertTemplateNotUsed(response, 'assets/naturegreensurface_detail.html')
|
||||
self.assertContains(response, "GS-001")
|
||||
self.assertContains(response, 'id="asset-map"')
|
||||
self.assertContains(response, 'asset_generic_map.js?v=20261010_order')
|
||||
self.assertContains(response, 'layer-switcher-control.js?v=20261010_order')
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -748,6 +748,9 @@
|
|||
if (mainLayer.onVisibilityChange && typeof mainLayer.onVisibilityChange === 'function') {
|
||||
mainLayer.onVisibilityChange(layerId, false, this.map);
|
||||
}
|
||||
if (typeof this.options.onVisibilityChange === 'function') {
|
||||
this.options.onVisibilityChange(layerId, false, this.map);
|
||||
}
|
||||
if (typeof this.map.fire === 'function') {
|
||||
this.map.fire('layerswitcher:visibilityChange', { layerId, visible: false });
|
||||
}
|
||||
|
|
@ -776,7 +779,7 @@
|
|||
const mainLayer = this.layers[0] || {};
|
||||
let beforeLayer = typeof mainLayer.beforeLayer === 'function'
|
||||
? mainLayer.beforeLayer(this.map)
|
||||
: mainLayer.beforeLayer;
|
||||
: (mainLayer.beforeLayer || (typeof this.options.beforeLayer === 'function' ? this.options.beforeLayer(this.map) : this.options.beforeLayer));
|
||||
|
||||
if (this.map.getLayer('territory-mask')) {
|
||||
beforeLayer = 'territory-mask';
|
||||
|
|
@ -788,7 +791,15 @@
|
|||
beforeLayer = undefined;
|
||||
const layers = (this.map.getStyle() && this.map.getStyle().layers) || [];
|
||||
for (const l of layers) {
|
||||
if (l.id.startsWith('gl-draw-') || l.id.startsWith('custom-draw-') || l.id.startsWith('polygon-')) {
|
||||
if (
|
||||
l.id.startsWith('gl-draw-') ||
|
||||
l.id.startsWith('custom-draw-') ||
|
||||
l.id.startsWith('polygon-') ||
|
||||
l.id.startsWith('asset-') ||
|
||||
l.id.startsWith('nature-') ||
|
||||
l.id.startsWith('layer-') ||
|
||||
l.id.startsWith('intersection-')
|
||||
) {
|
||||
beforeLayer = l.id;
|
||||
break;
|
||||
}
|
||||
|
|
@ -827,9 +838,15 @@
|
|||
if (mainLayer.onLayerAdded && typeof mainLayer.onLayerAdded === 'function') {
|
||||
mainLayer.onLayerAdded(layerId, this.map);
|
||||
}
|
||||
if (typeof this.options.onLayerAdded === 'function') {
|
||||
this.options.onLayerAdded(layerId, this.map);
|
||||
}
|
||||
if (mainLayer.onVisibilityChange && typeof mainLayer.onVisibilityChange === 'function') {
|
||||
mainLayer.onVisibilityChange(layerId, true, this.map);
|
||||
}
|
||||
if (typeof this.options.onVisibilityChange === 'function') {
|
||||
this.options.onVisibilityChange(layerId, true, this.map);
|
||||
}
|
||||
if (typeof this.map.fire === 'function') {
|
||||
this.map.fire('layerswitcher:layerAdded', { layerId, config: bg });
|
||||
this.map.fire('layerswitcher:visibilityChange', { layerId, visible: true });
|
||||
|
|
|
|||
Loading…
Reference in a new issue