自分で作った小さなデモにこんな小さな要件があります:データベースを通じて、指定された属性の要素を取得し、それをハイライト表示することです。
WFS の通常の方法で読み込む場合は問題ありませんが、layer
のfeature source
を遍歴するだけで済みます。効率は考慮せず、論理的には問題ありませんが、要件としてレイヤーのfeature
が非常に多い(世界中の海岸線から生成されたバッファーのため)ため、地図の読み込みの過程でベクタタイルの形式を使用しました。ベクタタイルタイプの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()
メソッドがないため、このアイデアは破綻しました。その後、データを遍歴するために普通の WFS レイヤーを新たに作成しようとも考えましたが、データ量が非常に大きく、一度の読み込みで 50MB 以上かかるため、この方法も完全に破綻しました。
その後、読み込み時にスタイルをこの形式の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
は検索する値に対応しています。
この方法はこのデータ量の下で、効果はまずまずです。以下の図のように: