リーフレットのレイヤーの順番を変更したいのですが。
レイヤーの順序を変更するために、2つのリーフレットプラグインを実装してみました。
最初に、機能しているように見えますが、layerGroupsをサポートしていないleaflet-control-orderlayersを試しました。これが私の提出されたバグです。
次に、layerGroupsをサポートするmapbbcode を試しましたが、動作しないか、維持されていないようです。
この機能を実装する方法について何か提案はありますか?
リーフレットのレイヤーの順番を変更したいのですが。
レイヤーの順序を変更するために、2つのリーフレットプラグインを実装してみました。
最初に、機能しているように見えますが、layerGroupsをサポートしていないleaflet-control-orderlayersを試しました。これが私の提出されたバグです。
次に、layerGroupsをサポートするmapbbcode を試しましたが、動作しないか、維持されていないようです。
この機能を実装する方法について何か提案はありますか?
回答:
あなたはこれをいくつかの方法で行うことができます(少なくとも、これは私が行う方法です):
layer.bringToFront()
そしてlayer.bringToBack()
、これらは一度に1つのレイヤーしか実行せず、それを前または後ろに押すだけで、中間ではありません。したがって、レイヤーを希望の順序に並べ、一番下にしたいレイヤーから始めて、layer.bringToFront()
各レイヤーを呼び出す必要があります。
レイヤーを削除して再度追加することによってもこれを行うことができます。これは少しもったいないようですが、とにかくレイヤーを再配置するときにマップを再描画する必要があるため、通常はそれほど大きな問題ではありません。
基本的には、すべてのレイヤーを削除してから、昇順に追加しますz-index
。したがって、すべてのオーバーレイレイヤーをループし、を呼び出してmap.removeLayer(layer)
、必要な順に並べ替えてから、z-index
を使用して再度追加しますlayer.addTo(map)
。
私は同じ問題を抱えていて、fixZOrder()メソッドを試しましたが、残念ながら、Leafletマーカーのzindexに影響を与えていないように見えるため、Leafマーカーを並べ替えませんでした。
.bringToFront()は、このメソッドをサポートするベクトル図形でのみ機能するようです、私が展開したリーフマーカーとは対照的に、このソリューションを実行不可能にレンダリングします。私の場合。
代わりに、レイヤーの順序をリーフレット(オプション)にロードした順序のままにしておいたため、レイヤーコントロールを使用するときにマーカースタッキング(OMS Spiderfプラグイン)で問題が発生しましたが、setZIndexOffset()
function myBring2Front() {
//layer1.bringToFront();
layer1.eachLayer(function (layer) {
layer.setZIndexOffset(2000);
});
layer2.eachLayer(function (layer) {
layer.setZIndexOffset(1000);
});
}
私のシナリオはなかったがいない必要がfixZOrder(layers)
最後に積み重ねられたマーカーと一緒に、このメソッドを使用して他の誰にも同様のアプローチを採用する必要があるかもしれないので、私はこれを掲示しています追加のソリューション上記の層注文方法の潜在的なユーザーのために。
クレジット:ghybsがstackoverflow.com/a/37850189/11106279で回答
@nothingisnecessaryからの回答と同様に、次の使用はlayer.bringToFront()
、layer control
データの非同期読み込みを組み合わせたときにzオーダーを維持するために使用します。
すべてのレイヤーが追加されるため、レイヤーをクリアしてマップに追加するのではなく、最小限のオーバーヘッドでレイヤーコントロールで選択したレイヤーを尊重します。
bringToFront()
これはできますが、レイヤー(コンテンツ)が含まれているレイヤーグループでのみ呼び出す必要があります。
レイヤーを定義します。
var dataLayers = {
Districts: new L.geoJSON(),
Farms: new L.featureGroup(),
Paddocks: new L.geoJSON(),
Surveys: new L.geoJSON()
};
L.control.layers(
// base maps
{
OSM: L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>', subdomains: ['a', 'b', 'c'] });,
},
dataLayers,
{
collapsed: false,
hideSingleBase: true
}).addTo(map);
次の関数を使用して、Zオーダーを適用します。
/**
* Ensure that layers are displayed in the correct Z-Order
* Instead of explicitly defining z-order on the groups the order of the calls to beingToFront controls the resulting zOrder
* @param {any} dataLayers Object that holds the references to the layer groups toggled by the layer control
**/
function fixZOrder(dataLayers) {
// only similar approach is to remove and re-add back to the map
// use the order in the dataLayers object to define the z-order
Object.keys(dataLayers).forEach(function (key) {
// check if the layer has been added to the map, if it hasn't then do nothing
// we only need to sort the layers that have visible data
// Note: this is similar but faster than trying to use map.hasLayer()
var layerGroup = dataLayers[key];
if (layerGroup._layers
&& Object.keys(layerGroup._layers).length > 0
&& layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path
&& layerGroup._layers[Object.keys(layerGroup._layers)[0]]._path.parentNode)
layerGroup.bringToFront();
});
}
レイヤーコントロールを使用する場合、レイヤーが表示に切り替わると、他のレイヤーの上に表示され、レイヤーが追加されたときに順序ロジックを再適用する必要があります。これはoverlayadd
、マップ上のイベントにバインドしてfixZOrder
関数を呼び出すことで実行できます。
map.on('overlayadd', function (e) {
fixZOrder(dataLayers);
}
データを非同期でロードする
fixZOrder
場合、データのロードが完了したときに呼び出す必要がある場合があります。実行時に追加された新しいレイヤーは、他のすべてのレイヤーの上にレンダリングされます。