我有一个页面,用户可以在其中选择他可以切换我显示的传单地图。
在初始传单地图加载后,我的问题是当我想刷新地图时。
我总是得到“地图容器已经初始化”:
问题线是:
var map = L.map('mapa').setView([lat, lon], 15);
最初它加载得很好,但是当我在表单中选择另一个参数并想再次显示地图时它崩溃了。
顺便说一句,我尝试$('#mapa')
在第二个之前使用 jQuery销毁和重新创建,setView()
但它显示了相同的错误。
我有一个页面,用户可以在其中选择他可以切换我显示的传单地图。
在初始传单地图加载后,我的问题是当我想刷新地图时。
我总是得到“地图容器已经初始化”:
问题线是:
var map = L.map('mapa').setView([lat, lon], 15);
最初它加载得很好,但是当我在表单中选择另一个参数并想再次显示地图时它崩溃了。
顺便说一句,我尝试$('#mapa')
在第二个之前使用 jQuery销毁和重新创建,setView()
但它显示了相同的错误。
在尝试map.remove();
重新加载地图之前先尝试。这使用 Leaflet 的库(而不是 jquery 的)删除了先前的地图元素。
最好的办法
map.off();
map.remove();
您应该添加 map.off(),它的运行速度也更快,并且不会导致事件出现问题
html:
<div id="weathermap"></div>
JavaScript:
function buildMap(lat,lon) {
document.getElementById('weathermap').innerHTML = "<div id='map' style='width: 100%; height: 100%;'></div>";
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttribution = 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors,' +
' <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
osmLayer = new L.TileLayer(osmUrl, {maxZoom: 18, attribution: osmAttribution});
var map = new L.Map('map');
map.setView(new L.LatLng(lat,lon), 9 );
map.addLayer(osmLayer);
var validatorsLayer = new OsmJs.Weather.LeafletLayer({lang: 'en'});
map.addLayer(validatorsLayer);
}
我用这个:
document.getElementById('weathermap').innerHTML = "<div id='map' style='width: 100%; height: 100%;'></div>";
在渲染地图的地方重新加载 div 的内容。
在初始化地图之前检查地图是否已经启动
var container = L.DomUtil.get('map');
if(container != null){
container._leaflet_id = null;
}
在初始化地图之前检查地图是否已经启动
var container = L.DomUtil.get('map');
if(container != null){
container._leaflet_id = null;
}
map.invalidateSize();
这个对我有用
好吧,经过多次寻找后,我意识到它在http://leafletjs.com/examples/layers-control.html上有很好的记录
我已经结束没有重新绘制地图,而是打印一次并在每个新的 ajax 调用上重新绘制点,所以问题是如何清理旧点并只打印新点。我已经结束了这样做:
var point = L.marker([new_marker[0], new_marker[1]]).addTo(map).bindPopup('blah blah');
points.push(point);
//points is a temporary array where i store the points for removing them afterwards
因此,在每次新的 ajax 调用中,在绘制新点之前,我都会执行以下操作:
for (i=0;i<points.length;i++) {
map.removeLayer(points[i]);
}
points=[];
到目前为止,一切都很好 :-)
当您只是删除地图时,它会破坏 div id 引用,因此,在 remove() 之后,您需要再次构建将显示地图的 div,以避免“未捕获错误:未找到地图容器”。
if(map != undefined || map != null){
map.remove();
$("#map").html("");
$("#preMap").empty();
$( "<div id=\"map\" style=\"height: 500px;\"></div>" ).appendTo("#preMap");
}
您可以尝试在初始化地图之前或离开页面时删除地图:
if(this.map) {
this.map.remove();
}
切换页面时,我在角度上遇到了同样的问题。我必须在离开页面之前添加此代码以使其正常工作:
$scope.$on('$locationChangeStart', function( event ) {
if(map != undefined)
{
map.remove();
map = undefined
document.getElementById('mapLayer').innerHTML = "";
}
});
没有document.getElementById('mapLayer').innerHTML = ""
地图没有显示在下一页。
如果要更新地图视图,例如更改地图中心,则不必删除然后重新创建地图,只需更新坐标即可
const mapInit = () => {
let map.current = w.L.map('map');
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright" target="_blank">OpenStreetMap</a> contributors'
}).addTo(map.current);
}
const setCoordinate = (gps_lat, gps_long) => {
map.setView([gps_lat, gps_long], 13);
}
initMap();
setCoordinate(50.403723 30.623538);
setTimeout(() => {
setCoordinate(51.505, -0.09);
}, 3000);
我有同样的问题。然后我设置全局地图变量,例如 var map=null 然后为显示地图我检查
if(map==null)then map=new L.Map('idopenstreet').setView();
通过此解决方案,您的地图将仅在 L.Map 填充该地图后第一次初始化,然后它不会为空。所以不会像地图容器已经初始化那样出现错误。
要在同一页面中刷新地图,您可以使用以下代码在页面上创建地图
if (!map) {
this.map = new L.map("mapDiv", {
center: [24.7136, 46.6753],
zoom: 5,
renderer: L.canvas(),
attributionControl: true,
});
}
然后使用下面的行刷新地图,但请确保使用相同的纬度、经度和缩放选项
map.setView([24.7136, 46.6753], 5);
此外,在使用 Angular 2+ 在同一页面中的选项卡之间切换时,我遇到了同样的问题,我可以通过在 Component 中添加以下代码来修复它constructor
var container = L.DomUtil.get('mapDiv');
if (container != null) {
container.outerHTML = ""; // Clear map generated HTML
// container._leaflet_id = null; << didn't work for me
}
您应该尝试在 react js 中卸载该函数以删除现有地图。
const Map = () => {
const mapContainer = useRef();
const [map, setMap] = useState({});
useEffect(()=>{
const map = L.map(mapContainer.current, {attributionControl: false}).setView([51.505, -0.09], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
maxZoom: 18,
attribution: 'Map',
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1
}).addTo(map);
// unmount map function
return () => map.remove();
}, []);
return (
<div style={{padding: 0, margin: 0, width: "100%", height: "100vh",}}
ref={el => mapContainer.current = el}>
</div>
);
}
使用redrawAll() 函数而不是renderAll()。
我们今天面临这个问题,我们解决了它。我们所做的 ?
传单地图加载 div 如下。
<div id="map_container">
<div id="listing_map" class="right_listing"></div>
</div>
当表单输入更改或提交时,我们按照以下步骤操作。在我的页面中删除传单地图容器并再次创建新的之后。
$( '#map_container' ).html( ' ' ).append( '<div id="listing_map" class="right_listing"></div>' );
在此代码之后,我的传单地图与表单过滤器一起工作正常,可以再次重新加载。
谢谢你。
如果您不全局存储地图对象引用,我建议
if (L.DomUtil.get('map-canvas') !== undefined) {
L.DomUtil.get('map-canvas')._leaflet_id = null;
}
<div id="map-canvas"></div>
地图被绘制到的对象在哪里。
这样,您就可以避免重新创建 html 元素,如果您这样做,就会发生这种情况remove()
。
对于刷新传单地图,您可以使用以下代码:
this.map.fitBounds(this.map.getBounds());
我在反应时遇到了同样的问题我通过在 useEffect 的顶部初始化解决了它这是我的反应代码。
const mapContainerRef = useRef(null);
useEffect( async () => {
const res =await Axios.get(BASE_PATH + 'fetchProperty')
const container = L.DomUtil.get(mapContainerRef.current); if(container != null){ container._leaflet_id = null; }
if(container) {
const mapView = L.map( mapContainerRef.current, {
zoom: 13,
center: [19.059984, 72.889999]
// maxZoom: 13
// minZoom: 15
});
// const canvas = mapView.getCanvasContainer();
mapView.zoomControl.setPosition("bottomright");
mapView.attributionControl.addAttribution(
"<a href='https://mascots.pro'>Mascots. pro</a>"
);
L.tileLayer(
// "https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=" + https://api.mapbox.com/styles/v1/anonymousmw/cko1eb1r20mdu18qqtps8i03p/tiles/{z}/{x}/{y}?access_token=
"https://api.mapbox.com/styles/v1/mapbox/dark-v9/tiles/{z}/{x}/{y}?access_token=" +
access_token,
{
attribution: '<a href="http://mascots.work">Mascots</a>'
}
).addTo(mapView);
const mask = L.tileLayer.mask(
"https://api.mapbox.com/styles/v1/anonymousmw/cko1eb1r20mdu18qqtps8i03p/tiles/{z}/{x}/{y}?access_token=" +
access_token,
{
attribution: '<a href="https://mascots.pro">Mascots pro</a>',
maskSize: 300
// maxZoom: 18,
// maxNativeZoom: 16
// tms: true
}
)
.addTo(mapView);
mapView.on("mousemove", function (e) {
mask.setCenter(e.containerPoint);
});
res.data.map((marker) => {
const innerHtmlContent = `<div id='popup-container' class='popup-container'> <h3> Property Details</h3>
<div class='popup-label'>Building Name :<p>${marker.Building}</p></div>
<div class='popup-address-label'> Address : <p>${marker.Landmark}, ${marker.Location}</p></div>
<div class='popup-rent-label'>Monthly Rent : <p> ₹ ${marker.Price}</p></div>
</div>`;
const divElement = document.createElement("div");
const assignBtn = document.createElement("div");
assignBtn.className = "map-link";
assignBtn.innerHTML = `<button class="view-btn">View Property</button>`;
divElement.innerHTML = innerHtmlContent;
divElement.appendChild(assignBtn);
assignBtn.addEventListener("click", (e) => {
console.log("dsvsdvb");
});
var iconOptions = {
iconUrl: "/images/location_pin2.svg",
iconSize: [25, 25]
};
var customIcon = L.icon(iconOptions);
// create popup contents
var customPopup = divElement;
// specify popup options
var customOptions = {
maxWidth: "500",
className: "custom"
};
const markerOptions = {
// title: "MyLocation",
// draggable: true
clickable: true,
icon: customIcon
};
const mark = L.marker([marker.Latitude,marker.Longitude], markerOptions);
mark.bindPopup(customPopup, customOptions);
mark.addTo(mapView);
// return mapView.off();
});
return () => mapView.remove();
}
}, [])
return (
<div className="map-box">
<div className="map-container" ref={mapContainerRef}></div>
</div>
);
我遇到了同样的问题,所以我在地图实例中创建了一个方法来重新加载它。
var map = L.map('mapa').setView([lat, lon], 15);
map.reload = function(){
map.remove();
map = L.map('mapa').setView([lat, lon], 15);
}
....
map.reload();
我在 reactjs 中做了这个
// Create map (dev = reuse existing map)
let myMap = L.DomUtil.get('map');
if(myMap == null){
myMap = L.map('mapid').setView(currentLocation, zoom);
}
html:
<div id='leaflet-map' #leafletMap></div>
JavaScript:
@ViewChild('leafletMap')
private mapElement: ElementRef;
private initMap(): void {
this.map = leaflet.map(this.mapElement.nativeElement, {
center: [39.01860177826393, 35.30274319309024],
zoom: 4,
});
leaflet
.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '',
maxZoom: 18,
})
.addTo(this.map);
}
放
var container = L.DomUtil.get('map');
if (container['_leaflet_id'] != null) {
container.remove();
}
前var map = L.map('map')
请享用 :)