我已经在这里看到了同样的问题:StackOverflow 但没有一个答案有帮助,或者至少我不明白。
如果我通过单击在地图上放置新标记,然后再次单击删除标记,然后尝试缩放,则会收到错误:
TypeError: Cannot read properties of null (reading '_latLngToNewLayerPoint')
at NewClass._animateZoom
发生这种情况的一个更简单的示例是当我单击标记以查看弹出窗口时。看到弹出窗口后,我关闭弹出窗口,然后尝试缩放,但每次缩放都会出错。
当我第一次关闭弹出窗口时,我收到一条警告,说
listener not found
这很奇怪,因为我只需单击地图即可关闭弹出窗口,并且 I DO 当我单击地图时有一个侦听器。
这是代码:
var mapLink = '<a href="https://www.esri.com/">Esri</a>';
var wholink = 'i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community';
var satelliteLayer = L.tileLayer(
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: '© ' + mapLink + ', ' + wholink,
maxZoom: 18,
});
var osm = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
});
var mapboxUrl = 'https://api.mapbox.com/styles/v1/johnmichel/ciobach7h0084b3nf482gfvvr/tiles/{z}/{x}/{y}?access_token=pk.eyJ1Ijoiam9obm1pY2hlbCIsImEiOiJjaW9iOW1vbHUwMGEzdnJseWNranhiMHpxIn0.leVOjMBazNl6v4h9MT7Glw';
var mapboxAttribution = 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>'
var streets = L.tileLayer(mapboxUrl, { id: 'mapbox/streets-v11', tileSize: 512, zoomOffset: -1, attribution: mapboxAttribution });
var map = L.map("mapContainer", {
center: [lat, lng],
zoom: 10,
layers: [osm, satelliteLayer, streets],
maxZoom: 18,
minZoom: 10,
smoothWheelZoom: true, // enable smooth zoom
smoothSensitivity: 1, // zoom speed. default is 1
smoothZoom: true,
smoothZoomDelay: 1000 // Default to 1000
}).on('click', this.onMapClick);
map.on('moveend', this.onMapMoved)
var baseMaps = {
"OpenStreetMap": osm,
"Satellite": satelliteLayer,
"Mapbox Streets": streets
};
var kayakLaunchLayer = L.layerGroup([]);
var yourPin = L.layerGroup([]);
this.markerLayerGroup = L.layerGroup();
this.singleMarkerLayerGroup = L.layerGroup();
var layerControl = L.control.layers(baseMaps).addTo(map);
map.addLayer(kayakLaunchLayer);
map.addLayer(yourPin);
this.markerLayerGroup = kayakLaunchLayer;
this.singleMarkerLayerGroup = yourPin;
// layerControl.addOverlay(this.markerLayerGroup, "Kayak Launches");
// layerControl.addOverlay(this.singleMarkerLayerGroup, "Your Pin");
map.invalidateSize();
this.map = map;
this.map
是我的 Vue 组件中 data
中定义的变量,this.singleMarkerLayerGroup
和 this.markerLayerGroup
也是如此。
这是我实际将标记添加到
this.markerLayerGroup
的功能,以便我可以将它们视为地图上的叠加层:
var lat = launch.loc.coordinates[1];
var lng = launch.loc.coordinates[0];
var marker = L.marker([lat, lng]).addTo(this.markerLayerGroup).on('click', this.onMarkerClick);
var photoImgwithContent = `<h2><a href="/launch/${launch._id}">${launch.name}</a></h2><img src="${launch.images[0]}" height="150px" width="150px"/><h3></h3>${this.capitalizeFirstLetter(launch.waterType)}`;
marker.bindPopup(photoImgwithContent);
现在这有什么问题吗?我已经重组了代码以尽可能严格地遵循文档,但仍然感到困惑。
但奇怪的是,如果我通过应用此地图选项来关闭缩放动画:zoomAnimation:false,那么错误就消失了,但没有缩放动画的地图看起来很糟糕。
这看起来与 Uncaught TypeError: this._map is null (Vue.js 3, Leaflet) 中的情况类似,因为您似乎使用 Vue.js 3,并且在某些 Layers/ 之后缩放地图时会发生错误弹出窗口已删除:
罪魁祸首是 Vue 对
的代理,这似乎干扰了 Leaflet 事件(取消)绑定。看起来 Vue 3 现在会自动执行深度代理this.map
解决方案包括每当您使用地图和图层组(即存储在
this
Vue 组件数据中的所有 Leaflet 对象)时“展开”/取消代理它们,例如与 Vue3 的 toRaw
实用函数:
var marker = L.marker([lat, lng])
.addTo(toRaw(this.markerLayerGroup));
另请参阅 Vue 3 指南减少大型不可变结构的反应性开销。
对于标记,您可以执行以下操作:
L.Marker.prototype._animateZoom = function (opt) {
if (!this._map) {
return
}
const pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
this._setPos(pos);
}