コンテンツにスキップ

FeatureEvaluator

FeatureEvaluator は、地物データへのアクセスと、プロパティに基づいた地物の動的スタイリングを提供するクラスです。Layer の featureCreated および featureUpdated イベントを通じて取得できます。

このクラスを使用して以下のことができます:

  • データソースから地物プロパティを読み取る
  • プロパティに基づいて地物を動的にスタイリングする

Type: FeatureSetId

Description: このフィーチャーセットの一意な識別子を取得します。

Example:

layer.on("featureCreated", ({ evaluator }) => {
console.log("地物ID:", evaluator.id);
});
type FeatureInfo = {
batchId: number;
properties: Record<string, unknown> | undefined;
layerId: string | undefined;
};
type FeatureEvaluatorCallback = (
info: FeatureInfo,
) => Partial<EvaluatedValue>;

データソースからこの地物のプロパティを読み取ります。コールバックはこの地物内の各バッチに対して呼び出されます。

Syntax:

readFeatureProperties(
f: (info: FeatureInfo) => void
): void

Parameters:

  • f: 各バッチの FeatureInfo オブジェクトを受け取るコールバック関数

Example:

// すべてのプロパティをログ出力
evaluator.readFeatureProperties(({ batchId, properties }) => {
console.log(`バッチ ${batchId}:`, properties);
});
evaluator.readFeatureProperties(({ properties }) => {
const attributes = properties?.["attributes"] ?? {};
const minHeight = attributes["minHeight"];
const maxHeight = attributes["maxHeight"];
console.log("高さ範囲:", minHeight, "-", maxHeight);
});

データソースからこの地物の指定されたルートプロパティキーのみを読み取ります。少数のプロパティのみが必要な場合、readFeatureProperties() よりも効率的です。

Syntax:

readFilteredFeatureProperties(
keys: string[],
f: (info: FeatureInfo) => void
): void

Parameters:

  • keys: 読み取るルートプロパティキーの配列
  • f: フィルタリングされたプロパティのみを含む FeatureInfo オブジェクトを受け取るコールバック関数

Example:

evaluator.readFilteredFeatureProperties(["height", "name"], ({ batchId, properties }) => {
console.log(`バッチ ${batchId}: height=${properties?.["height"]}, name=${properties?.["name"]}`);
});

プロパティに基づいて地物に動的スタイルを評価・適用します。コールバックはこの地物内の各バッチ(サブ地物)に対して呼び出されます。

Syntax:

evaluate(
f: FeatureEvaluatorCallback,
options?: {
filters?: string[];
}
): void

Parameters:

  • f: FeatureInfo オブジェクトを受け取り、スタイル値を返すコールバック関数
  • options: オプションの設定
    • options.filters: 読み取るルートプロパティキーの配列。指定した場合、一致するプロパティのみがコールバックに渡され、大規模なデータセットでのパフォーマンスが向上します。

Returns:

コールバック関数は以下のプロパティを含むオブジェクトを返すことができます:

PropertyTypeDescription
colorColor地物の色(new Color() を使用)
showboolean地物の表示/非表示
heightnumber地物の高さ(メートル)
extrudedHeightnumberポリゴンの押し出し高さ(メートル)
textstringラベルテキストの内容(テキスト/ラベル地物用)
widthnumberライン幅(ピクセル、ポリライン地物用)
sizenumberポイント/テキストサイズ(メートルまたはピクセル、ポイント/テキスト地物用)
opacitynumber地物の不透明度、範囲 0.0-1.0(ポリゴン/ポイント/ビルボード/モデル/テキスト用)
declutterPrioritynumberデクラッターの配置優先度。値が大きいほど重なりの競合に勝ちます(declutter が有効なポイント/ビルボード/テキスト用)。レイヤーの declutterPriority を上書きします
imagestring | null画像の URL(ビルボード地物用)。個別の URL ごとに一度だけ読み込まれ、レイヤーのテクスチャアトラスにパックされます。null を返すと以前に設定した地物ごとの画像がクリアされ、ビルボードマテリアルのデフォルト url に戻ります(マテリアルに url がない場合、その地物は非表示になります)

Example:

import { Color } from "@navaramap/three";
// 3D Tiles の建物を高さで色分け
layer.on("featureUpdated", ({ evaluator }) => {
evaluator.evaluate(({ properties }) => {
const measuredHeight = properties?.["height"] as number;
const color = (() => {
if (measuredHeight < 30) return new Color().setStyle("#00ff00");
if (measuredHeight < 60) return new Color().setStyle("#ffff00");
if (measuredHeight < 90) return new Color().setStyle("#ff00ff");
return new Color().setStyle("#ff0000");
})();
return {
color,
show: measuredHeight >= 30, // 低い建物を非表示
};
});
});
// GeoJSON ポリゴンにプロパティベースの押し出しを適用
layer.on("featureUpdated", ({ evaluator }) => {
evaluator.evaluate(({ properties }) => {
const height = (properties?.["height"] as number) ?? 0;
const extrudedHeight = (properties?.["extrudedHeight"] as number) ?? 0;
return {
height,
extrudedHeight,
};
});
});
// MVT 地物をカテゴリプロパティで色分け
layer.on("featureUpdated", ({ evaluator }) => {
evaluator.evaluate(({ properties }) => {
const category = properties?.["category"] as string;
const color = (() => {
if (category === "A") return "#0000ff";
if (category === "B") return "#00ff00";
return "#ff0000";
})();
return {
color: new Color().setStyle(color),
};
});
});
// テキストラベルのフィルタリングとスタイリング
layer.on("featureUpdated", ({ evaluator }) => {
evaluator.evaluate(({ properties }) => {
const text = properties?.["name"] as string;
return {
text,
show: !!text,
};
});
});
// プロパティに基づいて地物ごとのビルボード画像を設定
layer.on("featureUpdated", ({ evaluator }) => {
evaluator.evaluate(
({ properties }) => {
const icon = properties?.["icon"] as string | undefined;
// icon を持たない地物にはビルボードマテリアルのデフォルト url が適用される。
// `image: null` は以前に設定した画像のクリアにもなる
return { image: icon ? `/icons/${icon}.svg` : null };
},
{ filters: ["icon"] },
);
});
// featureClick イベントで選択した地物をハイライト
let selectedId: string | undefined;
// クリックで地物を選択
view.on("featureClick", (info) => {
selectedId = info?.properties?.["id"] as string;
layer.forceUpdate(); // スタイルを再評価
});
// 選択状態に基づいて色を変更
layer.on("featureUpdated", ({ evaluator }) => {
evaluator.evaluate(({ properties }) => {
const id = properties?.["id"] as string;
return {
color: new Color().setHex(selectedId === id ? 0xff0000 : 0xffffff),
};
});
});

evaluate() コールバックから返すことができる型の定義:

type EvaluatedValue = {
/** 地物の色 */
color?: Color;
/** 地物の表示/非表示 */
show?: boolean;
/** ポリゴンの押し出し高さ(メートル) */
extrudedHeight?: number;
/** 地物の高さ(メートル) */
height?: number;
/** ラベルテキストの内容 */
text?: string;
/** ライン幅(ピクセル、ポリライン地物用) */
width?: number;
/** ポイント/テキストサイズ(メートルまたはピクセル、ポイント/テキスト地物用) */
size?: number;
/** 地物の不透明度、範囲 0.0-1.0(ポリゴン/ポイント/ビルボード/モデル/テキスト用) */
opacity?: number;
/** 画像の URL(ビルボード地物用)。個別の URL ごとに一度だけ読み込まれ、
* レイヤーのテクスチャアトラスにパックされます。`null` は以前に設定した
* 地物ごとの画像をクリアし、ビルボードマテリアルのデフォルト url に戻します */
image?: string | null;
};