mcpField
C
cesiumjs-viewer-setup

cesiumjs-viewer-setup

github.com/cesiumgs開発193258 回インストール6 週間前に更新
リポジトリ

cesiumjs-viewer-setup について

cesiumjs-viewer-setupは、CesiumJSのViewerとシーンを初期化するためのリファレンスで、3D地球儀や地図アプリの開発者向けです。Viewer設定、地形や画像レイヤー、ジオコーディング、読み込んだコンテンツの表示範囲設定をまとめています。

主な機能

  1. 01ViewerとCesiumWidgetの初期化
  2. 02地形、画像、シーンの設定
  3. 03Ion、Google Maps、iTwinの設定
  4. 04ジオコーダーとViewer mixin
  5. 05読み込んだコンテンツへのカメラ設定

活用シーン

  1. 01カスタムUIや軽量なCesiumシーンの構築
  2. 02地形、画像、3D Tilesの設定
  3. 03読み込んだモデルやデータにカメラを合わせる
  4. 04ジオコーディングとドラッグ&ドロップ読み込みの設定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/cesiumgs/cesiumjs-skills --skill cesiumjs-viewer-setup

インストール後、Claude Code で/cesiumjs-viewer-setupを入力して読み込まれたか確認します。

詳細

CesiumJS Viewer とシーンのセットアップ

CesiumJS アプリケーションの初期化に関するリファレンスです。Viewer、CesiumWidget、Ion/GoogleMaps/ITwinPlatform の設定、ウィジェット、ファクトリーヘルパー、ジオコーダーサービス、Viewer のミックスイン、Credits、および関連する列挙型を扱います。

クイックスタート

import { Viewer, ImageryLayer, OpenStreetMapImageryProvider } from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";

const viewer = new Viewer("cesiumContainer", {
  baseLayer: new ImageryLayer(new OpenStreetMapImageryProvider({
    url: "https://tile.openstreetmap.org/",
    maximumLevel: 18,
  })),
  baseLayerPicker: false,
});

必須の HTML:<div id="cesiumContainer" style="width:100%;height:100vh"></div>

Cesium ion のデフォルト(Terrain.fromWorldTerrain、ImageryLayer.fromWorldImagery、createOsmBuildingsAsync、Google Photorealistic 3D Tiles)は、対象の実行環境で必要な ion または Google の利用権限がある場合にのみ使用してください。公開トークン不要の例では、明示的な公開プロバイダーと URL を指定した 3D Tiles を選択してください。

読み込んだコンテンツのフレーミング(重要)

タイルセット、モデル、またはデータソースを追加した後は、必ず明示的にフレーミングしてください。 デフォルトのオプションで構築した Viewer は、カメラが固定された地球のビューから開始します。追加したプリミティブに合わせて自動的にズームすることはありません。「灰色の地表しか見えない」または「アセットが隅に小さく表示される」という問題の最も一般的な原因は、これを忘れることです。

const tileset = await Cesium3DTileset.fromUrl(url);
viewer.scene.primitives.add(tileset);

// Pick ONE of:
await viewer.zoomTo(tileset);                 // instant fit to bounding sphere
await viewer.flyTo(tileset, { duration: 0 }); // animated; duration 0 = instant

viewer.zoomTo/viewer.flyTo が受け取るのは、Entity、Entity[]、EntityCollection、DataSource、ImageryLayer、Cesium3DTileset、VoxelPrimitive、Model、または TimeDynamicPointCloud です。これらは対象のバウンディングスフィアを使用します。そのため、任意のローカル座標系を持つタイルセットでも機能します。ECEF のカメラ位置を手動で計算すると、アセットを完全に見失うことがあります。

明示的なカメラ位置が必要な場合(例:方位角/ピッチの仕様を満たす場合)でも、viewer.zoomTo(target, headingPitchRange) を使用してください。範囲は推測するのではなく、バウンディングスフィアから導出されます。

import { HeadingPitchRange, Math as CesiumMath } from "cesium";

await viewer.zoomTo(tileset, new HeadingPitchRange(
  CesiumMath.toRadians(45),   // heading
  CesiumMath.toRadians(-30),  // pitch
  /* range omitted -> auto-fit */
));

Ion とプラットフォームの設定

Cesium Ion
import { Ion } from "cesium";

Ion.defaultAccessToken = "YOUR_TOKEN";  // required for ion assets
Ion.defaultServer = "https://your-ion-server.example.com/"; // optional: self-hosted
IonResource
import { IonResource, Cesium3DTileset } from "cesium";

const resource = await IonResource.fromAssetId(96188);
const tileset = await Cesium3DTileset.fromUrl(resource);
viewer.scene.primitives.add(tileset);
await viewer.zoomTo(tileset);
Google Maps Platform
import { GoogleMaps, createGooglePhotorealistic3DTileset, Viewer, IonGeocodeProviderType } from "cesium";

GoogleMaps.defaultApiKey = "YOUR_GOOGLE_MAPS_API_KEY"; // optional: without key, served via ion

const viewer = new Viewer("cesiumContainer", {
  geocoder: IonGeocodeProviderType.GOOGLE, // required with Google 3D Tiles
});

const tileset = await createGooglePhotorealistic3DTileset({
  onlyUsingWithGoogleGeocoder: true,
});
viewer.scene.primitives.add(tileset);
iTwin Platform(実験的)
import { ITwinPlatform, ITwinData } from "cesium";

ITwinPlatform.defaultAccessToken = "YOUR_ITWIN_TOKEN";
const tileset = await ITwinData.createTilesetForIModel(viewer, "imodel-id");

// 1.140+ (#13208): Reality Data of type GaussianSplat3DTiles is now supported
const splats = await ITwinData.createTilesetForRealityDataId(
  iTwinId,
  realityDataId,
  ITwinPlatform.RealityDataType.GaussianSplat3DTiles,
);
viewer.scene.primitives.add(splats);

Viewer コンストラクターのオプション

new Viewer(container, options?) -- container は DOM 要素またはその文字列 ID です。

ウィジェットの切り替え
オプションデフォルト用途
animationtrue再生コントロール
baseLayerPickertrue画像/地形の切り替え
fullscreenButtontrue全画面表示の切り替え
vrButtonfalseWebVR の切り替え
geocoderIonGeocodeProviderType.DEFAULT検索バー(非表示にする場合は false)
homeButtontrueホームビューに戻す
infoBoxtrueエンティティ情報のポップアップ
sceneModePickertrue2D/3D/Columbus の切り替え
selectionIndicatortrue選択マーカー
timelinetrue時間のスクラバー
navigationHelpButtontrueマウス/タッチ操作のヘルプ
projectionPickerfalse透視投影/正投影の切り替え
シーンとレンダリング
オプションデフォルト用途
sceneModeSceneMode.SCENE3D初期シーンモード
scene3DOnlyfalse3D に固定し、ジオメトリーインスタンスごとの GPU メモリを節約
shadowsfalse影の投影
terrainShadowsShadowMode.RECEIVE_ONLY地形の影モード
requestRenderModefalse変更時のみレンダリング
maximumRenderTimeChange0.0レンダリング時のシミュレーション時間の最大差分
msaaSamples4MSAA(無効にする場合は 1)
orderIndependentTranslucencytrue透過描画の順序
mapMode2DMapMode2D.INFINITE_SCROLL2D のスクロール動作

低電力向けまたはダッシュボード向けアプリでは、requestRenderMode: true と scene3DOnly: true を組み合わせてください。GPU の節約が求められるシナリオでは、一般に両方を併用する必要があります。

レイヤーと地形
オプションデフォルト用途
baseLayerImageryLayer.fromWorldImagery()ベース画像(なしにする場合は false。その場合は baseLayerPicker: false が必要)
terrainなし非同期地形ヘルパー(terrainProvider とは併用不可)
terrainProviderEllipsoidTerrainProvider同期地形プロバイダー
globenew Globe()地球儀を表示しない場合は false(宇宙シーン向け)
skyBox自動(WGS84)false にすると空/太陽/月を無効化
skyAtmosphere自動(WGS84)false にすると地平線の輝きを無効化
最小ビューアー(ウィジェットなし)
import { Viewer, ImageryLayer, OpenStreetMapImageryProvider } from "cesium";

const viewer = new Viewer("cesiumContainer", {
  baseLayer: new ImageryLayer(new OpenStreetMapImageryProvider({
    url: "https://tile.openstreetmap.org/",
    maximumLevel: 18,
  })),
  animation: false, baseLayerPicker: false, fullscreenButton: false,
  geocoder: false, homeButton: false, infoBox: false,
  sceneModePicker: false, selectionIndicator: false,
  timeline: false, navigationHelpButton: false,
});

CesiumWidget(軽量な代替手段)

UI ウィジェットも Knockout への依存もありません。カスタム UI や埋め込みに適しています。

import { CesiumWidget, Ion } from "cesium";
Ion.defaultAccessToken = "YOUR_TOKEN";

const widget = new CesiumWidget("cesiumContainer", { shouldAnimate: true });
// Exposes: widget.scene, widget.camera, widget.entities

SceneMode Enum

値説明
SceneMode.SCENE3D標準の 3D 地球儀(デフォルト)
SceneMode.SCENE2D真上から見た正投影図
SceneMode.COLUMBUS_VIEW高さのある 2.5D の平面地図
SceneMode.MORPHINGモード間を遷移中
import { Viewer, SceneMode } from "cesium";

const viewer = new Viewer("cesiumContainer", { sceneMode: SceneMode.SCENE2D });
viewer.scene.morphTo3D(2.0);          // animated transition
viewer.scene.morphToColumbusView(2.0);

シーンの設定

const scene = viewer.scene;
scene.globe.depthTestAgainstTerrain = true; // entities interact with terrain
scene.globe.enableLighting = true;          // sun-based lighting

// Key sub-objects
scene.camera;           // Camera
scene.primitives;       // PrimitiveCollection
scene.groundPrimitives; // PrimitiveCollection (ground-clamped)
scene.imageryLayers;    // ImageryLayerCollection
scene.postProcessStages;

scene.requestRender();  // trigger frame in requestRenderMode

重要:対応するコンストラクターオプションが false に設定されている場合は、scene.globe.* や scene.skyAtmosphere.* に絶対に触れないでください。 Viewer オプションでこれらを無効にすると、シーン上の対応するプロパティは undefined になり、.enableLighting、.depthTestAgainstTerrain、.show などのフィールドにアクセスすると、TypeError: Cannot set properties of undefined がスローされます。宇宙空間のシーンでは、コンストラクターで一度だけ設定し、その後これらのプロパティを変更しないでください(下記の「宇宙空間のシーン」を参照)。

ファクトリーヘルパー

createOsmBuildingsAsync
import { createOsmBuildingsAsync, Cesium3DTileStyle } from "cesium";

// Default styling (colors from OSM tags)
const tileset = await createOsmBuildingsAsync();
viewer.scene.primitives.add(tileset);

// Custom style
const styled = await createOsmBuildingsAsync({
  style: new Cesium3DTileStyle({
    color: { conditions: [
      ["${feature['building']} === 'hospital'", "color('#0000FF')"],
      [true, "color('#ffffff')"],
    ]},
  }),
});
createGooglePhotorealistic3DTileset
import { createGooglePhotorealistic3DTileset, IonGeocodeProviderType } from "cesium";

// Must use Google geocoder
const viewer = new Viewer("cesiumContainer", { geocoder: IonGeocodeProviderType.GOOGLE });
const tileset = await createGooglePhotorealistic3DTileset({ onlyUsingWithGoogleGeocoder: true });
viewer.scene.primitives.add(tileset);
Terrain.fromWorldTerrain / fromWorldBathymetry

terrain コンストラクターオプションにはこちらを推奨します。エラーイベントに対応し、処理をブロックしません。

import { Viewer, Terrain } from "cesium";

// World terrain with normals and water
const viewer = new Viewer("cesiumContainer", {
  terrain: Terrain.fromWorldTerrain({ requestVertexNormals: true, requestWaterMask: true }),
});

// Bathymetry (ocean floor)
const viewer2 = new Viewer("cesiumContainer", {
  terrain: Terrain.fromWorldBathymetry({ requestVertexNormals: true }),
});
Terrain イベントの処理
import { Terrain, CesiumTerrainProvider } from "cesium";

const terrain = new Terrain(CesiumTerrainProvider.fromUrl("https://my-terrain.example.com"));
viewer.scene.setTerrain(terrain);

terrain.readyEvent.addEventListener((provider) => {
  viewer.scene.globe.enableLighting = true;
});
terrain.errorEvent.addEventListener((error) => console.error("Terrain failed:", error));
createWorldTerrainAsync / createWorldImageryAsync

より低レベルの API で、生のプロバイダーを返します。プロバイダーを直接必要とする場合に使用します。

import { createWorldTerrainAsync, createWorldImageryAsync, IonWorldImageryStyle } from "cesium";

const terrainProvider = await createWorldTerrainAsync({ requestVertexNormals: true });
viewer.terrainProvider = terrainProvider;

const imageryProvider = await createWorldImageryAsync({ style: IonWorldImageryStyle.AERIAL_WITH_LABELS });

IonWorldImageryStyle:AERIAL(デフォルト) | AERIAL_WITH_LABELS | ROAD

ジオコーダーの設定

geocoder オプションには、false、IonGeocodeProviderType、または GeocoderService[] を指定できます。

IonGeocodeProviderType:DEFAULT | GOOGLE(Google タイルでは必須) | BING

import { Viewer, CartographicGeocoderService, IonGeocoderService, OpenCageGeocoderService } from "cesium";

// Multiple services (searched in order)
const viewer = new Viewer("cesiumContainer", {
  geocoder: [
    new CartographicGeocoderService(), // accepts "lat, lon" input
    new IonGeocoderService({ scene: viewer.scene }),
  ],
});
カスタム GeocoderService
const myGeocoder = {
  async geocode(input, type) {
    // type: GeocodeType.SEARCH or GeocodeType.AUTOCOMPLETE
    const resp = await fetch(`https://api.example.com/search?q=${input}`);
    const data = await resp.json();
    return data.map((item) => ({
      displayName: item.name,
      destination: Cartesian3.fromDegrees(item.lon, item.lat),
    }));
  },
};
const viewer = new Viewer("cesiumContainer", { geocoder: [myGeocoder] });

Viewer ミックスイン

import { Viewer, viewerDragDropMixin, viewerCesium3DTilesInspectorMixin,
  viewerCesiumInspectorMixin, viewerPerformanceWatchdogMixin, viewerVoxelInspectorMixin } from "cesium";

const viewer = new Viewer("cesiumContainer");

// Drag-and-drop CZML/GeoJSON/KML loading
viewer.extend(viewerDragDropMixin, { dropTarget: "cesiumContainer", clearOnDrop: true });
viewer.dropError.addEventListener((handler, name, error) => console.error(error));

viewer.extend(viewerCesium3DTilesInspectorMixin);    // 3D Tiles debug panel
viewer.extend(viewerCesiumInspectorMixin);            // general scene inspector
viewer.extend(viewerPerformanceWatchdogMixin);        // low-FPS warning
viewer.extend(viewerVoxelInspectorMixin);             // voxel debug panel

主な Viewer のプロパティとメソッド

プロパティ型
viewer.sceneScene
viewer.cameraCamera
viewer.entitiesEntityCollection
viewer.dataSourcesDataSourceCollection
viewer.imageryLayersImageryLayerCollection
viewer.terrainProviderTerrainProvider
viewer.clock / clockViewModelClock / ClockViewModel
viewer.canvasHTMLCanvasElement
viewer.screenSpaceEventHandlerScreenSpaceEventHandler
viewer.selectedEntity / trackedEntityEntity
viewer.shadowsboolean
viewer.resolutionScalenumber(デフォルト 1.0)
await viewer.flyTo(entity, { duration: 3.0, offset: headingPitchRange }); // animated
await viewer.zoomTo(tileset);   // instant; uses bounding sphere
viewer.destroy();               // free all resources

クレジットと FrameRateMonitor

import { Credit, FrameRateMonitor } from "cesium";

// Custom credit (showOnScreen = true)
viewer.creditDisplay.addStaticCredit(new Credit("Data by Example Corp", true));

// Monitor frame rate
const monitor = FrameRateMonitor.fromScene(viewer.scene);
monitor.lowFrameRate.addEventListener(() => console.warn("Low FPS"));
monitor.nominalFrameRate.addEventListener(() => console.log("FPS recovered"));

よく使われるパターン

地形と OSM 建物を含む本番用 Viewer
import { Ion, Viewer, Terrain, createOsmBuildingsAsync, Cartesian3, Math as CesiumMath } from "cesium";

Ion.defaultAccessToken = "YOUR_TOKEN";
const viewer = new Viewer("cesiumContainer", {
  terrain: Terrain.fromWorldTerrain(), animation: false, timeline: false,
});

viewer.scene.primitives.add(await createOsmBuildingsAsync());
viewer.scene.camera.flyTo({
  destination: Cartesian3.fromDegrees(-74.019, 40.6912, 750),
  orientation: { heading: CesiumMath.toRadians(20), pitch: CesiumMath.toRadians(-20) },
});
サンプル 3D Tileset の読み込みと表示範囲の調整

タイルセットのローカル座標系が不明な場合(サンプルアセットや離散 LOD のデモなど)、ECEF カメラ位置を手計算しないでください。アセットを見逃し、灰色の空のサーフェスが描画されます。HeadingPitchRange を指定して viewer.zoomTo を使用し、タイルセットのバウンディングスフィアに合わせた表示を導出してください。

import { Cesium3DTileset, HeadingPitchRange, Math as CesiumMath } from "cesium";

const tileset = await Cesium3DTileset.fromUrl(url);
viewer.scene.primitives.add(tileset);

await viewer.zoomTo(
  tileset,
  new HeadingPitchRange(
    CesiumMath.toRadians(45),
    CesiumMath.toRadians(-30),
    // omit range -> Cesium auto-fits the bounding sphere
  ),
);
宇宙空間のシーン(地球儀なし)

コンストラクターオプションのみで地球儀と大気を無効にしてください。シーンの globe と skyAtmosphere プロパティは undefined になるため、後から viewer.scene.globe.<anything> = ... や viewer.scene.skyAtmosphere.show = false を実行すると、Cannot set properties of undefined がスローされます。ライティング、地形に対する深度テスト、大気の表示設定などはコンストラクターで設定するか、宇宙空間のシーンでは設定を省略してください。

const viewer = new Viewer("cesiumContainer", {
  globe: false,           // viewer.scene.globe will be undefined
  skyAtmosphere: false,   // viewer.scene.skyAtmosphere will be undefined
  baseLayerPicker: false,
  baseLayer: false,       // no imagery layer is needed without a globe
});

// Safe post-construction tweaks (skyBox/sun/moon remain defined):
viewer.scene.skyBox.show = true;  // default star field
viewer.scene.sun.show = false;
viewer.scene.moon.show = false;

// DO NOT do this, throws because globe/skyAtmosphere are undefined:
// viewer.scene.globe.enableLighting = true;
// viewer.scene.skyAtmosphere.show = false;
明示的なレンダリングモード(低消費電力ダッシュボード)

2D や Columbus View が不要な場合は、scene3DOnly: true と組み合わせてください。これが標準的な低 GPU 負荷の設定です。

const viewer = new Viewer("cesiumContainer", {
  requestRenderMode: true,
  maximumRenderTimeChange: Infinity,
  scene3DOnly: true,
  animation: false,
  timeline: false,
});
// Call viewer.scene.requestRender() after programmatic changes
カスタムベースレイヤー
import { Viewer, ImageryLayer, OpenStreetMapImageryProvider } from "cesium";

const viewer = new Viewer("cesiumContainer", {
  baseLayerPicker: false,
  baseLayer: new ImageryLayer(new OpenStreetMapImageryProvider({
    url: "https://tile.openstreetmap.org/",
  })),
});
Web Mercator を使った Columbus View
import { Viewer, SceneMode, WebMercatorProjection } from "cesium";

const viewer = new Viewer("cesiumContainer", {
  sceneMode: SceneMode.COLUMBUS_VIEW, mapProjection: new WebMercatorProjection(),
});

パフォーマンスのヒント

  1. 静的な状態が大半を占めるアプリでは、requestRenderMode: true を設定します。CPU/GPU の使用量とバッテリー消費を抑えられます。変更後は scene.requestRender() を呼び出します。
  2. 2D/Columbus View が不要な場合は、scene3DOnly: true を使用します。ジオメトリインスタンスごとの GPU メモリを節約できます。ダッシュボードや低電力のシナリオでは、通常 requestRenderMode と併せて設定する必要があります。
  3. 使用しないウィジェット(animation: false、timeline: false)を無効にして、DOM のオーバーヘッドを減らします。
  4. 低電力デバイスでは msaaSamples: 1 を設定します。デフォルトの 4 は画質とのバランスを取った値です。
  5. HiDPI ディスプレイでは resolutionScale を下げる(例:0.75)と、フレームレートが向上します。
  6. await createWorldTerrainAsync() より Terrain.fromWorldTerrain() を優先します。ノンブロッキングで、エラーイベントを利用できます。
  7. 地形で requestVertexNormals: true を有効にすると、ほとんどコストをかけずに適切なライティングを実現できます。
  8. DOM から削除するときは viewer.destroy() を呼び出し、WebGL コンテキストを解放します。
  9. イメージレイヤーは 2~3 個に制限します。追加するたびに、フラグメントごとのテクスチャ検索が増えます。

フレーミングのチェックリスト(何も表示されない/フレーム外への描画を防ぐ)

ビューアーの設定タスクを完了とする前に、次の項目を確認します。

  1. タイルセット、モデル、GeoJSON/KML/CZML データソース、またはエンティティコレクションを追加した後、await viewer.zoomTo(target) または await viewer.flyTo(target) を呼び出していること。
  2. ローカル座標系が不明なタイルセットでは、カメラの位置を手動で選んだ Cartesian3.fromDegrees(...) ではなく、バウンディングスフィア(HeadingPitchRange)から導出していること。
  3. シナリオで heading/pitch が指定されている場合、推測した目的地を使って camera.flyTo に設定するのではなく、HeadingPitchRange を介して zoomTo/flyTo に渡していること。
  4. シナリオでアセットの下に地図を表示する想定の場合、必要なベースイメージレイヤーが実際に存在すること(count == 1)。
  5. コンストラクターオプションで globe: false または skyAtmosphere: false が設定されている場合、それ以降のコードで viewer.scene.globe.* または viewer.scene.skyAtmosphere.* にアクセスしないこと。どちらも undefined であり、アクセスすると例外が発生します。

関連項目

  • cesiumjs-camera -- カメラの位置設定、flyTo、lookAt、ナビゲーションの制約
  • cesiumjs-entities -- Entity API、データソース、GeoJSON/KML/CZML の読み込み
  • cesiumjs-imagery -- イメージプロバイダー、レイヤー管理、分割画面
  • cesiumjs-terrain-environment -- 地形プロバイダー、Globe、大気、空、ライティング

コメント