Dodawanie / usuwanie warstw Ulotki GeoJSON

30

Próbuję pokazać różne warstwy GeoJSON na różnych warstwach powiększenia za pomocą interfejsu API Leaflet. Mogę ładować i wyświetlać wszystkie trzy warstwy jednocześnie (choć tak naprawdę nie chcę, aby wszystkie były wyświetlane jednocześnie). Mogę ładować i wyświetlać je przy różnych poziomach powiększenia.

Mam ustawiony kod, aby na poziomach powiększenia 1-6 mapa wyświetlała jedną warstwę GeoJSON. Na poziomach 7-10 pokaże inny, a na poziomach 11+ pokaże trzeci. Wyświetlanie ich działa. To, co próbuję teraz uruchomić, to wyłączenie innych, jeśli jeden jest wyświetlany. Przejście od 1-6 do 7-10 działa (co oznacza, że ​​poprawnie wyłącza warstwę 1-6), ale nie od 7-10 do 11+ (co oznacza, że ​​warstwa 7-10 przykleja się) i nie mogę zrozumieć dlaczego (używa tego samego kodu).

Oto ajax dla warstw 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);
});
}

A oto główna funkcja, która wywołuje ajax w zależności od powiększenia. simpCounter jest początkowo ustawiony na 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;
    }
}
});

Więc ponownie, pierwsze przejście poprawnie wyłącza starą warstwę, ale drugie przejście nie. Dzięki za pomoc.

Josh
źródło
Żeby wyjaśnić, to włącza JSON dla 11+ i NIE wyłącza 7-10?
RomaH
To jest poprawne.
Josh

Odpowiedzi:

28

Spróbuj zamiast tego:

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

A dla twojej funkcji wywoływania:

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

Gdy przekazujesz argumenty map, geojsonLayera defaultStylew wywołaniu getJson(defaultStyle, map, 60, geojsonLayer);tworzysz nowe wystąpienia obiektów. Następnie wykonujesz pracę nad instancjami, które mogą odbijać się na ekranie, ale po powrocie do „głównej pętli” w zasadzie zapomina o wszystkim, co właśnie zrobił i powraca do poprzedniego stanu.

Ponieważ zgaduję, że zdefiniowałeś defaultStyle, mapa początkowa geojsonLayerpopulacja w zasięgu globalnym po prostu musisz do nich zadzwonić, nie musisz ich przekazywać. Z korektami, które wprowadziłem, zmienia globalny, mapwięc zmiany utrzymują się po zakończeniu wywołań funkcji.

To rozwiązanie działało dla mnie. Możesz zobaczyć całą zawartość pliku, którą zrobiłem tutaj: http://pastebin.com/yMYQJ2jK

Definiuję również końcowy poziom powiększenia dla 1-7, abyś mógł zobaczyć swoje początkowe dane JSON po powrocie do początkowego poziomu powiększenia, w przeciwnym razie zostanie ono utracone i nigdy nie zostanie wywołane, dopóki nie przeładujesz strony!

RomaH
źródło
Dzięki. Nie zdawałem sobie sprawy, że przekazywanie zmiennych tworzy wystąpienia tymczasowe.
Josh
Tak, jedynym sposobem, aby zachować zmiany w sposób, w jaki robiłeś to byłoby przekazać to z powrotem z returnoświadczeniem. Używanie globals w javascript wydaje się powszechne, więc zrobienie tego w ten sposób będzie najłatwiejsze do wykonania.
RomaH
To ma sens. Niedawno przeczytałem w książce Best Practices, aby nie używać globali, ale najwyraźniej niewłaściwie użyłem alternatywy. Dzięki.
Josh
Najlepszą praktyką we wszystkich językach programowania jest nieużywanie globałów. Łatwiej jest śledzić błędy. Ale najlepsza praktyka jest jedynie regułą. Większość zastosowań javascript-in-page wydaje się na tyle lekka, że ​​można łatwo zarządzać efektami ubocznymi. Jeśli piszesz cały moduł lub zewnętrzny js, unikałbym globals.
RomaH
1

Ulotka ma strukturę danych typu kolekcja grup warstw, a także interfejs kontroli warstw, który można włączać i wyłączać po zakodowaniu go jako detektorów zdarzeń w polu wyboru.

Carl Carlson
źródło
1

Napisałem poniższy przykład, aby pokazać, jak usunąć wielokrotność warstwy 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();
Mercel Santos
źródło