Z-Index in OpenLayers 3: Ebenenreihenfolge in OL3

13

Gibt es eine Methode zum Ändern der Z-Indizes von Layern in OpenLayers3 wie in der alten Version?

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

Ich muss die Reihenfolge der Ebenen mithilfe einer Karte ändern. Eine solche Möglichkeit, wie z-index zu definieren, hilft also nicht

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
quelle
Ich habe Probleme bei der Verwendung dieser Lösung, wahrscheinlich aufgrund meines Unverständnisses für solche Dinge. Kannst du bitte ein Beispiel für das Ergebnis posten? Ich glaube, es würde mir wirklich helfen.
Dave_does_not_understand

Antworten:

10

Versuchen Sie etwas wie:

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

Die Liste der Ebenen befindet sich in einem Objekt, das von einem erbt ol.Collection. Siehe dazu das API-Dokument .

Seien Sie vorsichtig, ich bin mir ziemlich sicher, dass Sie keine beliebige Zahl wie 99 in verwenden können setAt: Das erste Argument steht für die Position im Array der Ebenen und das zweite Argument für die Ebenenelementreferenz, die Sie verschieben möchten. Um die Anzahl der Ebenen zu ermitteln, verwenden Sie einfachmap.getLayers().getArray().length

Obwohl Sie sehen, dass wir ein JS-Array für Layer erhalten können, bin ich mir nicht sicher, ob eine direkte Bearbeitung dieses Arrays der beste Weg ist, da an Layer Ereignisse angehängt werden können. Sie können ol.Collectionstattdessen die Methoden verwenden.

ThomasG77
quelle
Ich war für Overlays nach einer Lösung gesucht, so wollte ich nur einen Kommentar hinzufügen zu sagen , dass diese (natürlich) auch für Overlays funktioniert, wie map.getOverlays()kehrt ein ol.Collectionwiemap.getLayers() der Fall ist.
Dezibyte
8

Es ist nicht mehr so ​​einfach wie früher, aber es gibt einige Hilfsmethoden für die Sammlung. Das sollte es Ihnen ermöglichen, ähnliche Dinge wie oben beschrieben zu tun.

Angenommen, Sie haben eine Karte namens map mit 4 Layern, dh [base_layer, coastlines, heatmap, marker]

Anschließend können Sie die Auflistung über map.getLayers () und das Array von Layern über map.getLayers (). GetArray () und einzelne Layer über abrufen

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

Sie können die Ebenenreihenfolge über die Erfassungsmethoden ändern. Es wird wahrscheinlich helfen, einige Hilfsfunktionen zu erstellen, wie:

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

Hoffentlich haben Sie die Möglichkeit, Ihre Layer zu identifizieren und zu finden. Ich habe bei der Erstellung eine ID wie layer.set ("layer_id" 44) festgelegt, die dann über layer.get ("layer_id") abgerufen werden kann. Anschließend können Sie eine findLayer-Hilfsschleife durch Ihr Ebenenarray führen und den Ebenenindex zurückgeben.

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

Auf diese Weise kann ich so etwas wie moveLayerBefore (map, findLayer (44), findLayer (22)) haben;

Wie auch immer, es gibt eine Menge Methoden in der Sammlung, aber dies hilft Ihnen hoffentlich beim Einstieg. Und sorry, wenn es Fehler in diesem Code gibt, das ist alles, was der Verstand kompiliert hat ... :)

quatschend
quelle
5

Basierend auf der Antwort von srussking habe ich den folgenden Code unter der Annahme geschrieben, dass das Hauptkartenobjekt map heißt und es sich um eine globale Variable handelt.

Hier ist mein 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
quelle
1

Es ist nicht erforderlich, die Indizes in der Auflistung über setAt oder insertAt zu behandeln. Am einfachsten ist es, die setZIndex-Methode auf der Ebene wie in der API zu verwenden

geoLayer.setZIndex(999);
emiliegue
quelle
Das Knifflige dabei ist, dass es anscheinend nur funktioniert, wenn sich die Ebenen bereits auf der Karte befinden. Angenommen, ich habe zwei Vektorebenen direkt auf die Karte gelegt (eine nach der anderen, nicht alle auf einmal). Erstens habe ich ZIndex 10 eingestellt, zweitens ZIndex 9. Dies funktioniert nicht. Die zweite mit ZIndex 9 wird über ZIndex 10 angezeigt.
kiradotee
1

In meinem Fall verursachte die Antwort von ThomasG77 einen Fehler AssertionError, da der Layer, den ich gerade nach oben verschieben wollte, bereits an die Karte angehängt war ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Lösung, die bei mir funktioniert hat:

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

(Die Funktion remove gibt die entfernte Ebene zurück.) Oneliner sollte auch funktionieren, aber ich habe es nicht getestet.

r34
quelle