Добавление / удаление листов листов GeoJSON


30

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

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

Вот ajax для слоев 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);
});
}

А вот и основная функция, которая вызывает ajax в зависимости от масштаба. 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 кажется обычным делом, поэтому сделать это будет проще всего.
RomaH

В этом есть смысл. Недавно я читал в книге «Лучшие практики», чтобы не использовать глобальные переменные, но, очевидно, я неправильно использовал альтернативу. Спасибо.
Джош

На всех языках программирования рекомендуется не использовать глобальные переменные, легче отслеживать ошибки. Но лучшая практика - это только правило. Большинство вариантов использования 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.