Indeks Z w OpenLayers 3: kolejność warstw w OL3


13

Czy istnieje metoda zmiany indeksów Z warstw w OpenLayers3, tak jak w starej wersji?

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

Muszę zmienić kolejność warstw za pomocą mapy. Tak więc możliwość zdefiniowania takiego indeksu Z nie pomaga

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

    }
});

Mam problem z korzystaniem z tego rozwiązania, najprawdopodobniej z powodu mojego niezrozumienia takich rzeczy. czy możesz opublikować przykład wyniku? Wierzę, że to naprawdę by mi pomogło?
dave_does_not_understand

Odpowiedzi:


10

Wypróbuj coś takiego:

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

Lista warstw znajduje się w obiekcie dziedziczącym po ol.Collection. Zobacz dokument API dla tego.

Bądź ostrożny, jestem całkiem pewien, że nie możesz użyć dowolnej liczby, takiej jak 99 in setAt: pierwszy argument dotyczy pozycji w tablicy warstw, a drugi argument dotyczy odniesienia do elementu warstwy, który chcesz przenieść. Aby uzyskać liczbę warstw, wystarczy użyćmap.getLayers().getArray().length

Chociaż widzisz, że możemy uzyskać tablicę JS dla warstw, nie jestem pewien, aby manipulowanie tą tablicą bezpośrednio było najlepszym sposobem, ponieważ warstwy mogą mieć dołączone zdarzenia. Zamiast tego możesz użyć tych ol.Collectionmetod.


Szukałem rozwiązania dla nakładek, więc ja po prostu chciałem, aby dodać komentarz mówiący, że to (oczywiście) działa również dla nakładek, jak map.getOverlays()zwraca ol.Collectionpodobnie jak map.getLayers()robi.
decibyte

8

To nie jest tak proste, jak kiedyś, ale istnieją pewne metody pomocnicze dla kolekcji. To powinno pozwolić ci robić podobne rzeczy, jak ThomasG77 opisany powyżej.

Zakładając, że masz mapę o nazwie mapa, z 4 warstwami, tj. [Warstwa_podstawowa, linie brzegowe, mapa termiczna, znaczniki]

Następnie możesz pobrać kolekcję za pomocą map.getLayers (), a tablicę warstw za pomocą map.getLayers (). GetArray (), a poszczególne warstwy za pomocą

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

Możesz manipulować kolejnością warstw za pomocą metod zbierania. Prawdopodobnie pomoże stworzyć niektóre funkcje pomocnicze, takie jak:

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

Mam nadzieję, że masz możliwość zidentyfikowania swoich warstw i ich odnalezienia. Ustawiłem identyfikator tworzenia, taki jak layer.set („layer_id” 44), który można następnie pobrać przez layer.get („layer_id”). Następnie możesz utworzyć pętlę pomocniczą findLayer przez tablicę warstw i zwrócić indeks warstw.

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

W ten sposób mogę mieć coś takiego jak moveLayerBefore (map, findLayer (44), findLayer (22));

W każdym razie w kolekcji znajduje się mnóstwo metod, ale mam nadzieję, że to pomoże Ci zacząć. I przepraszam, jeśli w tym kodzie są błędy, to wszystko jest skompilowane w myślach ... :)


5

na podstawie odpowiedzi srussking napisałem następujący kod, zakładając, że główny obiekt mapy o nazwie mapa i jest to zmienna globalna, wolałem używać warstwy znajdowania według nazwy, a nie według identyfikatora,

oto mój kod:

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

Nie ma potrzeby obsługi indeksów w kolekcji za pośrednictwem setAt lub insertAt. Najprostszym sposobem jest użycie metody setZIndex na warstwie, jak w interfejsie API

geoLayer.setZIndex(999);

Problem polega na tym, że wydaje się, że działa tylko wtedy, gdy warstwy są już na mapie. Powiedzmy, że umieściłem dwie warstwy wektorowe bezpośrednio na mapie (jedna po drugiej, nie wszystkie naraz). Pierwszy ustawiłem na ZIndex 10, drugi na ZIndex 9. To nie działa. Drugi z ZIndexem 9 pojawi się nad ZIndexem 10.
kiradotee 24.01.2018

1

W moim przypadku odpowiedź ThomasG77 spowodowała AssertionError, ponieważ warstwa, którą miałem przenieść na górę, była już dołączona do mapy ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Rozwiązanie, które działało dla mnie:

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

(funkcja usuń zwraca usuniętą warstwę). Oneliner powinien również działać, ale go nie testowałem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.