Cesiumを使った開発の始め方

# はじめに

この記事では、今は亡きGoogle Earth APIの代替でもある、WebGLによる地球儀ライブラリ [Cesium](https://cesiumjs.org/) を使った開発を、まっさらな状態から始める方法を解説していきます。

Cesiumには最近急速に発達したフロントエンド周りの技術が色々盛り込まれているので、モダンなフロントエンド開発に触れる良い機会にもなるかと思います。

# Cesiumの開発の始め方

## 1. Node.js のインストール

npm で Cesium をインストールするのがオススメなので、まず Node.js を導入しましょう。

[Node.js 公式サイト](https://nodejs.org/en/)から落とすか、[nvm](https://github.com/creationix/nvm)、[homebrew](http://brew.sh/)、[nodebrew](https://github.com/hokaccha/nodebrew)、[nodenv](https://github.com/nodenv/nodenv), [ndenv](https://github.com/riywo/ndenv)...等のツールで導入できます。

ここではインストールの話は端折ってしまいます。インストール方法は、各ツールのページをご参照下さい。

（個人的には、Windowsなら[nvm-windows](https://github.com/coreybutler/nvm-windows)、Mac/Linuxなら[nvm](https://github.com/creationix/nvm)が良いかなぁと思ってます）

## 2. プロジェクト作成

ターミナルで作業します。

```
mkdir cesium-project
cd cesium-project
npm init -y
```

package.json が作成されます。

これはプロジェクトのメタデータで、今後インストールするモジュールの名前とバージョン情報なども管理できます。無くても Cesium はインストールできますが、 git で管理しながら開発するときには、 package.json を作っておくことをおすすめします。

## 3. Cesiumのインストール

Cesium は npm から利用可能です。

Cesium公式サイトからzipでダウンロードして解凍…ということを毎回繰り返すよりは、 npm で管理することでpackage.json に Cesium のバージョンが記録されてバージョンを固定でき、Cesium のバージョンアップも非常に楽になります。また、他の人が同じ環境を再現するのも楽になります。

```
npm install cesium --save
```

または省略形として、以下のようにもできます。

```
npm i cesium -S
```

インストール時に `--save` オプションを指定しているので、package.jsonにCesiumのバージョン情報が記録されます。このpackage.jsonもgit管理しておけば、他の人がこのプロジェクトをクローンしたあと、単に `npm i` するだけで、記録されたバージョンのcesiumがインストールされます。

ちなみに、上記の方法で一度cesiumをインストールしたプロジェクトで、cesiumを最新版にアップデートしたい場合は、

```
npm i cesium@latest -S
```

とすると良いでしょう。

:warning: Cesiumは、バージョンアップに伴いAPIの破壊的変更が度々行われているので、アップグレード時は動かなくなる可能性に注意してください。

:information_source: インストール速度が非常に早いので、知ってる人は npm より [Yarn](https://yarnpkg.com/lang/en/) の方がいいですよ、とおすすめしておく

## 4. Hello, world!

以下のファイルを作ります。

```index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>cesium</title>
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
    <link rel="stylesheet" href="node_modules/cesium/Build/Cesium/Widgets/widgets.css">
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div id="cesium" class="cesium"></div>
    <script src="node_modules/cesium/Build/Cesium/Cesium.js"></script>
    <script src="main.js"></script>
  </body>
</html>
```

```style.css
body {
  margin: 0;
}

.cesium {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
}
```

```main.js
(function() {
  "use strict";

  var viewer = new Cesium.Viewer("cesium");

  // コードをここに記述

}());
```

ここまで作ると、プロジェクトの中身はこういう感じになっているはずです。

```
cesium-project
 ├─ node_modules
 │   └ cesium
 │     └ Build
 │       ├ Cesium             <= 圧縮済 本番用
 │       │ └ Cesium.js
 │       └ CesiumUnminified   <= 未圧縮 開発用
 │         └ Cesium.js
 ├─ package.json
 ├─ index.html
 ├─ style.css
 └─ main.js
```

※ gitで管理するなら、.gitignoreでnode_modules以下を無視する設定にしておくのを忘れずに！

後は、index.htmlを下記の方法でローカルサーバー経由で開くと、めでたくCesiumが動作します！

## 5. ローカルサーバー立ち上げ

Same-Oigin Policy等のため、Cesiumはそのままブラウザで開いても動作しません。開発用にローカルサーバーを立てましょう。

せっかくNode.jsを導入してるので、npmで導入できる [st](https://www.npmjs.com/package/st) が一番簡単だと思います、

stをターミナルで使えるようにするために、まずはstをグローバルにインストールします。

```
npm i st -g
```

そして、以下のコマンドでサーバーを起動します。

```
st -nc -i index.html
```

※ nc は no cache の意味。開発していると何回もリロードすることになりますが、そのときにキャッシュが効かなくなるので、変更がすぐ反映されるようになります。

ターミナルにURLが表示されますので、ブラウザで見ることができます。

## 6. ちょっとカスタマイズ

最初から日本が表示されるようにしてみます。

```main.js
var viewer = new Cesium.Viewer("cesium");

viewer.camera.setView({
  destination: Cesium.Cartesian3.fromDegrees(138, 30, 3000000),
  orientation: {
    heading: 0, // 水平方向の回転度（ラジアン）
    pitch: -1.3, // 垂直方向の回転度（ラジアン） 上を見上げたり下を見下ろしたり
    roll: 0
  }
});
```

KMLを表示させてみる例。`your.kml` を表示させたいKMLへのパスに変えるだけ。

```main.js
var viewer = new Cesium.Viewer("cesium");

viewer.dataSources.add(Cesium.KmlDataSource.load("your.kml"));
```

あとは、Cesiumの[APIリファレンス](https://cesiumjs.org/refdoc.html)と[サンプル](https://cesiumjs.org/Cesium/Apps/Sandcastle/index.html)を見て、思う存分弄り倒しましょう！

# おまけ

## 開発用と本番用で読み込むJSを変える

上記のindex.htmlでは、本番用のCesiumを読み込んでいますが、普段は開発用の未圧縮Cesiumを読み込み、本番用には本番の圧縮済Cesiumを読み込ませたいこともあります。

gulp および [gulp-preprocess](https://www.npmjs.com/package/gulp-preprocess) を使うと、ビルド時にHTMLの中身を書き換えることが可能です。

```
npm i gulp-cli -g
npm i gulp gulp-preprocess -D
```

```index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>cesium</title>
    <!-- @ifndef production -->
    <link rel="stylesheet" href="node_modules/cesium/Build/CesiumUnminified/Widgets/widgets.css">
    <!-- @endif -->
    <!-- @ifdef production !>
    <link rel="stylesheet" href="node_modules/cesium/Build/Cesium/Widgets/widgets.css">
    <!-- @endif -->
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div id="cesium" class="cesium"></div>
    <!-- @ifndef production -->
    <script src="node_modules/cesium/Build/CesiumUnminified/Cesium.js"></script>
    <!-- @endif -->
    <!-- @ifdef production !>
    <script src="node_modules/cesium/Build/Cesium/Cesium.js"></script>
    <!-- @endif -->
    <script src="main.js"></script>
  </body>
</html>
```

```gulpfile.js
const gulp = require("gulp");
const preprocess = require("gulp-preprocess");

gulp.task("build", () => {
  return gulp
    .src("index.html")
    .pipe(preprocess({
      context: { production: true }
    }))
    .pipe(gulp.dest("build"))
});
```

```
gulp build
```

これで build ディレクトリ内に、本番用index.htmlファイルが吐き出されます。

## IE10以下は切り捨て可能

Cesium で用いられる WebGL は、IE10以下では対応していないため、IE10以下は全て無視し、IE11以降の機能を使って開発可能です。

## webpackでCesiumを使う方法

~~[cesium-webpack-boilerplate](https://github.com/rot1024/cesium-webpack-boilerplate)~~

~~Cesium公式ブログ記事「[Cesium and webpack](https://cesiumjs.org/2016/01/26/Cesium-and-Webpack/)」を基に、webpack v2 に対応させたボイラープレートを作りました。手前味噌ですが、よかったら参考にしてみてください。~~

Cesium公式のサンプルが上がっています。

https://github.com/AnalyticalGraphicsInc/cesium-webpack-example

## ReactでCesiumを使う方法

👉 拙作の[Resium](https://github.com/darwin-education/resium)を使うと便利です。