Índice Z no OpenLayers 3: ordenação de camadas no OL3

13

Existe um método para alterar índices Z de camadas no OpenLayers3 como na versão antiga?

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

Preciso alterar a ordem das camadas usando um mapa. Portanto, essa possibilidade de definir o índice z como este não ajuda

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
fonte
Estou tendo problemas para usar esta solução, provavelmente devido à minha falta de compreensão dessas coisas. você pode por favor postar um exemplo do resultado, acredito que realmente me ajudaria?
Dave_does_not_understand

Respostas:

10

Tente algo como:

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

A lista de camadas está em um objeto herdado de um ol.Collection. Veja o documento da API para isso.

Tenha cuidado, tenho certeza, você não pode usar um número arbitrário como 99 in setAt: o primeiro argumento é para a posição na matriz de camadas e o segundo argumento é para a referência do elemento da camada que você deseja mover. Para obter o número de camadas, basta usarmap.getLayers().getArray().length

Embora você veja que podemos obter uma matriz JS para camadas, não tenho certeza de que manipular essa matriz diretamente é a melhor maneira, porque as camadas podem ter eventos anexados. Você pode usar os ol.Collectionmétodos.

ThomasG77
fonte
Eu estava procurando uma solução para sobreposições, então eu só queria adicionar um comentário dizendo que isso (é claro) também funciona para sobreposições, como map.getOverlays()retornos e ol.Collectionassim como map.getLayers()faz.
Decibyte
8

Não é tão fácil como costumava ser, mas existem alguns métodos auxiliares para a coleção. Isso deve permitir que você faça coisas semelhantes às descritas no ThomasG77 acima.

Supondo que você tenha um mapa chamado map, com 4 camadas, isto é [camada_ base, linhas costeiras, mapa de calor, marcadores]

Em seguida, você pode obter a coleção via map.getLayers () e a matriz de camadas via map.getLayers (). GetArray () e camadas individuais via

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

Você pode manipular a ordem das camadas através dos métodos de coleta. Provavelmente ajudará a criar algumas funções auxiliares como:

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

Espero que você tenha a capacidade de identificar suas camadas e encontrá-las, defino um ID na criação como layer.set ("layer_id" 44), que pode ser recuperado através de layer.get ("layer_id"). Em seguida, você pode fazer um loop auxiliar do findLayer pela matriz de camadas e retornar o índice da camada.

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

Dessa forma, posso ter algo como moveLayerBefore (map, findLayer (44), findLayer (22));

De qualquer forma, existem vários métodos na coleção, mas espero que isso ajude você a começar. E desculpe se há erros nesse código, isso é tudo compilado ... :)

srussking
fonte
5

com base na resposta srussking, escrevi o código a seguir, assumindo que o objeto principal do mapa é chamado map e é uma var global, preferi usar a camada de localização por nome e não por id,

aqui está o meu código:

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
fonte
1

Não há necessidade de manipular os índices na coleção via setAt ou insertAt. A maneira mais fácil é usar o método setZIndex na camada, como na API

geoLayer.setZIndex(999);
emiliegue
fonte
O mais complicado aqui é que parece funcionar apenas se as camadas já estiverem no mapa. Digamos, eu coloquei duas camadas de vetor diretamente no mapa (uma por uma, não todas de uma vez). Primeiro, defino para o ZIndex 10, depois para o ZIndex 9. Isso não funciona. O segundo com ZIndex 9 aparecerá acima ZIndex 10.
kiradotee
1

No meu caso, a resposta de ThomasG77 causou um AssertionError, porque a camada que eu estava prestes a mover para o topo já estava anexada ao mapa ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Solução que funcionou para mim:

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

(a função remove retorna a camada removida). O Oneliner também deve funcionar, mas não testei.

r34
fonte