banner
陈不易

陈不易

没有技术想聊生活
twitter
medium
tg_channel

矢量タイルのハイライト選択 Openlayers[1]

自分が作成した小さなデモには、次のような小さな要件があります:データベースの検索を使用して、指定された属性のフィーチャを取得し、それをハイライト表示します。

WFS の通常の方法でロードする場合、問題はありません。layerfeature sourceを反復処理するだけで、効率を考慮せずにロジックは問題ありませんが、1 つの要件は、フィーチャの数が非常に多いことです(グローバル範囲の海岸線から生成されたバッファーゾーンです)。そのため、地図のロードプロセスでは、ベクトルタイルの形式を使用しています。ベクトルタイルタイプのsourceにはgetFeatures()メソッドがないため、ハイライト表示する必要のあるフィーチャを反復処理することは困難です。

レイヤーの静的スタイルは、最新のopenlayersの例の方法を使用して設定されます:

//カラーテーブル
const colorTable = {
  "No": "rgba(200, 54, 54, 0)",
  "type1": "#FF0000",
  "type2": "#E69800",
  ...
  "": "#00FFFFFF",
};
export function createRiskLevelStyle(feature) {

  const riskLevel = feature.get('props_X');
  let selected = !!selection[feature.getId()];
  return new Style({
    fill: new Fill({
      //color: colorTable[riskLevel],
      color: selected ? 'rgba(200,20,20,0.8)' : colorTable[riskLevel],
      //color: 
    }),
    stroke: new Stroke({
      color: '#FFFFFF',
      width: 0.1,
    })
  })
}

ここで、selectedはマウスクリックでのハイライト表示に使用され、ロジックは、クリック後にfeatureidをキーとして保存し、そのフィーチャが選択されたことを示します。

もちろん、この要件を考慮する際に、最初に思いついたのは、featureCollectionを反復処理し、対応するフィーチャのIdを見つけて、selectionグローバル変数に保存することでした。しかし、ベクトルタイルのsourceにはgetFeatures()メソッドがないため、このアイデアは破綻しました。その後、データ量が非常に大きいため、データを一度にロードすると 50 メガバイト以上になるため、データを反復処理するために通常の WFS レイヤーを新しく作成することさえ考えましたが、この方法も完全に破綻しました。

その後、ロード時にスタイルをこの形式のstyleFuncで使用できるので、検索時にレイヤーに新しいFuncを割り当てると効果的かどうか、パフォーマンスはどうかを考えました。そのため、styleFunを微調整した結果は次のようになります:

export function createRiskLevelStyleSearch(names) {
  return function (feature) {
    const riskLevel = feature.get('props_X');
    let properties = feature.getProperties();
    let zh = properties['label'];
    let en = properties['name'];
    let searched = false;
    if (zh === undefined || en === undefined) {
      searched = false;
    } else {
      names.forEach((v) => {
        if (en === v.key)
          searched = true;
      });
    }
    return new Style({
      fill: new Fill({
        //color: colorTable[riskLevel],
        color: searched ? 'rgba(200,20,20,0.8)' : colorTable[riskLevel],
        //color:
      }),
      stroke: new Stroke({
        color: '#FFFFFF',
        width: 0.1,
      })
    });
  }

}

パラメータnamesは国名の配列であり、itemkeyは検索する値に対応します。

この方法は、このデータ量ではまあまあの効果があります。以下はスクリーンショットです:

image

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。