自分が作成した小さなデモには、次のような小さな要件があります:データベースの検索を使用して、指定された属性のフィーチャを取得し、それをハイライト表示します。
WFS の通常の方法でロードする場合、問題はありません。layer
のfeature 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
はマウスクリックでのハイライト表示に使用され、ロジックは、クリック後にfeature
のid
をキーとして保存し、そのフィーチャが選択されたことを示します。
もちろん、この要件を考慮する際に、最初に思いついたのは、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
は国名の配列であり、item
のkey
は検索する値に対応します。
この方法は、このデータ量ではまあまあの効果があります。以下はスクリーンショットです: