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);
|
addIntersectionAssetsLayer(container);
|
||||||
addConnectionLinesLayer();
|
addConnectionLinesLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure asset layers are stacked above basemaps
|
||||||
|
bringAssetLayersToTop();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,6 +227,8 @@
|
||||||
addLineLayer();
|
addLineLayer();
|
||||||
addPointLayer();
|
addPointLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bringAssetLayersToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPointLayer() {
|
function addPointLayer() {
|
||||||
|
|
@ -651,9 +656,29 @@
|
||||||
'current-asset-icon',
|
'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() {
|
function bringAssetLayersToTop() {
|
||||||
|
if (!map || typeof map.isStyleLoaded !== 'function' || !map.isStyleLoaded()) return;
|
||||||
ASSET_LAYER_ORDER.forEach(id => {
|
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;
|
if (typeof LayerSwitcherControl === 'undefined') return;
|
||||||
|
|
||||||
const layerSwitcher = new LayerSwitcherControl({
|
const layerSwitcher = new LayerSwitcherControl({
|
||||||
|
onBasemapChange: function() {
|
||||||
|
bringAssetLayersToTop();
|
||||||
|
},
|
||||||
layers: [
|
layers: [
|
||||||
{
|
{
|
||||||
id: 'ortho',
|
id: 'ortho',
|
||||||
name: 'Orthophotos',
|
name: 'Orthophotos',
|
||||||
icon: 'satellite',
|
icon: 'satellite',
|
||||||
group: 'ortho',
|
group: 'ortho',
|
||||||
|
beforeLayer: getBasemapBeforeLayer,
|
||||||
|
onLayerAdded: () => bringAssetLayersToTop(),
|
||||||
|
onVisibilityChange: (layerId, isVisible) => {
|
||||||
|
if (isVisible) bringAssetLayersToTop();
|
||||||
|
},
|
||||||
layer: {
|
layer: {
|
||||||
type: 'raster',
|
type: 'raster',
|
||||||
paint: { 'raster-opacity': 1 }
|
paint: { 'raster-opacity': 1 }
|
||||||
},
|
},
|
||||||
|
basemaps: (window.MAP_BACKGROUNDS && window.MAP_BACKGROUNDS.length > 0) ? window.MAP_BACKGROUNDS : undefined,
|
||||||
sublayers: [
|
sublayers: [
|
||||||
{
|
{
|
||||||
id: 'urbis',
|
id: 'urbis',
|
||||||
|
|
@ -700,6 +734,12 @@
|
||||||
|
|
||||||
map.addControl(layerSwitcher, 'top-left');
|
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
|
// The LayerSwitcherControl appends sublayer selectors to document.body with
|
||||||
// position:fixed and hardcoded coordinates designed for fullscreen maps.
|
// position:fixed and hardcoded coordinates designed for fullscreen maps.
|
||||||
// We move each selector into #asset-map (position:relative) and switch to
|
// 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
|
// After any ortho interaction, put asset layers back on top
|
||||||
map.getContainer().addEventListener('click', (e) => {
|
map.getContainer().addEventListener('click', (e) => {
|
||||||
if (e.target.closest('.layer-switcher-btn') || e.target.closest('.layer-switcher-sublayer-btn')) {
|
if (e.target.closest('.layer-switcher-btn') || e.target.closest('.layer-switcher-sublayer-btn') || e.target.closest('.layer-switcher-item')) {
|
||||||
setTimeout(bringAssetLayersToTop, 150);
|
setTimeout(bringAssetLayersToTop, 50);
|
||||||
|
setTimeout(bringAssetLayersToTop, 200);
|
||||||
}
|
}
|
||||||
}, true);
|
}, 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
|
// Remove draw control and listeners
|
||||||
if (drawInstance && drawControlAdded) {
|
if (drawInstance && drawControlAdded) {
|
||||||
mapInstance.off('draw.create', handleDrawCreate);
|
mapInstance.off('draw.create', handleDrawCreate);
|
||||||
|
|
|
||||||
|
|
@ -1852,11 +1852,11 @@
|
||||||
{% block script %}
|
{% block script %}
|
||||||
<!-- MapLibre GL 5.7.0 -->
|
<!-- MapLibre GL 5.7.0 -->
|
||||||
<script src="{% static 'common/maplibre-gl.js' %}"></script>
|
<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_cms_edit_mode.js' %}"></script>
|
||||||
<script src="{% static 'assets/asset_location_edit.js' %}"></script>
|
<script src="{% static 'assets/asset_location_edit.js' %}"></script>
|
||||||
<!-- MapLibre map initialization for asset detail -->
|
<!-- 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) -->
|
<!-- MapboxDraw for geometry editing (Point, LineString, Polygon) -->
|
||||||
<script src="{% static 'common/mapbox-gl-draw.js' %}"></script>
|
<script src="{% static 'common/mapbox-gl-draw.js' %}"></script>
|
||||||
<script src="{% static 'assets/asset_geometry_edit.js' %}?v=1.1"></script>
|
<script src="{% static 'assets/asset_geometry_edit.js' %}?v=1.1"></script>
|
||||||
|
|
@ -1865,11 +1865,11 @@
|
||||||
{% block extra_scripts %}
|
{% block extra_scripts %}
|
||||||
<!-- MapLibre GL 5.7.0 -->
|
<!-- MapLibre GL 5.7.0 -->
|
||||||
<script src="{% static 'common/maplibre-gl.js' %}"></script>
|
<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_cms_edit_mode.js' %}"></script>
|
||||||
<script src="{% static 'assets/asset_location_edit.js' %}"></script>
|
<script src="{% static 'assets/asset_location_edit.js' %}"></script>
|
||||||
<!-- MapLibre map initialization for asset detail -->
|
<!-- 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) -->
|
<!-- MapboxDraw for geometry editing (Point, LineString, Polygon) -->
|
||||||
<script src="{% static 'common/mapbox-gl-draw.js' %}"></script>
|
<script src="{% static 'common/mapbox-gl-draw.js' %}"></script>
|
||||||
<script src="{% static 'assets/asset_geometry_edit.js' %}?v=1.1"></script>
|
<script src="{% static 'assets/asset_geometry_edit.js' %}?v=1.1"></script>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class NatureLocationsGeoJSONTest(TestCase):
|
||||||
|
|
||||||
# Create a user
|
# Create a user
|
||||||
self.user = User.objects.create_user(username="testuser", password="password123")
|
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
|
# Give thematic access to user
|
||||||
UserThematics.objects.create(
|
UserThematics.objects.create(
|
||||||
|
|
@ -5720,6 +5720,8 @@ class NatureLocationDetailViewTest(TestCase):
|
||||||
self.assertTemplateNotUsed(response, 'assets/naturegreensurface_detail.html')
|
self.assertTemplateNotUsed(response, 'assets/naturegreensurface_detail.html')
|
||||||
self.assertContains(response, "GS-001")
|
self.assertContains(response, "GS-001")
|
||||||
self.assertContains(response, 'id="asset-map"')
|
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') {
|
if (mainLayer.onVisibilityChange && typeof mainLayer.onVisibilityChange === 'function') {
|
||||||
mainLayer.onVisibilityChange(layerId, false, this.map);
|
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') {
|
if (typeof this.map.fire === 'function') {
|
||||||
this.map.fire('layerswitcher:visibilityChange', { layerId, visible: false });
|
this.map.fire('layerswitcher:visibilityChange', { layerId, visible: false });
|
||||||
}
|
}
|
||||||
|
|
@ -776,7 +779,7 @@
|
||||||
const mainLayer = this.layers[0] || {};
|
const mainLayer = this.layers[0] || {};
|
||||||
let beforeLayer = typeof mainLayer.beforeLayer === 'function'
|
let beforeLayer = typeof mainLayer.beforeLayer === 'function'
|
||||||
? mainLayer.beforeLayer(this.map)
|
? 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')) {
|
if (this.map.getLayer('territory-mask')) {
|
||||||
beforeLayer = 'territory-mask';
|
beforeLayer = 'territory-mask';
|
||||||
|
|
@ -788,7 +791,15 @@
|
||||||
beforeLayer = undefined;
|
beforeLayer = undefined;
|
||||||
const layers = (this.map.getStyle() && this.map.getStyle().layers) || [];
|
const layers = (this.map.getStyle() && this.map.getStyle().layers) || [];
|
||||||
for (const l of 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;
|
beforeLayer = l.id;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -827,9 +838,15 @@
|
||||||
if (mainLayer.onLayerAdded && typeof mainLayer.onLayerAdded === 'function') {
|
if (mainLayer.onLayerAdded && typeof mainLayer.onLayerAdded === 'function') {
|
||||||
mainLayer.onLayerAdded(layerId, this.map);
|
mainLayer.onLayerAdded(layerId, this.map);
|
||||||
}
|
}
|
||||||
|
if (typeof this.options.onLayerAdded === 'function') {
|
||||||
|
this.options.onLayerAdded(layerId, this.map);
|
||||||
|
}
|
||||||
if (mainLayer.onVisibilityChange && typeof mainLayer.onVisibilityChange === 'function') {
|
if (mainLayer.onVisibilityChange && typeof mainLayer.onVisibilityChange === 'function') {
|
||||||
mainLayer.onVisibilityChange(layerId, true, this.map);
|
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') {
|
if (typeof this.map.fire === 'function') {
|
||||||
this.map.fire('layerswitcher:layerAdded', { layerId, config: bg });
|
this.map.fire('layerswitcher:layerAdded', { layerId, config: bg });
|
||||||
this.map.fire('layerswitcher:visibilityChange', { layerId, visible: true });
|
this.map.fire('layerswitcher:visibilityChange', { layerId, visible: true });
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue