Z-index in OpenLayers 3: ordinamento dei layer in OL3


13

Esiste un metodo per modificare gli indici Z dei layer in OpenLayers3 come nella vecchia versione?

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

Devo cambiare l'ordine dei livelli usando una mappa. Quindi la possibilità di definire z-index come questa non aiuta

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

    }
});

Sto riscontrando problemi nell'uso di questa soluzione, molto probabilmente a causa della mia mancanza di comprensione di tali cose. puoi per favore pubblicare un esempio del risultato, credo che mi aiuterebbe davvero?
dave_does_not_understand,

Risposte:


10

Prova qualcosa del tipo:

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

L'elenco dei livelli si trova in un oggetto che eredita da un ol.Collection. Vedi il documento API per questo.

Fai attenzione, sono abbastanza sicuro, non puoi usare un numero arbitrario come 99 in setAt: il primo argomento è per la posizione nella matrice dei livelli e il secondo argomento è per il riferimento dell'elemento del livello che vuoi spostare. Per ottenere il numero di livelli, basta usaremap.getLayers().getArray().length

Anche se vedi che possiamo ottenere un array JS per layer, non sono sicuro che manipolare direttamente questo array sia il modo migliore perché i layer possono avere eventi collegati. Puoi ol.Collectioninvece usare i metodi.


Stavo cercando una soluzione per le sovrapposizioni, quindi volevo solo aggiungere un commento dicendo che questo (ovviamente) funziona anche per le sovrapposizioni, come map.getOverlays()restituisce ol.Collectionesattamente come map.getLayers().
decibita il

8

Non è facile come una volta, ma ci sono alcuni metodi di supporto per la raccolta. Ciò dovrebbe consentirti di fare cose simili a quelle descritte in precedenza da ThomasG77.

Supponendo di avere una mappa denominata mappa, con 4 livelli, cioè [base_layer, coste, heatmap, marker]

Quindi puoi ottenere la raccolta tramite map.getLayers () e l'array di livelli tramite map.getLayers (). GetArray () e singoli livelli tramite

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

È possibile manipolare l'ordine dei livelli tramite i metodi di raccolta. Probabilmente aiuterà a creare alcune funzioni di supporto come:

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

Spero che tu abbia la possibilità di identificare i tuoi livelli e trovarli, ho impostato un id sulla creazione come layer.set ("layer_id" 44), che può quindi essere recuperato tramite layer.get ("layer_id"). Quindi puoi avere un loop helper findLayer attraverso l'array di layer e restituire l'indice di layer.

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

In questo modo posso avere qualcosa come moveLayerBefore (map, findLayer (44), findLayer (22));

Comunque, ci sono molti metodi nella collezione, ma spero che questo ti aiuti a iniziare. E scusate se ci sono bug in quel codice, è tutto compilato mentalmente ... :)


5

in base alla risposta srussking ho scritto il seguente codice assumendo l'oggetto principale della mappa chiamato map ed è un var globale, ho preferito usare il livello find per nome e non per id,

ecco il mio codice:

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

1

Non è necessario gestire gli indici nella raccolta tramite setAt o insertAt. Il modo più semplice è utilizzare il metodo setZIndex sul layer come nell'API

geoLayer.setZIndex(999);

La cosa difficile qui è che sembra funzionare solo se i livelli sono già sulla mappa. Dì, ho messo due livelli vettoriali direttamente sulla mappa (uno per uno, non tutti in una volta). Il primo che ho impostato su ZIndex 10, il secondo su ZIndex 9. Questo non funziona. Il secondo con ZIndex 9 apparirà sopra ZIndex 10.
kiradotee,

1

Nel mio caso la risposta di ThomasG77 ha causato un AssertionError, perché il livello che stavo per spostare in alto era già collegato alla mappa ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Soluzione che ha funzionato per me:

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

(la funzione di rimozione restituisce il livello rimosso). Anche Oneliner dovrebbe funzionare, ma non l'ho provato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.