Comment changer l'ordre des calques dans leaflet.js

10

Je voudrais pouvoir changer l'ordre des couches dans le dépliant.

J'ai essayé d'implémenter deux plugins de dépliants afin de changer l'ordre des couches.

D'abord, j'ai essayé les dépliants-control-orderlayers , ce qui semble fonctionner, mais ne prend pas en charge les groupes de couches, voici mon bug déposé .

Ensuite, j'ai essayé mapbbcode , qui prend en charge layerGroups, mais ne semble pas fonctionner ni être maintenu.

Quelqu'un a-t-il des suggestions pour implémenter cette fonctionnalité?

Bwyss
la source
Duplicata possible: stackoverflow.com/questions/12848812/…
rien n'est nécessaire

Réponses:

9

Vous pouvez le faire de deux manières (au moins, c'est comme ça que je le fais):

  1. layer.bringToFront()et layer.bringToBack()mais ceux-ci ne feront qu'une couche à la fois, et ne la pousseront que vers l'avant ou l'arrière, pas entre les deux. Vous devez donc placer vos calques dans l'ordre souhaité, commencer par le calque que vous souhaitez placer en bas et appeler layer.bringToFront()chaque calque.

  2. Vous pouvez également le faire en supprimant et en rajoutant le calque. Cela semble en quelque sorte un gaspillage, mais comme la carte doit de toute façon être redessinée lors du repositionnement des couches, ce n'est généralement pas si grave.

Voici un violon assez complexe qui illustre le problème

Fondamentalement, vous supprimez tous les calques, puis les ajoutez à nouveau dans l' z-indexordre croissant . Parcourez donc toutes vos couches de superposition, appelez map.removeLayer(layer), puis triez-les selon votre choix z-index, puis ajoutez-les à nouveau en utilisant layer.addTo(map).

rien n'est nécessaire
la source
1

J'avais le même problème et j'ai essayé la méthode fixZOrder (), mais malheureusement, cela n'a pas commandé les marqueurs Leaf pour moi car cela ne semble pas affecter le zindex des marqueurs Leaflet.

Il semble que .bringToFront () ne fonctionne que sur les formes vectorielles qui prennent en charge cette méthode, contrairement aux marqueurs Leaf que j'ai déployés rendant cette solution inapplicable, sans parler des autres problèmes de code que je rencontrais avec fixZOrder (), mais cela pourrait être unique à mon cas.

La

Au lieu de cela, j'ai simplement laissé l'ordre des couches à Leaflet (options) dans l'ordre dans lequel je les ai chargées, ce qui a causé des problèmes d'empilement de marqueurs (plug-in OMS Spiderf) lors de l'utilisation des contrôles de couche , mais j'ai réussi à les résoudre à l'aide de ma propre fonction basée sur setZIndexOffset ()

function myBring2Front() {
        //layer1.bringToFront();
        layer1.eachLayer(function (layer) {
          layer.setZIndexOffset(2000);
        });
        layer2.eachLayer(function (layer) {
          layer.setZIndexOffset(1000);
        });
    }

Bien que mon scénario n'ait pas exigé fixZOrder(layers)à la fin quiconque utilisant cette méthode avec des marqueurs empilés peut avoir besoin d'adopter une approche similaire et donc je poste cela comme une solution supplémentaire pour les utilisateurs potentiels de la méthode d'ordre des couches mentionnée ci-dessus.

La

CRÉDIT : ghybs répond sur stackoverflow.com/a/37850189/11106279

Michael B
la source
0

Semblable à la réponse de @nothingisnecessary, les utilisations suivantes permettent layer.bringToFront()de maintenir l'ordre z lorsque vous avez layer controlun chargement de données combiné et asynchrone.

nous ne voulons pas effacer les couches et les ajouter à la carte car cela ajoutera toutes les couches, mais nous voulons plutôt respecter les couches sélectionnées dans le contrôle des couches avec des frais généraux minimaux. bringToFront()peut le faire, mais nous devons l'appeler uniquement sur un groupe de calques contenant des calques (contenu).

Définissez les calques:

var dataLayers = {
    Districts: new L.geoJSON(),
    Farms: new L.featureGroup(),
    Paddocks: new L.geoJSON(),
    Surveys: new L.geoJSON()
};

L.control.layers(
    // base maps
    {
        OSM: L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', subdomains: ['a', 'b', 'c'] });,
    },
    dataLayers,
    {
        collapsed: false,
        hideSingleBase: true
    }).addTo(map);

Utilisez la fonction suivante pour appliquer l'ordre z:

/**
 * Ensure that layers are displayed in the correct Z-Order
 * Instead of explicitly defining z-order on the groups the order of the calls to beingToFront controls the resulting zOrder
 * @param {any} dataLayers Object that holds the references to the layer groups toggled by the layer control
 **/
function fixZOrder(dataLayers) {

    // only similar approach is to remove and re-add back to the map
    // use the order in the dataLayers object to define the z-order
    Object.keys(dataLayers).forEach(function (key) {

        // check if the layer has been added to the map, if it hasn't then do nothing
        // we only need to sort the layers that have visible data
        // Note: this is similar but faster than trying to use map.hasLayer()
        var layerGroup = dataLayers[key];
        if (layerGroup._layers
            && Object.keys(layerGroup._layers).length > 0
            && layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path
            && layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path.parentNode)
            layerGroup.bringToFront();
    });
}

Lorsque vous utilisez le contrôle des calques, lorsqu'un calque est basculé en vue, il sera au-dessus des autres calques, nous devons réappliquer la logique de commande lorsqu'un calque est ajouté. Cela peut être fait en se liant à l' overlayaddévénement sur la carte et en appelant la fixZOrderfonction:

map.on('overlayadd', function (e) {
    fixZOrder(dataLayers);
}

Si vous chargez vos données de manière asynchrone, vous devrez peut-être également appeler fixZOrderlorsque votre chargement de données sera terminé, les nouvelles couches ajoutées lors de l'exécution seront rendues par-dessus toutes les autres couches.

Chris Schaller
la source
0

Vous devez créer Panel pour contrôler la commande.

map.createPane('myPane1');
map.createPane('myPane2');
map.getPane('myPane1').style.zIndex = 400;
map.getPane('myPane2').style.zIndex = 800;

Avec cela, vous pouvez ajouter le calque au volet que vous souhaitez.

Jimmy Yshiy
la source