Cesiumによるエンティティ操作とプリミティブ描画の高度な活用法

エンティティの生成と管理

CesiumJSにおいて、Entity APIを使用してシーン上にオブジェクトを追加および管理する基本的な手法は以下の通りです。このAPIは、位置や形状などのプロパティを直感的に定義できるため、データの可視化に広く利用されています。

// シーンにポイントエンティティを追加する関数
function createMarkerEntity() {
    const initialPosition = Cesium.Cartesian3.fromDegrees(135.0, 35.0);

    const marker = viewer.entities.add({
        id: 'primary_marker',
        position: initialPosition,
        point: {
            pixelSize: 12,                // ピクセルサイズ
            color: Cesium.Color.CYAN,    // 塗りつぶしの色(Cesium.Colorを使用)
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 4,
            disableDepthTestDistance: Number.POSITIVE_INFINITY
        }
    });
    
    return marker;
}

const activeEntity = createMarkerEntity();

エンティティの検索と更新

既存のエンティティをIDを用いて取得し、そのプロパティを動的に変更するプロセスです。これにより、インタラクティブなフィードバックや状態の更新が可能になります。

// 特定IDのエンティティを取得
const targetId = 'primary_marker';
const foundEntity = viewer.entities.getById(targetId);

if (foundEntity) {
    // エンティティのスタイルを更新
    foundEntity.point.color = Cesium.Color.YELLOW;
    foundEntity.point.pixelSize = 15;
    
    // または削除
    // viewer.entities.remove(foundEntity);
}

存在確認と安全な削除

エンティティがコレクション内に存在するかを確認した上で、削除処理を行う安全な実装例です。また、IDが存在しない場合に新規作成を行うユーティリティ的な使用方法も示します。

const checkId = 'temp_marker';

// IDによる存在確認と新規作成
const entityObj = viewer.entities.getOrCreateEntity(checkId);
entityObj.position = Cesium.Cartesian3.fromDegrees(140.0, 36.0);

// コレクション内への包含確認
const isRegistered = viewer.entities.contains(entityObj);
console.log('Entity exists:', isRegistered);

// 特定IDを用いた削除
if (viewer.entities.getById(checkId)) {
    viewer.entities.removeById(checkId);
}

パフォーマンスの最適化

大量のエンティティを一括で追加・更新する際、イベントの発火を一時停止することでレンダリングパフォーマンスを大幅に向上させることができます。以下のコードでは、1000個のランダムなポイントを生成する際の最適化手法を示しています。

// イベント処理の一時停止
viewer.entities.suspendEvents();

try {
    const totalCount = 1000;
    for (let i = 0; i < totalCount; i++) {
        const randomLon = Math.random() * 360 - 180;
        const randomLat = Math.random() * 180 - 90;

        viewer.entities.add({
            position: Cesium.Cartesian3.fromDegrees(randomLon, randomLat),
            point: {
                pixelSize: 8,
                color: Cesium.Color.fromRandom({ alpha: 1.0 }),
            },
        });
    }
} finally {
    // 処理完了後にイベント処理を再開
    viewer.entities.resumeEvents();
}

注意: suspendEventsおよびresumeEventsは、エンティティコレクションに関するイベントのみを制御します。シーン全体のレンダリングループやその他のUIイベントには影響しません。

プリミティブ(Primitive)を使用した高度な描画

エンティティAPIよりも低レベルなPrimitive APIを使用することで、より柔軟で高性能なジオメトリ描画が可能になります。以下の例では、複数の矩形領域をRectangleGeometryEllipsoidSurfaceAppearanceを用いて描画しています。

function renderCustomRectangles() {
    const primitiveLayer = viewer.scene.primitives;
    
    // 描画対象の領域定義
    const zones = [
        { west: 130.0, south: 30.0, east: 135.0, north: 35.0 },
        { west: 130.0, south: 36.0, east: 135.0, north: 40.0 },
        { west: 130.0, south: 41.0, east: 135.0, north: 45.0 }
    ];

    zones.forEach((zone, index) => {
        // ジオメトリインスタンスの生成
        const geometryInstance = new Cesium.GeometryInstance({
            id: `zone_layer_${index}`,
            geometry: new Cesium.RectangleGeometry({
                rectangle: Cesium.Rectangle.fromDegrees(zone.west, zone.south, zone.east, zone.north),
                vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
            })
        });

        // マテリアルと外観の定義
        const materialAppearance = new Cesium.EllipsoidSurfaceAppearance({
            material: Cesium.Material.fromType('Water', {
                baseWaterColor: new Cesium.Color(0.0, 0.5, 1.0, 0.8),
                blendColor: new Cesium.Color(0.0, 0.8, 1.0, 0.5),
                normalMap: 'path/to/normal_map.jpg',
                frequency: 1000.0,
                animationSpeed: 0.01,
                amplitude: 10.0
            })
        });

        // プリミティブの作成とシーンへの追加
        const rectanglePrimitive = new Cesium.Primitive({
            geometryInstances: geometryInstance,
            appearance: materialAppearance,
            asynchronous: true
        });

        primitiveLayer.add(rectanglePrimitive);
    });
}

// 関数の実行
renderCustomRectangles();

タグ: Cesium WebGL javascript 3D Visualization Entity API

6月25日 17:46 投稿