Leaflet中imageOverlay与layerGroup的缩放层级异常问题
问题分析与解决方案
问题原因
这不是Leaflet的bug,是代码逻辑遗漏了关键步骤:
- 移除
Knooppunten叠加层时,仅将knooppuntenBool设为false,但没有清空knooppuntenGroup中已存在的所有imageOverlay图层。 - 每次缩放地图时,你只移除了当前的
imgA并添加新图层,但之前创建的旧图层其实都保存在knooppuntenGroup里。再次勾选显示该叠加层时,group内所有历史图层会一起被渲染,导致所有旧PNG重新显示。
修复代码
修改overlayremove事件处理逻辑,添加清空图层组的操作,同时优化moveend中的图层移除逻辑:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Test</title> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script> <style> .schermvullend { position: absolute; width: 100%; height: 100%; } </style> </head> <body> <div id="map" class="schermvullend"></div> <script type="text/javascript"> var url = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'; var zoom = 16; var breedtegraad = '51.561721700355974'; var lengtegraad = '5.072394019517229'; var knooppuntenBool = false; var osm = L.tileLayer(url, { maxZoom: 18, attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>' }); var baseMap = 'OpenStreetMap'; var baseMaps = { "OpenStreetMap": osm }; var map = L.map('map', { center: [breedtegraad, lengtegraad], zoom: zoom, layers: [baseMaps[baseMap]] }); var layerControl = L.control.layers(baseMaps, null, {position: 'bottomleft', collapsed: false}).addTo(map); var knooppuntenGroup = L.layerGroup(); let knooppuntenName = 'Knooppunten'; layerControl.addOverlay(knooppuntenGroup, knooppuntenName); var imgA; function getKnooppunten() { let obj = map.getBounds(); let size = map.getSize(); let bbox = obj._southWest.lat + ',' + obj._southWest.lng + ',' + obj._northEast.lat + ',' + obj._northEast.lng; let imageUrl = 'https://service.pdok.nl/wandelnet/regionale-wandelnetwerken/wms/v1_0?' + 'REQUEST=GetMap&' + 'SERVICE=WMS&' + 'VERSION=1.3.0&' + 'FORMAT=image/png&' + 'STYLES=&' + 'TRANSPARENT=true&' + 'layers=wandelnetwerken&' + 'WIDTH=' + size.x + '&' + 'HEIGHT=' + size.y + '&' + 'CRS=EPSG:4326&' + 'BBOX=' + bbox; var errorOverlayUrl = 'https://cdn-icons-png.flaticon.com/512/110/110686.png'; var altText = 'Wandelknooppunten'; var latLngBounds = L.latLngBounds([[obj._southWest.lat, obj._southWest.lng], [obj._northEast.lat, obj._northEast.lng]]); imgA = L.imageOverlay(imageUrl, latLngBounds, { opacity: 1, errorOverlayUrl: errorOverlayUrl, alt: altText, interactive: true }).addTo(knooppuntenGroup); } map.on({ overlayadd: function(e) { if (e.name === knooppuntenName) { getKnooppunten(); knooppuntenBool = true; } }, overlayremove: function(e) { if (e.name === knooppuntenName) { knooppuntenBool = false; // 清空图层组内所有历史图层 knooppuntenGroup.clearLayers(); // 重置imgA引用 imgA = null; } }, moveend: function() { if (knooppuntenBool && imgA) { // 仅当imgA存在时才移除 knooppuntenGroup.removeLayer(imgA); getKnooppunten(); } } }); </script> </body> </html>
关键修改点
- 在
overlayremove事件中添加knooppuntenGroup.clearLayers(),彻底清空图层组内的所有旧图层,同时重置imgA引用避免无效操作。 - 在
moveend事件中增加imgA存在性判断,防止空引用报错。
内容的提问来源于stack exchange,提问作者remko_g
相关产品推荐
相关产品推荐

