76

我有一个页面,用户可以在其中选择他可以切换我显示的传单地图。

在初始传单地图加载后,我的问题是当我想刷新地图时。

我总是得到“地图容器已经初始化”:

问题线是:

var map = L.map('mapa').setView([lat, lon], 15);

最初它加载得很好,但是当我在表单中选择另一个参数并想再次显示地图时它崩溃了。

顺便说一句,我尝试$('#mapa')在第二个之前使用 jQuery销毁和重新创建,setView()但它显示了相同的错误。

4

23 回答 23

117

在尝试map.remove();重新加载地图之前先尝试。这使用 Leaflet 的库(而不是 jquery 的)删除了先前的地图元素。

于 2013-10-05T04:05:16.933 回答
39

最好的办法

map.off();
map.remove();

您应该添加 map.off(),它的运行速度也更快,并且不会导致事件出现问题

于 2016-08-14T06:56:10.067 回答
38

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 的内容。

于 2013-12-04T10:51:06.260 回答
19

在初始化地图之前检查地图是否已经启动

var container = L.DomUtil.get('map');
      if(container != null){
        container._leaflet_id = null;
      }
于 2018-04-26T04:38:16.767 回答
9

只用这个

map.invalidateSize();

https://github.com/Leaflet/Leaflet/issues/690

于 2018-12-18T16:04:25.720 回答
6

在初始化地图之前检查地图是否已经启动

var container = L.DomUtil.get('map');

if(container != null){

container._leaflet_id = null;

}

map.invalidateSize();

这个对我有用

于 2019-09-09T10:16:31.167 回答
5

好吧,经过多次寻找后,我意识到它在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=[];

到目前为止,一切都很好 :-)

于 2013-10-05T16:56:42.093 回答
5

当您只是删除地图时,它会破坏 div id 引用,因此,在 remove() 之后,您需要再次构建将显示地图的 div,以避免“未捕获错误:未找到地图容器”。

if(map != undefined || map != null){
    map.remove();
   $("#map").html("");
   $("#preMap").empty();
   $( "<div id=\"map\" style=\"height: 500px;\"></div>" ).appendTo("#preMap");
}
于 2016-11-17T15:19:07.577 回答
4

您可以尝试在初始化地图之前或离开页面时删除地图:

if(this.map) {
  this.map.remove();
}
于 2019-03-02T10:52:48.553 回答
3

切换页面时,我在角度上遇到了同样的问题。我必须在离开页面之前添加此代码以使其正常工作:

    $scope.$on('$locationChangeStart', function( event ) {
    if(map != undefined)
    {
      map.remove();
      map = undefined
      document.getElementById('mapLayer').innerHTML = "";
    }
});

没有document.getElementById('mapLayer').innerHTML = ""地图没有显示在下一页。

于 2018-05-17T07:47:40.380 回答
3

如果要更新地图视图,例如更改地图中心,则不必删除然后重新创建地图,只需更新坐标即可

const mapInit = () => {
 let map.current = w.L.map('map');

 L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <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);
于 2020-03-26T17:27:40.777 回答
1

我有同样的问题。然后我设置全局地图变量,例如 var map=null 然后为显示地图我检查

if(map==null)then map=new L.Map('idopenstreet').setView();

通过此解决方案,您的地图将仅在 L.Map 填充该地图后第一次初始化,然后它不会为空。所以不会像地图容器已经初始化那样出现错误。

于 2016-06-06T13:43:08.077 回答
1

要在同一页面中刷新地图,您可以使用以下代码在页面上创建地图

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
}
于 2020-09-08T20:04:25.947 回答
1

您应该尝试在 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>
    );
}
于 2021-04-02T13:41:11.670 回答
0

使用redrawAll() 函数而不是renderAll()。

于 2017-04-16T19:42:31.350 回答
0

我们今天面临这个问题,我们解决了它。我们所做的 ?

传单地图加载 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>' );

在此代码之后,我的传单地图与表单过滤器一起工作正常,可以再次重新加载。

谢谢你。

于 2020-01-26T13:45:27.480 回答
0

如果您不全局存储地图对象引用,我建议

if (L.DomUtil.get('map-canvas') !== undefined) { 
   L.DomUtil.get('map-canvas')._leaflet_id = null; 
}

<div id="map-canvas"></div>地图被绘制到的对象在哪里。

这样,您就可以避免重新创建 html 元素,如果您这样做,就会发生这种情况remove()

于 2020-07-26T19:20:33.700 回答
0

对于刷新传单地图,您可以使用以下代码:

this.map.fitBounds(this.map.getBounds());

于 2020-07-28T05:10:35.190 回答
0

我在反应时遇到了同样的问题我通过在 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>
);
于 2021-05-11T12:31:12.250 回答
0

我遇到了同样的问题,所以我在地图实例中创建了一个方法来重新加载它。

var map = L.map('mapa').setView([lat, lon], 15);
map.reload = function(){
   map.remove();
   map = L.map('mapa').setView([lat, lon], 15);
}

....

map.reload();

于 2021-07-02T03:15:41.673 回答
0

我在 reactjs 中做了这个

// Create map (dev = reuse existing map)
let myMap = L.DomUtil.get('map');
if(myMap == null){
  myMap = L.map('mapid').setView(currentLocation, zoom);
}
于 2021-08-05T22:20:11.463 回答
0

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);
}
于 2021-11-25T09:26:02.543 回答
0

    var container = L.DomUtil.get('map');
    if (container['_leaflet_id'] != null) {
      container.remove();
    }

var map = L.map('map')

请享用 :)

于 2022-03-02T12:01:30.850 回答