Ajouter / supprimer des couches GeoJSON de dépliant

30

J'essaie d'afficher différentes couches GeoJSON à différentes couches de zoom à l'aide de l'API Leaflet. Je peux charger et afficher les trois couches à la fois (même si je ne veux pas qu'elles apparaissent toutes en même temps). Je peux les charger et les afficher à différents niveaux de zoom.

J'ai le code configuré de sorte qu'aux niveaux de zoom 1 à 6, la carte affiche une couche GeoJSON. Aux niveaux 7 à 10, il en affichera un autre et aux niveaux 11+, il en affichera un troisième. Les afficher fonctionne. Ce que j'essaye de faire maintenant, c'est de désactiver les autres si l'un d'eux est affiché. Passer de 1-6 à 7-10 fonctionne (ce qui signifie qu'il désactive correctement le calque 1-6), mais pas de 7-10 à 11+ (ce qui signifie que le calque 7-10 colle) et je ne peux pas comprendre pourquoi (il utilise le même code).

Voici l'ajax pour les couches 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);
});
}

Et voici la fonction principale qui appelle l'ajax en fonction du zoom. simpCounter est initialement défini sur 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;
    }
}
});

Encore une fois, la première transition désactive correctement l'ancien calque, mais pas la deuxième transition. Merci pour l'aide.

Josh
la source
Juste pour clarifier, il allume le json pour 11+ et ne s'éteint pas 7-10?
RomaH
C'est exact.
Josh

Réponses:

28

Essayez plutôt ceci:

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

Et pour votre fonction d'appel:

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

Lorsque vous passez les arguments map, geojsonLayeret defaultStyledans l'appel, getJson(defaultStyle, map, 60, geojsonLayer);vous créez de nouvelles instances des objets. Vous effectuez ensuite un travail sur les instances qui peuvent se refléter sur l'écran, mais une fois qu'il revient à la `` boucle principale '', il oublie essentiellement tout ce qu'il vient de faire et revient à l'état précédent.

Puisque je suppose que vous avez défini defaultStyle, mapet la geojsonLayerpopulation initiale dans la portée mondiale, vous n'avez qu'à les appeler, pas besoin de les transmettre. Avec les ajustements que j'ai faits, il change le global mappour que les changements persistent après la fin des appels de fonction.

Cette solution a fonctionné pour moi. Vous pouvez voir l'intégralité du contenu du fichier que j'ai créé ici: http://pastebin.com/yMYQJ2jK

Je définis également un niveau de zoom final pour 1-7 afin que vous puissiez voir vos données JSON initiales lorsque vous revenez au niveau de zoom initial, sinon elles sont perdues et ne sont jamais rappelées sauf si vous rechargez la page!

RomaH
la source
Merci. Je ne savais pas que le passage de variables crée des instances temporaires.
Josh
Oui, la seule façon de conserver les changements comme vous le feriez serait de les renvoyer avec une returndéclaration. L'utilisation de globaux en javascript semble courante, donc cette façon de procéder sera la plus simple pour terminer votre tâche.
RomaH
Ça a du sens. J'avais lu récemment dans un livre de bonnes pratiques pour ne pas utiliser les globaux, mais apparemment j'utilisais mal l'alternative. Merci.
Josh
Il est préférable dans tous les langages de programmation de ne pas utiliser les globaux, il est plus facile de suivre les bogues. Mais les meilleures pratiques ne sont qu'une règle d'or. La plupart des utilisations de javascript sur la page semblent suffisamment légères pour que les effets secondaires puissent être facilement gérés. Si vous écrivez un module entier ou des js externes, j'éviterais les globaux.
RomaH
1

La brochure a un type de structure de données de collection de groupes de couches et également une interface de contrôle de couche que vous pouvez activer et désactiver une fois que vous la codez en tant qu'écouteurs d'événements sur la case à cocher.

Carl Carlson
la source
1

J'ai écrit l'exemple ci-dessous pour montrer comment supprimer plusieurs couches 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
la source