Índice Z en OpenLayers 3: ordenamiento de capas en OL3


13

¿Hay algún método para cambiar los índices Z de las capas en OpenLayers3 como en la versión anterior?

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

Necesito cambiar el orden de las capas usando un mapa. Entonces, la posibilidad de definir un índice z como este no ayuda

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

    }
});

Tengo problemas para usar esta solución, probablemente debido a mi falta de comprensión de tales cosas. ¿Pueden publicar un ejemplo del resultado, creo que realmente me ayudaría?
dave_does_not_understand

Respuestas:


10

Intenta algo como:

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

La lista de capas está en un objeto que hereda de un ol.Collection. Vea el documento de API para ello.

Tenga cuidado, estoy bastante seguro, no puede usar un número arbitrario como 99 en setAt: el primer argumento es para la posición en la matriz de capas y el segundo argumento es para la referencia del elemento de capa que desea mover. Para obtener el número de capas, solo usemap.getLayers().getArray().length

Aunque puede ver que podemos obtener una matriz JS para capas, no estoy seguro de que manipular esta matriz directamente sea la mejor manera porque las capas pueden tener eventos adjuntos. Puedes usar los ol.Collectionmétodos en su lugar.


Estaba buscando una solución para las superposiciones, así que solo quería agregar un comentario que dijera que esto (por supuesto) también funciona para las superposiciones, ya que map.getOverlays()devuelve un me ol.Collectiongusta map.getLayers().
decibyte

8

No es tan fácil como solía ser, pero hay algunos métodos auxiliares para la colección. Eso debería permitirle hacer cosas similares a las que ThomasG77 describió anteriormente.

Suponiendo que tiene un mapa llamado mapa, con 4 capas, es decir, [capa_base, costas, mapa de calor, marcadores]

Luego puede obtener la colección a través de map.getLayers (), y la matriz de capas a través de map.getLayers (). GetArray (), y capas individuales a través de

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

Puede manipular el orden de las capas mediante los métodos de recopilación. Probablemente ayudará a crear algunas funciones auxiliares como:

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

Espero que tenga la capacidad de identificar sus capas y encontrarlas, configuré una identificación en la creación como layer.set ("layer_id" 44), que luego se puede recuperar a través de layer.get ("layer_id"). Entonces puede tener un bucle de ayuda findLayer a través de su matriz de capas y devolver el índice de capa.

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 esta manera puedo tener algo como moveLayerBefore (map, findLayer (44), findLayer (22));

De todos modos, hay una gran cantidad de métodos en la colección, pero espero que esto te ayude a comenzar. Y lo siento si hay errores en ese código, todo está compilado mentalmente ... :)


5

basado en la respuesta srussking, escribí el siguiente código asumiendo que el objeto del mapa principal se llama map y es una var global, preferí usar find layer por nombre y no por id,

Aquí está mi 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'));

1

No es necesario manejar los índices en la colección a través de setAt o insertAt. La forma más fácil es usar el método setZIndex en la capa como en la API

geoLayer.setZIndex(999);

Lo complicado aquí es que parece que solo funciona si las capas ya están en el mapa. Digamos que pongo dos capas vectoriales directamente en el mapa (una por una, no todas a la vez). El primero lo configuré en ZIndex 10, el segundo en ZIndex 9. Esto no funciona. El segundo con ZIndex 9 aparecerá sobre ZIndex 10.
kiradotee

1

En mi caso, la respuesta de ThomasG77 causó un AssertionError, porque la capa que estaba a punto de mover a la parte superior ya estaba adjunta al mapa ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Solución que funcionó para mí:

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

(la función remove devuelve la capa eliminada). Oneliner debería funcionar también, pero no lo probé.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.