refresh leaflet map: map container is already init

2019-01-10 22:48发布

问题:

I have a page where given a select to the user he can switch the leaflet map I show.

After a initial leaflet map load, my problem is when i want to refresh the map.

I always get "Map container is already initialized":

The problem line is:

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

Initially it loads well, but when I select another parameter in the form and want to display the map another time it crashes.

btw, I've tried to destroy and recreate $('#mapa') with jQuery before the second setView() but it shows the same error.

回答1:

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);
}

I use this:

document.getElementById('weathermap').innerHTML = "<div id='map' style='width: 100%; height: 100%;'></div>";

to reload content of div where render map.



回答2:

Try map.remove(); before you try to reload the map. This removes the previous map element using Leaflet's library (instead of jquery's).



回答3:

the best way

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

You should add map.off(), it also works faster, and does not cause problems with the events



回答4:

well, after much seeking i realized it's well documented at http://leafletjs.com/examples/layers-control.html

i've ended not repainting the map, but print it once and repaint the points on each new ajax call, so the problem was how to clean up the old points and print only the new ones. i've ended doing this:

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

so, at each new ajax call, before painting the new points, i do the following:

for (i=0;i<points.length;i++) {
  map.removeLayer(points[i]);
}
points=[];

so far, so good :-)



回答5:

When you just remove a map, it destroys the div id reference, so, after remove() you need to build again the div where the map will be displayed, in order to avoid the "Uncaught Error: Map container not found".

if(map != undefined || map != null){
    map.remove();
   $("#map").html("");
   $("#preMap").empty();
   $( "<div id=\"map\" style=\"height: 500px;\"></div>" ).appendTo("#preMap");
}


回答6:

Before initializing map check for is the map is already initiated or not

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


回答7:

I had same problem.then i set globally map variable e.g var map= null and then for display map i check

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

By this solution your map will be initialize only first time after that map will be fill by L.Map then it will not be null. so no error will be there like map container already initialize.



回答8:

use the redrawAll() function rather than renderAll().



回答9:

I had the same problem on angular when switching page. I had to add this code before leaving the page to make it works:

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

Without document.getElementById('mapLayer').innerHTML = "" the map was not displayed on the next page.



回答10:

Only use this

map.invalidateSize();

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