Agregar / Eliminar capas de folleto GeoJSON

30

Estoy tratando de mostrar diferentes capas de GeoJSON en diferentes capas de zoom utilizando la API Leaflet. Puedo cargar y mostrar las tres capas a la vez (aunque en realidad no quiero que se muestren todas a la vez). Puedo cargarlos y mostrarlos en diferentes niveles de zoom.

Tengo el código configurado para que en los niveles de Zoom 1-6, el mapa muestre una capa GeoJSON. En los niveles 7-10, mostrará otro, y en los niveles 11+ mostrará un tercero. Mostrarlos funciona. Lo que estoy tratando de hacer funcionar ahora es apagar los otros si se muestra uno. Ir de 1-6 a 7-10 funciona (lo que significa que apaga la capa 1-6 correctamente), pero no de 7-10 a 11+ (lo que significa que la capa 7-10 se queda) y no puedo entender averiguar por qué (usa el mismo código).

Aquí está el ajax para las capas 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);
});
}

Y aquí está la función principal que llama al ajax dependiendo del zoom. simpCounter se establece en 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;
    }
}
});

De nuevo, la primera transición apaga la capa anterior correctamente, pero la segunda transición no. Gracias por la ayuda.

Josh
fuente
Solo para aclarar, ¿ESTÁ activando el json para 11+ y NO desactivando 7-10?
RomaH
Eso es correcto.
Josh

Respuestas:

28

Intenta esto en su lugar:

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

Y para su función de llamada:

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

Cuando estás pasando los argumentos map, geojsonLayery defaultStyleen la llamada getJson(defaultStyle, map, 60, geojsonLayer);va a crear nuevas instancias de los objetos. Luego, realiza el trabajo en las instancias que pueden reflejarse en la pantalla, pero una vez que vuelve al 'bucle principal', básicamente olvida todo lo que acaba de hacer y vuelve al estado anterior.

Como supongo que definió defaultStyle, mapy la geojsonLayerpoblación inicial en el ámbito global, solo tiene que llamarlos, no es necesario pasarlos. Con los ajustes que hice, cambia el global, mappor lo que los cambios persisten después de que finalizan las llamadas a funciones.

Esta solución funcionó para mí. Puede ver el contenido completo del archivo que hice aquí: http://pastebin.com/yMYQJ2jK

También defino un nivel de zoom final para 1-7 para que pueda ver sus datos JSON iniciales cuando regrese al nivel de zoom inicial, de lo contrario, se perderá y nunca se volverá a llamar a menos que vuelva a cargar la página.

RomaH
fuente
Gracias. No me di cuenta de que pasar variables crea instancias temporales.
Josh el
Sí, la única forma de mantener los cambios de la forma en que lo hacía sería pasarlos de regreso con una returndeclaración. El uso de globales en JavaScript parece común, por lo que hacerlo de esta manera será la forma más fácil de completar su tarea.
RomaH
Eso tiene sentido. Había leído recientemente en un libro de Mejores Prácticas para no usar globales, pero aparentemente estaba haciendo un mal uso de la alternativa. Gracias.
Josh
Es una buena práctica en todos los lenguajes de programación no usar globales, es más fácil rastrear errores. Pero la mejor práctica es solo una regla general. La mayoría de los usos de JavaScript en la página parecen lo suficientemente ligeros como para que los efectos secundarios se puedan gestionar fácilmente. Si está escribiendo un módulo completo o js externos, evitaría los globales.
RomaH
1

El folleto tiene un tipo de estructura de datos de colección de grupos de capas y también una interfaz de control de capas que puede activar y desactivar una vez que lo codifica como oyentes de eventos en la casilla de verificación.

Carl Carlson
fuente
1

Escribí el siguiente ejemplo para mostrar cómo eliminar capas múltiples de 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
fuente