OpenLayers 3のZ-index 3:OL3でのレイヤーの順序付け


13

古いバージョンのようにOpenLayers3のレイヤーのZ-indexを変更する方法はありますか?

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 14

回答:


10

次のようなものを試してください:

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

レイヤーのリストは、から継承するオブジェクトにありますol.CollectionAPIドキュメントを参照してください。

注意してください。99のような任意の数字は使用できませんsetAt。最初の引数はレイヤーの配列内の位置であり、2番目の引数は移動するレイヤー要素参照です。レイヤーの数を取得するには、単に使用しますmap.getLayers().getArray().length

レイヤーのJS配列を取得できることがわかりますが、レイヤーにイベントをアタッチできるため、この配列を直接操作することが最良の方法であるかどうかはわかりません。ol.Collection代わりにメソッドを使用できます。


オーバーレイのソリューションを探していたので、これは(もちろん)オーバーレイにも機能するというコメントを追加したかっmap.getOverlays()ol.Collectionだけmap.getLayers()です。
デシバイト

8

以前ほど簡単ではありませんが、コレクションにはいくつかのヘルパーメソッドがあります。これにより、上記のThomasG77と同様のことができるはずです。

mapという名前のマップがあり、4つのレイヤー、つまり[base_layer、coastlines、heatmap、markers]があるとします

次に、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)のような作成時にidを設定します。これは、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 answerに基づいて、mapと呼ばれるメインマップオブジェクトとそれがグローバル変数であると仮定して次のコードを書きました。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を介してコレクション内のインデックスを処理する必要はありません。最も簡単な方法は、APIのようにレイヤーでsetZIndexメソッドを使用することです

geoLayer.setZIndex(999);

ここで注意が必要なのは、レイヤーが既にマップ上にある場合にのみ機能するようです。たとえば、2つのベクターレイヤーをマップにまっすぐに配置します(一度にすべてではなく、1つずつ)。1つ目はZIndex 10に設定し、2つ目はZIndex 9に設定します。これは機能しません。ZIndex 9の2つ目はZIndex 10の上に表示されます。
kiradotee18年

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

(remove関数は削除されたレイヤーを返します)。Onelinerも動作するはずですが、テストしませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.