Hinzufügen / Entfernen von Leaflet GeoJSON-Layern

30

Ich versuche, mithilfe der Leaflet-API verschiedene GeoJSON-Ebenen in verschiedenen Zoomebenen anzuzeigen. Ich kann alle drei Ebenen gleichzeitig laden und anzeigen (obwohl ich eigentlich nicht möchte, dass sie alle gleichzeitig angezeigt werden). Ich kann sie in verschiedenen Zoomstufen laden und anzeigen.

Ich habe den Code so eingestellt, dass die Karte bei Zoomstufen 1-6 einen GeoJSON-Layer anzeigt. Auf den Stufen 7-10 wird eine andere und auf den Stufen 11+ eine dritte angezeigt. Das Anzeigen funktioniert. Ich versuche jetzt, die anderen auszuschalten, wenn einer angezeigt wird. Es funktioniert, von 1-6 auf 7-10 zu gehen (was bedeutet, dass die 1-6-Ebene korrekt deaktiviert wird), aber nicht von 7-10 auf 11+ (was bedeutet, dass die 7-10-Ebene erhalten bleibt), und ich kann es mir nicht vorstellen herausfinden, warum (es verwendet den gleichen Code).

Hier ist der Ajax für die GeoJSON-Ebenen:

function getJson(defaultStyle, map, simp, geojsonLayer){
var url = 'file' + simp + '.json';
map.removeLayer(geojsonLayer);
geojsonLayer.clearLayers();
$.getJSON(url, function(data){
    geojsonLayer = L.geoJson(data, {
        style: defaultStyle,
        onEachFeature: onEachFeature
    });
    geojsonLayer.addTo(map);
});
}

Und hier ist die Hauptfunktion, die den Ajax abhängig vom Zoom aufruft. simpCounter wird anfänglich auf 0 gesetzt.

map.on('zoomend', function(e) {
if (map.getZoom() >= 7 && map.getZoom() <= 10) {
    if (simpCounter == 0 || simpCounter == 2) {
    getJson(defaultStyle, map, 60, geojsonLayer);
    simpCounter = 1;
    }
} else if (map.getZoom() >= 11) {
    if (simpCounter == 0 || simpCounter == 1) {
    getJson(defaultStyle, map, 35, geojsonLayer);
    simpCounter = 2;
    }
}
});

Der erste Übergang schaltet also die alte Ebene wieder korrekt aus, der zweite Übergang jedoch nicht. Danke für die Hilfe.

Josh
quelle
Nur um zu verdeutlichen, es ist das Einschalten des JSON für 11+ und NICHT das Ausschalten von 7-10?
RomaH
Das ist richtig.
Josh

Antworten:

28

Versuchen Sie dies stattdessen:

function getJson(simp){  //Removed unneeded arguments here
    var url = 'file' + simp + '.json';
    map.removeLayer(geojsonLayer);
    //geojsonLayer.clearLayers();  I don't believe this needed.
    $.getJSON(url, function(data){
        geojsonLayer = L.geoJson(data, {
            style: defaultStyle,
            onEachFeature: onEachFeature
        });
        geojsonLayer.addTo(map);
    });
}

Und für Ihre anrufende Funktion:

map.on('zoomend', function(e) {
    if (map.getZoom() >= 7 && map.getZoom() <= 10) {
        if (simpCounter == 0 || simpCounter == 2) {
        getJson(60);
        simpCounter = 1;
        }
    } else if (map.getZoom() >= 11) {
        if (simpCounter == 0 || simpCounter == 1) {
        getJson(35);
        simpCounter = 2;
        }
    } else if (map.getZoom() <= 7) { //Return to original data
        if (simpCounter == 1 || simpCounter == 2) {
        getJson(XX); //Fill out with correct file name
        simpCounter = 0;
        }
    }
});

Wenn Sie die Argumente sind vorbei map, geojsonLayerund defaultStylein dem Anruf getJson(defaultStyle, map, 60, geojsonLayer);Du neue Instanzen der Objekte erstellen. Anschließend bearbeiten Sie die Instanzen, die möglicherweise auf dem Bildschirm angezeigt werden. Sobald sie jedoch in die Hauptschleife zurückkehren, werden im Grunde alle Aktionen vergessen und der vorherige Status wird wiederhergestellt.

Da ich vermute, dass Sie definiert defaultStylehaben mapund die anfängliche geojsonLayerGrundgesamtheit im globalen Bereich Sie nur anrufen müssen, müssen Sie sie nicht weitergeben. Mit den Anpassungen, die ich vorgenommen habe, wurden die globalen mapÄnderungen so angepasst, dass die Änderungen auch nach Beendigung der Funktionsaufrufe bestehen bleiben.

Diese Lösung hat bei mir funktioniert. Sie können den gesamten Inhalt der von mir erstellten Datei hier sehen: http://pastebin.com/yMYQJ2jK

Ich definiere auch eine endgültige Zoomstufe für 1-7, damit Sie Ihre anfänglichen JSON-Daten sehen können, wenn Sie zur anfänglichen Zoomstufe zurückkehren.

RomaH
quelle
Vielen Dank. Ich wusste nicht, dass das Übergeben von Variablen temporäre Instanzen erzeugt.
Josh
Ja, die einzige Möglichkeit, die Änderungen so beizubehalten, wie Sie sie vorgenommen haben, wäre, sie mit einer returnErklärung zurückzusenden. Die Verwendung von Globals in Javascript scheint üblich zu sein, daher ist es am einfachsten, diese Aufgabe zu erledigen.
RomaH
Das macht Sinn. Ich hatte kürzlich in einem Best Practices-Buch gelesen, dass man keine Globals verwenden soll, aber anscheinend habe ich die Alternative missbraucht. Vielen Dank.
Josh
Es ist in allen Programmiersprachen eine bewährte Methode, keine Globals zu verwenden. Es ist einfacher, Fehler zu verfolgen. Best Practice ist jedoch nur eine Faustregel. Die meisten Javascript-in-Page-Anwendungen scheinen so leicht zu sein, dass die Nebenwirkungen leicht beherrscht werden können. Wenn Sie ein ganzes Modul oder externe Js schreiben, würde ich Globals vermeiden.
RomaH
1

Die Broschüre verfügt über eine Datenstruktur vom Typ Layergruppensammlung und eine Benutzeroberfläche für die Layerkontrolle, die Sie ein- und ausschalten können, sobald Sie sie als Ereignis-Listener für das Kontrollkästchen codieren.

Carl Carlson
quelle
1

Ich habe das folgende Beispiel geschrieben, um zu zeigen, wie man mehrere geoJSON-Layer entfernt.

///adding geoJSON data

          var myGeoJSON = L.geoJSON(myData, {

            onEachFeature: function (feature, layer) {
                layer.myTag = "myGeoJSON"
            }

        });


////// function to remove geoJSON layers 

    var removeMarkers = function() {
        map.eachLayer( function(layer) {

          if ( layer.myTag &&  layer.myTag === "myGeoJSON") {
            map.removeLayer(layer)
              }

            });

    }

//// calling function 

removeMarkers();
Mercel Santos
quelle