Додавання / вилучення шарів GeoJSON листівки


30

Я намагаюся показувати різні шари GeoJSON на різних шарах збільшення за допомогою API Leaflet. Я можу завантажувати та показувати всі три шари одночасно (хоча я насправді не хочу, щоб вони відображалися одразу). Я можу завантажувати та показувати їх на різних рівнях збільшення.

У мене встановлений код, щоб на рівнях масштабування 1-6 на карті відображався один шар GeoJSON. На рівнях 7-10 він покаже інший, а на рівнях 11+ - третій. Показ їх працює. Те, що я намагаюся зараз працювати, - це вимкнення інших, якщо один відображається. Перехід від 1-6 до 7-10 працює (це означає, що він вимикає шари 1-6 правильно), але не від 7-10 до 11+ (це означає, що шар 7-10 тримається навколо), і я не можу зрозуміти чому (він використовує той самий код).

Ось аякс для шарів 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);
});
}

І ось основна функція, яка викликає аякс залежно від масштабування. simpCounter встановлюється спочатку 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;
    }
}
});

Отже, перший перехід вимикає старий шар правильно, але другий перехід не робить. Дякую за допомогу.


Просто для уточнення, це ВКЛЮЧЕННЯ json для 11+, а НЕ відключення 7-10?
RomaH

Це правильно.
Джош

Відповіді:


28

Спробуйте це замість цього:

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

А для функції дзвінка:

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

Коли ви передаєте аргументи map, geojsonLayerі defaultStyleу виклику getJson(defaultStyle, map, 60, geojsonLayer);ви створюєте нові екземпляри об'єктів. Потім ви виконуєте роботу над екземплярами, які можуть відображатись на екрані, але як тільки він повертається до "головної петлі", він, як правило, забуває все, що тільки зробив, і повертається до попереднього стану.

Оскільки я здогадуюсь, що ви визначили defaultStyle, mapі початкову geojsonLayerсукупність у глобальному масштабі ви просто повинні їх називати, не потрібно їх передавати. Завдяки внесеним налаштуванням він змінився глобальним, mapтому зміни зберігаються після закінчення викликів функції.

Це рішення працювало на мене. Ви можете побачити весь вміст файлу, який я створив тут: http://pastebin.com/yMYQJ2jK

Я також визначаю кінцевий рівень масштабування для 1-7, щоб ви могли бачити вихідні дані JSON, коли повернетесь до початкового рівня збільшення, інакше вони втрачаються і ніколи не передзвонюються, якщо ви не перезавантажуєте сторінку!


Спасибі. Я не усвідомлював, що передача змінних створює тимчасові екземпляри.
Джош

Так, єдиним способом зберегти зміни, які ви робили, було б передати їх назад із returnзаявою. Використання глобальних мереж у JavaScript видається загальним, тому виконати цей спосіб буде найпростішим для виконання вашого завдання.
Рома

Що має сенс. Нещодавно я читав у книзі «Кращі практики», щоб не використовувати глобалі, але, мабуть, я неправильно використовував альтернативу. Спасибі.
Джош

Найкраще в усіх мовах програмування не застосовувати глобальних даних. Простіше відстежувати помилки. Але найкраща практика - це лише правило. Більшість застосувань JavaScript на сторінці здаються досить легкими, щоб побічними ефектами можна було легко керувати. Якщо ви пишете цілий модуль або зовнішній js, я б уникав глобальних.
RomaH

1

листівка має тип структури даних колекції шарів шарів, а також інтерфейс управління шаром, який можна включати та вимикати, як тільки ви кодуєте його як слухачів подій у прапорець.


1

Я написав нижченаведений приклад, щоб показати, як видалити декілька шарів 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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.