Cesium とは

各種ゲームのリアルへの更なる追及やデジタルツインの普及など、近年、地理空間データの活用場が増えてきているように思います。
地理空間データを分析や視覚化するプラットフォームとして、[QGIS](https://qgis.org/)、[ArcGIS](https://www.esrij.com/products/arcgis/)、[Cesium](https://cesium.com/) 等、様々なものがありますが、その中でも、機能が豊富で、非営利目的であれば無料で使用することができる Cesium について、どういったものなのか、簡単に説明していこうと思います。

# 概要
Cesium は、3D 地理空間データを Web 上で視覚化、分析、共有するためのオープンソースのプラットフォームです。リアルタイムの 3D 地球儀と地図を提供し、世界中の地理情報システム (GIS) データ、衛星画像、都市モデル、その他の 3D 地理空間データを高精度で表示することができます。Cesium は、WebGL 技術を使用してブラウザ上で直接、ハードウェア加速された 3D グラフィックスをレンダリングします。


Cesium は主に以下のコンポーネントにより構成されています。

- **Cesium ion**: 3D 地理空間データをウェブで簡単に利用できるようにするクラウドベースのプラットフォーム
- **Cesium ion SDK**: Cesium ion の REST API を簡単に利用するための JavaScript ツールキット
- **CesiumJS**: ウェブブラウザ上でリッチな 3D 地球儀と地図を表示するためのオープンソース JavaScript ライブラリ\
- **Cesium for Unreal**: Unreal Engine でリアルタイムの 3D 地理空間データを利用するためのプラグイン\
- **Cesium for Unity**: Unity ゲームエンジンで Cesium の 3D 地理空間データを活用するためのプラグイン
- **Cesium OSM Buildings**: 誰でも編集可能なオープンソースの地図を提供する [OpenStreetMap](https://www.openstreetmap.org/) の建物データに基づく3Dモデルを全世界規模で提供する無料のレイヤー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/f80d9f1d-e8d4-53a3-da6d-f382f5460b68.png)

# Cesium コンポーネント

## Cesium ion

[Cesium ion](https://ion.cesium.com/) はクラウドベースのプラットフォームで、3D 地理空間データを Web 表示用に最適化、ホスティング、そして配信するサービスです。

ユーザーは様々な形式の地理空間データをアップロードでき、Cesium ion はそれを自動的に Web フレンドリーな形式に変換し、ストリーミング配信のために最適化します。これにより、開発者は CesiumJS や Cesium for Unreal などのツールを使用して、アプリケーション内でこれらのデータを簡単に利用できます。

### 主な機能

| 概要 | 説明 |
|:--|:--|
| 3D 地理空間データのアップロードと自動変換 | 様々な形式の地理空間データをWeb表示用に最適化。 |
| クラウドベースのデータホスティング | 安全なクラウドストレージによるデータのホスティング。 |
| データの最適化と配信 | 大規模な 3D データセットを効率的にストリーミング。 |
| グローバル地形と衛星画像 | 高解像度の地形データと衛星画像へのアクセス。 |
| APIを通じたデータ管理 | データのアップロード、変換、管理を自動化。 |

## Cesium ion SDK

Cesium ion SDK は、Cesium ion REST API を簡単に使用できるようにするための JavaScript ツールキットです。この SDK を利用することで、開発者はプログラム的に Cesium ion の機能にアクセスし、アプリケーションから直接データのアップロード、管理、または配信の設定を行うことができます。Cesium ion SDK は、CesiumJS ライブラリと組み合わせて使用されることが多いです。

### 主な機能

| 概要 | 説明 |
|:--|:--|
| APIラッパー | Cesium ion REST API を簡単に利用するための JavaScript ラッパー。 |
| アクセストークン管理 | Cesium ion のアクセストークンを管理し、認証を容易にする機能。 |
| データアセットの統合 | CesiumJS アプリケーション内で Cesium ion のデータを簡単に利用。 |

## CesiumJS

CesiumJS は、Web ブラウザ上で動作する3D 地理空間アプリケーションを開発するためのオープンソースのJavaScript ライブラリです。3D 地球儀、地図、およびさまざまな 3D データセットを表示するための豊富な API を提供し、開発者はこれを利用してインタラクティブなユーザーインターフェースやビジュアライゼーションを実現できます。CesiumJS は Cesium ion と密接に連携し、クラウド上でホスティングされた 3D データを簡単に統合できます。

### 主な機能

| 概要 | 説明 |
|:--|:--|
| 3D 地球儀と地図の描画 | 3D、2D、および 2.5D のビューをサポート。 |
| 3D Tiles の表示 | 大規模な 3D モデルと地理空間データの効率的なストリーミングと表示。 |
| 動的オブジェクトの描画 | 時間に基づいたデータや動的なシーンの描画。 |
| カスタマイズ可能なビジュアルスタイル | マテリアル、ライティング、その他の視覚効果のカスタマイズ。 |
| インタラクティブなユーザーインターフェイス | ユーザー操作に応じた視点の変更、オブジェクトの選択など。 |

## Cesium for Unreal

Cesium for Unreal は、Epic Games の Unreal Engine 用に開発されたプラグインで、リアルタイムの 3D 地理空間アプリケーションやゲーム、シミュレーションの開発を可能にします。このプラグインを使用すると、Unreal Engine プロジェクト内で直接 Cesium ion から高解像度の地理空間データをインポートし、リアルな世界環境をシミュレーションできます。フォトリアリスティックなレンダリングと大規模なデータセットのサポートが特徴です。

### 主な機能

| 概要 | 説明 |
|:--|:--|
| Unreal Engine 内での地理空間データの利用 | リアルワールドの地形、都市、その他の地理空間データの表示と編集。 |
| フォトリアリスティックなビジュアル |  Unreal Engine の高度なレンダリング機能を活用。 |
| 大規模データセットのストリーミング | Cesium ion からの効率的な 3D Tiles データのストリーミング。 |
| ゲーム開発とシミュレーション | ゲームやシミュレーションプロジェクトでのリアルワールド環境の利用。 |

## Cesium for Unity

Cesium for Unity は、Unity ゲームエンジン用に設計されたプラグインで、Unity プロジェクトにリアルワールドの地理空間データを統合できます。Cesium for Unity を使用すると、開発者は Cesium ion から地形、衛星画像、3D シティモデルなどのデータをインポートし、クロスプラットフォームの 3D アプリケーションやゲーム内で利用できます。

### 主な機能

| 概要 | 説明 |
|:--|:--|
| Unity 内での地理空間データの表示 | リアルタイムでの地形、建物、その他の地理空間データの表示。 |
| クロスプラットフォーム対応 | Unity を通じた多様なプラットフォームへの展開。 |
| Cesium ion の統合 | Cesium ion プラットフォームからデータを直接取り込み、利用。 |

## Cesium OSM Buildings

Cesium OSM Buildings は、全世界の建物データを含む無料の 3D Tiles データセットで、OpenStreetMap から派生したものです。CesiumJS を使用して、Web アプリケーション内でリアルタイムにこれらの 3D 建物を表示できます。都市計画、不動産開発、ゲーム開発など、さまざまなアプリケーションで利用できるリッチなビジュアルと詳細なメタデータを提供します。

### 主な機能

| 概要 | 説明 |
|:--|:--|
| OpenStreetMap の建物データの 3D 表示 | 全世界の OSM 建物データを 3D で表示。 |
| リアルタイムのビジュアライゼーション | CesiumJS を使用したリアルタイムでの 3D 建物レイヤーのストリーミング表示。 |
| メタデータの利用 | 建物の高さ、名前、その他の属性情報のアクセス。 |

# Tips

## Cesium for Unreal と Cesium for Unity の違い

Cesium for Unreal と Cesium for Unity は、それぞれ Unreal Engine と Unity ゲームエンジンに 3D 地理空間データを統合するために設計されたツールです。これらのプラグインは、Cesium の強力な地理空間データホスティングとストリーミング機能を活用し、ゲーム開発やシミュレーション、ビジュアライゼーションプロジェクトにリアルワールドの地形や都市モデルを取り込むことを可能にします。機能面での違いは、主にそれぞれのゲームエンジンの特性や、プラグインがリリースされた時期の成熟度によって異なります。

### Cesium for Unreal の特徴

- **フォトリアルなレンダリング**: Unreal Engine はフォトリアルなレンダリングに優れており、Cesium for Unreal はこの点を活かして高品質なビジュアルを提供します。
- **大規模なデータセットの効率的なストリーミング**: Cesium の 3D Tiles を利用して、大規模な地理空間データセットを効率的にストリーミングし、リアルタイムで表示します。
- **高度なグラフィックス機能**: Unreal Engine の高度なグラフィックスと物理シミュレーション機能を利用して、リアルな環境シミュレーションが可能です。

### Cesium for Unity の特徴

- **クロスプラットフォーム対応**: Unity はクロスプラットフォーム開発に強みを持っており、Cesium for Unity を使用することで様々なデバイス上での3D地理空間アプリケーションの開発が容易になります。
- **リアルタイムの地理空間データ表示**: Unity プロジェクト内で Cesium ion から提供されるリアルタイムの地理空間データを利用できます。
- **インタラクティブなアプリケーション開発**: Unity のインタラクティブなコンテンツ作成ツールを使用して、ユーザーが直接操作できる地理空間データベースのアプリケーションを構築できます。

### 機能の差分

Cesium for Unreal と Cesium for Unity は、それぞれがターゲットとするゲームエンジンの能力と開発コミュニティのニーズに合わせて最適化されています。具体的な機能の差分は以下の通りです：

- **レンダリングの品質**: Unreal Engine はフォトリアルなレンダリングに特化しているため、Cesium for Unreal は非常に高品質なビジュアライゼーションを提供する可能性が高いです。一方、Cesium for Unity も高品質なビジュアライゼーションを提供しますが、Unreal Engine ほどのフォトリアルなレンダリングには特化していません。
- **使用用途と対象プラットフォーム**: Unity はモバイルや Web プラットフォーム向けの開発に強みを持っているため、Cesium for Unity はこれらのプラットフォームでの使用を想定しています。Unreal Engine（および Cesium for Unreal）は、ハイエンドな PC やコンソールゲーム、VR/AR アプリケーションに適しています。

最終的に、どちらのプラグインを使用するかは、プロジェクトの要件、目指すビジュアルの品質、開発チームの熟練度、および対象プラットフォームによって異なります。

## Cesium Sandcastle について
Cesium には、CesiumJS の機能を試すことができるインタラクティブな環境として、**[Cesium Sandcastle](https://sandcastle.cesium.com/)** というものが用意されています。ここには、多数のサンプルとチュートリアルが用意されており、CesiumJS を使用したアプリケーション開発を始める際に非常に便利です。このツールを使用すると、コードの変更がリアルタイムで地球儀上に反映されるため、開発プロセスが効率的になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/c09bb1c4-32b7-35bc-c112-2367f9cb5988.png)

## CesiumJS を使った簡単なアプリの開発

CesiumJS を使用したアプリ開発を行うのは非常に簡単で、上述の [Cesium Sandcastle](https://sandcastle.cesium.com/) や [チュートリアル](https://cesium.com/docs/tutorials/getting-started/)など、豊富なドキュメントも用意されています。

CesiumJS を使用した簡単なアプリケーションのソースコードを以下に示します。
このアプリでは、指定したグローバル座標上に赤いポインタと文字列を配置し、任意の視点からのマップを描画しています。

:::note warn
動作させるには、[Cesium ion](https://ion.cesium.com/) で事前にアクセストークンを取得し、ソースコード内の `YOUR_ACCESS_TOKEN` 部分を書き換える必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/b8693987-79ce-7ab1-4194-805da5a13951.png)
:::

```html
<!DOCTYPE html> 
<html lang="ja"> 
<head> 
 <meta charset="utf-8">
 <script src="https://cesium.com/downloads/cesiumjs/releases/1.108/Build/Cesium/Cesium.js"></script>
 <link href="https://cesium.com/downloads/cesiumjs/releases/1.108/Build/Cesium/Widgets/widgets.css" rel="stylesheet"> 
</head> 
<body> 
  <div id="cesiumContainer" style="width: 1800px; height:900px"></div> 
  <script>
    Cesium.Ion.defaultAccessToken = 'YOUR_ACCESS_TOKEN';  // 自身のアクセストークンに書き換え
     
    var viewer = new Cesium.Viewer('cesiumContainer', {
      timeline: false, // タイムライン表示の無効化
      animation: false,  // 再生アニメーションの無効化
      baseLayerPicker: false,  // レイヤー切替の無効化
    });
    //viewer.forceResize();
    
    // Cesium ロゴの削除
    viewer._cesiumWidget._creditContainer.parentNode.removeChild(viewer._cesiumWidget._creditContainer);
    
    (function(){
      var ekb = viewer.entities.add({
        name : '明石市立天文科学館 展望台',
        // 緯度経度
        position: Cesium.Cartesian3.fromDegrees(135.0012443222342, 34.64955935410281),
        
        // ポインタ設定
        point: {
          pixelSize: 16,
          color: Cesium.Color.RED
        },
        
        // ラベル設定
        label : {
          text: '明石市立天文科学館 展望台',
          font: 'bold 12pt Hiragino Maru Gothic ProN',
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          outlineWidth: 10,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
          pixelOffset: new Cesium.Cartesian2(0, -16)  // 中心点からのオフセット位置
        }
      });

      // How to place camera around point
      var heading = Cesium.Math.toRadians(0);  // 視点の回転
      var pitch = Cesium.Math.toRadians(-30);  // 視点の高さ
      viewer.zoomTo(ekb, 
        new Cesium.HeadingPitchRange(heading, pitch, 280000)  // 第三引数はズーム表示
      );
    })();
  </script>
</body> 
</html>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2659159/c29fa8b6-d3e1-8cc7-19ae-41ef0dcd18d9.png)

# 参考文献
- **Cesium ion**, https://ion.cesium.com/
- **CesiumJS**, https://cesium.com/platform/cesiumjs/
- **Cesium Sandcastle**, https://sandcastle.cesium.com/
- **Cesium: la plataforma para crear mapas web en 3D**
, https://mappinggis.com/2020/07/cesium-la-plataforma-para-crear-mapas-web-en-3d/
- **OpenStreetMap**, https://www.openstreetmap.org/