Z-індекс у OpenLayers 3: упорядкування шарів в OL3


13

Чи існує метод зміни Z-індексів шарів у OpenLayers3, як це було у старій версії?

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

Мені потрібно змінювати порядок шарів протягом усього використання карти. Тож така можливість, як визначення z-індексу на кшталт цього, не допомагає

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

    }
});

У мене виникають проблеми з використанням цього рішення, швидше за все, через моє нерозуміння таких речей. Ви можете, будь ласка, опублікувати приклад результату, я вважаю, що це дійсно допоможе мені?
dave_does_not_understand

Відповіді:


10

Спробуйте щось на кшталт:

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

Список шарів знаходиться в об'єкті, успадкованому від ol.Collection. Див . Документ API для цього.

Будьте уважні, я впевнений, ви не можете використовувати довільне число, наприклад 99 setAtдюймів: перший аргумент - це позиція в масиві шарів, а другий аргумент - посилання на елемент шару, який ви хочете перемістити. Щоб отримати кількість шарів, просто використовуйтеmap.getLayers().getArray().length

Хоча ви бачите, що ми можемо отримати JS-масив для шарів, я не впевнений, що маніпулювання цим масивом є найкращим способом, оскільки шари можуть додавати події. Ви можете використовувати ol.Collectionметоди замість цього.


Я шукав рішення для накладок, тому просто хотів додати коментар, кажучи, що це (звичайно) також працює для накладок, оскільки map.getOverlays()повертає так ol.Collectionсамо, як map.getLayers()це робиться.
децибайт

8

Це не так просто, як раніше, але є кілька допоміжних методів колекції. Це повинно дозволяти вам робити подібні дії, як описано вище ThomasG77.

Припустимо, що у вас є карта з назвою на карті, що має 4 шари, тобто [базовий_шар, берегові лінії, теплова карта, маркери]

Тоді ви можете отримати колекцію через map.getLayers (), а масив шарів через map.getLayers (). GetArray () та окремі шари через

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

Ви можете маніпулювати порядком шарів за допомогою методів збору. Можливо, це допоможе створити деякі допоміжні функції, такі як:

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

Сподіваюся, у вас є можливість ідентифікувати ваші шари і знаходити їх, я встановив ідентифікатор на створення, подібний layer.set ("layer_id" 44), який потім можна отримати через layer.get ("layer_id"). Тоді ви можете мати помітну петлю findLayer через масив шарів і повернути індекс шару.

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

Таким чином я можу мати щось на кшталт moveLayerBefore (map, findLayer (44), findLayer (22));

У будь-якому випадку в колекції є маса методів, але, сподіваємось, це допоможе вам почати роботу. І вибачте, якщо в цьому коді є помилки, це все з розумом складено ... :)


5

на основі відповіді srussking я написав наступний код, припускаючи головний об'єкт map, який називається map, і це глобальний var, я вважав за краще використовувати шар пошуку за назвою, а не за id,

ось мій код:

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

Не потрібно обробляти індекси в колекції через setAt або insertAt. Найпростіший спосіб - використовувати метод setZIndex на шарі, як в API

geoLayer.setZIndex(999);

Тут складно, що це, здається, працює лише в тому випадку, якщо шари вже є на карті. Скажімо, я поклав два векторні шари прямо на карту (один за одним, не всі одразу). Перший я встановив на ZIndex 10, другий на ZIndex 9. Це не працює. Другий з ZIndex 9 з'явиться над ZIndex 10.
kiradotee

1

У моєму випадку відповідь ThomasG77 викликала таке AssertionError, тому що шар, який я збирався перенести на верх, вже був приєднаний до карти ( https://openlayers.org/en/v4.4.2/doc/errors/#58 ).

Рішення, яке працювало для мене:

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

(функція видалення повертає видалений шар). Oneliner також повинен працювати, але я цього не перевіряв.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.