Closed5

【Leaflet】親Layerを探す

ややぎややぎ
  • L.Map.eachLayer()を使うと、全てのgroupレイヤーも,pathレイヤーも全て取得してしまう
  • groupレイヤーに所属しているpathレイヤーも取得される
ややぎややぎ

問題としては下記

  • もしmapに追加されているレイヤーを順繰り全部保持したいリストに入れる場合、複数回同じpathレイヤーが保存されてしまう事になる
    • pathレイヤー
    • pathレイヤーが所属しているgroupレイヤー1
    • pathレイヤーが所属しているgroupレイヤー2
ややぎややぎ

https://leafletjs.com/examples/extending/extending-1-classes.html
継承関係を見てみる。
Leafletにおいて、groupレイヤーとして扱われるものはL.LayerGroupを継承しているみたい。
またL.LayerGroupはhasLayer()という関数を持っている。
hasLayer()にレイヤーorレイヤーIDを渡すと、その渡したレイヤーがそのグループの子に属するか判別できる。

// boolean
group.hasLayer(childLayer);
ややぎややぎ
  1. map.eachLayer()で全レイヤー探索して、L.LayerGroupおよび、それを継承した型のレイヤーを全て保持する
const layerGroups = [];
map.eachLayer((layer)=>{
  // L.LayerGroup or L.FeatureGroup or L.GeoJson
  if( layer instanceof L.LayerGroup ) layerGroups.push(layer);
})
  1. もう一回map.eachLayer()で全探索する。今度は、L.LayerGroup以外の型を対象にする。1で取得したgroupにhasLayer()をかけて、そのレイヤーがgroupに所属しているか調べる。
  • L.DivOverlay
  • L.Path
  • L.GridLayer
  • etc...
const soloFeatures = [];

map.eachLayer((layer)=>{
  // groupじゃないレイヤーを対象にする
  if( !(layer instanceof L.LayerGroup) ){
    const parent = layerGroups.find((group)=>{
      return group.hasLayer(layer);
    })
    // 親がいない場合保持
    if(!parent) soloFeatures.push(layer);
  }
})
  1. groupに所属していなかったらそのレイヤーは単体のレイヤーということで、L.LayerGroupと同列に保持する
const parentLayers = [...layerGroups,...soloFeatures];
ややぎややぎ

大体こんな感じでいい気がした。
eachLayer()回しすぎなのが気になる。
ループの中で重い処理を入れないように気をつけたい。

このスクラップは2023/11/16にクローズされました