Aggiunta / rimozione di strati GeoJSON di volantini


30

Sto cercando di mostrare diversi livelli GeoJSON a diversi livelli di zoom utilizzando l'API Leaflet. Posso caricare e visualizzare tutti e tre i livelli contemporaneamente (anche se in realtà non li voglio mostrare tutti contemporaneamente). Posso caricarli e visualizzarli a diversi livelli di zoom.

Ho impostato il codice in modo che ai livelli di zoom 1-6, la mappa mostrerà un livello GeoJSON. Ai livelli 7-10, ne mostrerà un altro, e ai livelli 11+ ne mostrerà un terzo. Visualizzarli funziona. Quello che sto cercando di far funzionare ora è spegnere gli altri se ne viene visualizzato uno. Passare da 1-6 a 7-10 funziona (il che significa che disattiva correttamente il livello 1-6), ma non da 7-10 a 11+ (il che significa che il livello 7-10 rimane in giro) e non riesco a capire perché (usa lo stesso codice).

Ecco l'ajax per i layer GeoJSON:

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

Ed ecco la funzione principale che chiama ajax a seconda dello zoom. inizialmente simpCounter è impostato su 0.

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

Quindi, di nuovo, la prima transizione disattiva correttamente il vecchio livello, mentre la seconda transizione no. Grazie per l'aiuto.


Giusto per chiarire, si sta accendendo il json per 11+ e NON si spegne 7-10?
RomaH,

È corretto.
Josh,

Risposte:


28

Prova questo invece:

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

E per la tua funzione di chiamata:

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

Quando si passa gli argomenti map, geojsonLayere defaultStylenella chiamata getJson(defaultStyle, map, 60, geojsonLayer);che si sta creando nuove istanze degli oggetti. Quindi esegui un lavoro sulle istanze che possono riflettersi sullo schermo ma una volta tornato al "ciclo principale", in pratica dimentica tutto ciò che ha appena fatto e ritorna allo stato precedente.

Dato che immagino che tu abbia definito defaultStyle, mape la geojsonLayerpopolazione iniziale nell'ambito globale, devi solo chiamarli, non è necessario passarli. Con le regolazioni che ho apportato, cambia il globale, mapquindi i cambiamenti persistono al termine delle chiamate di funzione.

Questa soluzione ha funzionato per me. Puoi vedere l'intero contenuto del file che ho creato qui: http://pastebin.com/yMYQJ2jK

Definisco anche un livello di zoom finale per 1-7 in modo da poter vedere i tuoi dati JSON iniziali quando torni al livello di zoom iniziale, altrimenti viene perso e non viene mai richiamato a meno che non ricarichi la pagina!


Grazie. Non mi rendevo conto che il passaggio delle variabili crea istanze temporanee.
Josh,

Sì, l'unico modo per mantenere i cambiamenti nel modo in cui lo stavi facendo sarebbe passarli indietro con una returndichiarazione. L'uso dei globali in JavaScript sembra comune, quindi farlo in questo modo sarà il modo più semplice per completare l'attività.
RomaH,

Ciò ha senso. Avevo letto di recente in un libro di Best Practices di non usare i globi, ma apparentemente stavo abusando dell'alternativa. Grazie.
Josh,

È buona prassi in tutti i linguaggi di programmazione non usare i globali, è più facile rintracciare i bug. Ma le migliori pratiche sono solo una regola empirica. La maggior parte degli usi di javascript in-page sembra abbastanza leggera da poter gestire facilmente gli effetti collaterali. Se stai scrivendo un intero modulo o js esterni, eviterei i globi.
RomaH,

1

il volantino ha un tipo di raccolta di gruppi di dati di struttura di dati e anche un'interfaccia di controllo del livello che puoi attivare e disattivare una volta codificato come listener di eventi sulla casella di controllo.


1

Ho scritto l'esempio di seguito per mostrare come rimuovere livelli multipli geoJSON.

///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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.