Index Z dans OpenLayers 3: ordre des couches dans OL3

13

Existe-t-il une méthode pour modifier les index Z des couches dans OpenLayers3 comme c'était le cas dans l'ancienne version?

map.setLayerIndex(markers, 99); //set the marker layer to an arbitrarily high layer index

J'ai besoin de changer l'ordre des couches à travers une carte. Donc, une telle possibilité de définir un z-index comme celui-ci n'aide

var geoLayer = new ol.layer.Vector({
    source : new ol.source.GeoJSON({
        projection : 'EPSG:900913',
        url : './myGeoJson.json'
    }),
    style : function(feature, resolution) {
        var text = resolution < 5000 ? feature.get('name') : '';
        if (!styleCache[text]) {
            styleCache[text] = [new ol.style.Style({
                fill : new ol.style.Fill({
                    color : 'rgba(255, 255, 255, 0.1)'
                }),
                stroke : new ol.style.Stroke({
                    color : '#319FD3',
                    width : 1
                }),
                text : new ol.style.Text({
                    font : '12px Calibri,sans-serif',
                    text : text,
                    fill : new ol.style.Fill({
                        color : '#000'
                    }),
                    stroke : new ol.style.Stroke({
                        color : '#fff',
                        width : 3
                    })
                }),
                zIndex : 999
            })];
        }

    }
});
Anuket
la source
J'ai du mal à utiliser cette solution, probablement en raison de mon manque de compréhension de ces choses. pouvez-vous s'il vous plaît poster un exemple du résultat, je crois que cela m'aiderait vraiment?
dave_does_not_understand

Réponses:

10

Essayez quelque chose comme:

map.getLayers().setAt(99, markers)

La liste des calques se trouve dans un objet héritant d'un ol.Collection. Voir le doc API pour cela.

Attention, je suis sûr que vous ne pouvez pas utiliser de nombre arbitraire comme 99 dans setAt: le premier argument est pour la position dans le tableau des couches et le second argument est pour la référence d'élément de couche que vous souhaitez déplacer. Pour obtenir le nombre de couches, utilisez simplementmap.getLayers().getArray().length

Bien que vous voyiez que nous pouvons obtenir un tableau JS pour les couches, je ne suis pas sûr que la manipulation directe de ce tableau soit la meilleure façon car les couches peuvent avoir des événements attachés. Vous pouvez utiliser les ol.Collectionméthodes à la place.

ThomasG77
la source
Je cherchais une solution pour les superpositions, donc je voulais juste ajouter un commentaire disant que cela (bien sûr) fonctionne également pour les superpositions, comme le map.getOverlays()renvoie un ol.Collectiontout comme le map.getLayers()fait.
décibyte
8

Ce n'est plus aussi simple qu'avant, mais il existe des méthodes d'assistance pour la collecte. Cela devrait vous permettre de faire des choses similaires à celles décrites par ThomasG77 ci-dessus.

En supposant que vous avez une carte nommée carte, avec 4 couches, c'est-à-dire [couche_base, côtes, carte thermique, marqueurs]

Ensuite, vous pouvez obtenir la collection via map.getLayers (), et le tableau de couches via map.getLayers (). GetArray (), et les couches individuelles via

var heatmap = map.getLayers().getArray()[2]

Vous pouvez manipuler l'ordre des couches via les méthodes de collecte. Cela aidera probablement à créer des fonctions d'assistance comme:

function moveLayerBefore(map, old_idx, new_idx){
  var layer = map.getLayers().removeAt(old_idx);
  map.getLayers().insertAt(new_idx, layer);
}

J'espère que vous avez la possibilité d'identifier vos calques et de les trouver, j'ai défini un identifiant lors de la création comme layer.set ("layer_id" 44), qui peut ensuite être récupéré via layer.get ("layer_id"). Ensuite, vous pouvez avoir une boucle d'aide findLayer dans votre tableau de couches et renvoyer l'index de couche.

function findLayer(map, layer_id){
  var layer_idx = -1;
  $.each(map.getLayers().getArray(), function (k,v){
    var this_layer_id = v.get("layer_id")
    if(this_layer_id == layer_id){
      layer_idx = k;
    }
  });
  return layer_idx;
}   

De cette façon, je peux avoir quelque chose comme moveLayerBefore (map, findLayer (44), findLayer (22));

Quoi qu'il en soit, il existe une tonne de méthodes dans la collection, mais j'espère que cela vous aidera à démarrer. Et désolé s'il y a des bugs dans ce code, c'est tout l'esprit compilé ... :)

srussking
la source
5

sur la base de la réponse srussking, j'ai écrit le code suivant en supposant que l'objet principal de la carte appelé map et qu'il s'agit d'une variable globale, j'ai préféré utiliser la couche de recherche par nom et non par id,

voici mon code:

function moveLayerBefore(old_idx, new_idx){
    if((old_idx === -1) || (new_idx === -1)){
        return false;
    }

    layer = map.getLayers().removeAt(old_idx);
    map.getLayers().insertAt(new_idx, layer);
}

function findLayer(layer_name){
    var layer_idx = -1;
    $.each(map.getLayers().getArray(), function (k,v){
        var this_layer_name = v.get('name');
        if(this_layer_name == layer_name){
            layer_idx = k;
        }
    });

    return layer_idx;
}

// set name1 before name2
moveLayerBefore(findLayer('name1'),findLayer('name2'));
talsibony
la source
1

Pas besoin de gérer les index de la collection via setAt ou insertAt. La façon la plus simple est d'utiliser la méthode setZIndex sur la couche comme dans l' API

geoLayer.setZIndex(999);
Emiliegue
la source
La chose délicate ici est que cela ne semble fonctionner que si les couches sont déjà sur la carte. Disons que j'ai placé deux couches vectorielles directement sur la carte (une par une, pas toutes à la fois). Le premier que j'ai réglé sur ZIndex 10, le second sur ZIndex 9. Cela ne fonctionne pas. Le deuxième avec ZIndex 9 apparaîtra au-dessus de ZIndex 10.
kiradotee
1

Dans mon cas, la réponse de ThomasG77 a provoqué un AssertionError, car la couche que j'étais sur le point de déplacer vers le haut était déjà attachée à la carte ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Solution qui a fonctionné pour moi:

    let layers = map.getLayers();
    let markerTemp = layers.remove(refToMarkerLayer);
    layers.push(markerTemp);

(la fonction de suppression renvoie le calque supprimé). Oneliner devrait également fonctionner, mais je ne l'ai pas testé.

r34
la source