Z-index dalam OpenLayers 3: pemesanan lapisan dalam OL3


13

Apakah ada metode untuk mengubah indeks-Z lapisan di OpenLayers3 seperti di versi lama?

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

Saya perlu mengubah urutan lapisan menggunakan peta. Jadi kemungkinan mendefinisikan z-index seperti ini tidak membantu

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

    }
});

Saya mengalami masalah dalam menggunakan solusi ini, kemungkinan besar karena kurangnya pemahaman saya tentang hal-hal seperti itu. dapatkah Anda memposting contoh hasilnya, saya yakin itu akan sangat membantu saya?
dave_does_not_understand

Jawaban:


10

Coba sesuatu seperti:

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

Daftar lapisan dalam objek yang diwarisi dari ol.Collection. Lihat dokumen API untuk itu.

Hati-hati, saya cukup yakin, Anda tidak dapat menggunakan angka arbitrer seperti 99 in setAt: arg pertama untuk posisi dalam array lapisan dan argumen kedua adalah untuk referensi elemen layer yang ingin Anda pindahkan. Untuk mendapatkan jumlah layer, gunakan sajamap.getLayers().getArray().length

Meskipun Anda melihat kita bisa mendapatkan array JS untuk lapisan, saya tidak yakin memanipulasi array ini secara langsung adalah cara terbaik karena lapisan dapat memiliki acara terlampir. Anda dapat menggunakan ol.Collectionmetode sebagai gantinya.


Saya sedang mencari solusi untuk overlay, jadi saya hanya ingin menambahkan komentar yang mengatakan bahwa ini (tentu saja) juga berfungsi untuk overlay, seperti map.getOverlays()mengembalikan ol.Collectionseperti yang map.getLayers()dilakukan.
Decibyte

8

Ini tidak semudah dulu, tetapi ada beberapa metode pembantu untuk koleksi. Itu akan memungkinkan Anda untuk melakukan hal-hal serupa seperti ThomasG77 yang dijelaskan di atas.

Dengan asumsi Anda memiliki peta bernama peta, dengan 4 lapisan yaitu [base_layer, garis pantai, peta panas, spidol]

Kemudian Anda bisa mendapatkan koleksi melalui map.getLayers (), dan array lapisan melalui map.getLayers (). GetArray (), dan masing-masing layer melalui

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

Anda dapat memanipulasi urutan lapisan melalui metode pengumpulan. Mungkin akan membantu untuk membuat beberapa fungsi pembantu seperti:

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

Semoga Anda memiliki kemampuan untuk mengidentifikasi lapisan Anda dan menemukan mereka, saya menetapkan id pada pembuatan seperti layer.set ("layer_id" 44), yang kemudian dapat diambil melalui layer.get ("layer_id"). Kemudian Anda dapat memiliki loop helper findLayer melalui array lapisan Anda dan mengembalikan indeks lapisan.

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

Dengan cara ini saya dapat memiliki sesuatu seperti moveLayerBefore (peta, findLayer (44), findLayer (22));

Bagaimanapun, ada banyak metode dalam koleksi, tetapi mudah-mudahan ini membantu Anda memulai. Dan maaf jika ada bug dalam kode itu, itu semua dikompilasi pikiran ... :)


5

berdasarkan jawaban srussking saya menulis kode berikut dengan asumsi objek peta utama yang disebut peta dan itu adalah global var, saya lebih suka menggunakan find layer dengan nama dan bukan oleh id,

ini kode saya:

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

Tidak perlu menangani indeks dalam koleksi melalui setAt atau insertAt. Cara termudah adalah dengan menggunakan metode setZIndex pada lapisan seperti pada API

geoLayer.setZIndex(999);

Yang sulit di sini adalah tampaknya hanya berfungsi jika lapisan sudah ada di peta. Katakanlah, saya meletakkan dua layer vektor langsung ke peta (satu per satu, tidak semuanya sekaligus). Pertama saya atur ke ZIndex 10, yang kedua ke ZIndex 9. Ini tidak berhasil. Yang kedua dengan ZIndex 9 akan muncul di atas ZIndex 10.
Kiradotee

1

Dalam kasus saya, jawaban ThomasG77 menyebabkan AssertionError, karena lapisan yang akan saya pindahkan ke atas sudah terlampir pada peta ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Solusi yang berhasil untuk saya:

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

(fungsi hapus mengembalikan lapisan yang dihapus). Oneliner juga bisa digunakan, tetapi saya tidak mengujinya.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.