Adicionando / removendo camadas de folheto GeoJSON

30

Estou tentando mostrar diferentes camadas GeoJSON em diferentes camadas de zoom usando a API do Leaflet. Posso carregar e exibir todas as três camadas ao mesmo tempo (embora na verdade não queira que todas sejam exibidas de uma vez). Posso carregá-los e exibi-los em diferentes níveis de zoom.

Eu tenho o código configurado para que, nos níveis de zoom 1 a 6, o mapa mostre uma camada GeoJSON. Nos níveis 7-10, ele mostrará outro, e nos níveis 11+, mostrará um terceiro. Exibi-los funciona. O que estou tentando começar a trabalhar agora é desativar os outros se um for exibido. Passar de 1-6 a 7-10 funciona (o que significa que desativa a camada 1-6 corretamente), mas não de 7-10 a 11+ (o que significa que a camada 7-10 fica por aqui) e não consigo entender por que (ele usa o mesmo código).

Aqui está o ajax para as camadas 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);
});
}

E aqui está a principal função que chama o ajax, dependendo do zoom. simpCounter é definido como 0 inicialmente.

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

Então, novamente, a primeira transição desliga a camada antiga corretamente, mas a segunda transição não. Obrigado pela ajuda.

Josh
fonte
Só para esclarecer, está ligando o json para 11+ e NÃO desativando 7-10?
RomaH 23/11/12
Está correto.
28412 Josh

Respostas:

28

Tente isso:

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 para a sua função de chamada:

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 você está passando os argumentos map, geojsonLayere defaultStylena chamada getJson(defaultStyle, map, 60, geojsonLayer);que está a criar novas instâncias de objetos. Em seguida, você executa o trabalho nas instâncias que podem refletir na tela, mas quando volta ao 'loop principal', basicamente esquece tudo o que acabou de fazer e retorna ao estado anterior.

Desde que suponho que você definiu defaultStyle, mape a geojsonLayerpopulação inicial no escopo global, você apenas precisa chamá-los, não há necessidade de ignorá-los. Com os ajustes que fiz, mudou o global, de mapmodo que as alterações persistem após o término das chamadas de função.

Esta solução funcionou para mim. Você pode ver todo o conteúdo do arquivo que criei aqui: http://pastebin.com/yMYQJ2jK

Também defino um nível de zoom final para 1-7, para que você possa ver os dados JSON iniciais quando retornar ao nível de zoom inicial; caso contrário, eles serão perdidos e nunca serão chamados de volta, a menos que você recarregue a página!

RomaH
fonte
Obrigado. Não percebi que a passagem de variáveis ​​cria instâncias temporárias.
26412 Josh
Sim, a única maneira de manter as mudanças do jeito que você estava fazendo seria devolvê-lo com uma returndeclaração. O uso de globals em javascript parece comum, portanto, dessa maneira, será mais fácil concluir sua tarefa.
RomaH
Isso faz sentido. Eu tinha lido recentemente em um livro de práticas recomendadas para não usar globals, mas aparentemente estava usando mal a alternativa. Obrigado.
28412 Josh
É uma prática recomendada em todas as linguagens de programação não usar globais, é mais fácil rastrear bugs. Mas as melhores práticas são apenas uma regra de ouro. A maioria dos usos de javascript na página parece leve o suficiente para que os efeitos colaterais possam ser gerenciados com facilidade. Se você estiver escrevendo um módulo inteiro ou js externos, eu evitaria globais.
RomaH 26/11/12
1

O folheto possui um tipo de estrutura de dados de coleta de grupos de camadas e também uma interface de controle de camadas que você pode ativar e desativar depois de codificá-lo como ouvintes de eventos na caixa de seleção.

Carl Carlson
fonte
1

Eu escrevi o exemplo abaixo para mostrar como remover múltiplos geoJSON layer.

///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
fonte