OpenLayers 3中的Z索引:OL3中的图层排序


13

是否像旧版本一样,可以在OpenLayers3中更改图层的Z索引?

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

我需要在整个地图中更改图层顺序。所以像这样定义z-index的可能性没有帮助

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 2014年

Answers:


10

尝试类似的东西:

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

图层列表位于继承自的对象中ol.Collection。请参阅API文档

请注意,我很确定,您不能在99中使用任意数字setAt:第一个arg用于表示图层数组中的位置,第二个arg用于要移动的图层元素引用。要获取层数,只需使用map.getLayers().getArray().length

尽管您看到我们可以为图层获取一个JS数组,但我不确定直接操作此数组是否是最佳方法,因为图层可以附加事件。您可以改用这些ol.Collection方法。


我一直在寻找叠加层的解决方案,所以我只想添加一条评论,说(当然)这也适用于叠加层,就像map.getOverlays()返回ol.Collection一样map.getLayers()
十进制

8

它不像以前那样容易,但是有一些用于收集的帮助方法。那应该允许您做与上述ThomasG77类似的事情。

假设您有一个名为map的地图,有4层,即[base_layer,海岸线,热图,标记]

然后,您可以通过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);
}

希望您有能力识别您的图层并找到它们,我在创建时设置了一个ID,例如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,并且它是一个全局变量,我更喜欢按名称而不是ID使用find层,

这是我的代码:

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处理集合中的索引。最简单的方法是像API一样在图层上使用setZIndex方法

geoLayer.setZIndex(999);

棘手的是,这似乎只有在图层已经在地图上时才起作用。说,我将两个矢量层直接放在地图上(一个接一个,不是一次全部)。我将第一个设置为ZIndex 10,第二个设置为ZIndex9。这不起作用。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也应该工作,但我没有对其进行测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.