Cesiumで徐々に大きくなる円を作った

Cesiumで徐々に大きくなる円を作りました。

https://twitter.com/danburutobira/status/1596885737802452992

# 作成手順
## ① Cesiumのインストール
cesium-webpack-example を使用した（が、純粋なCesiumGSでも問題ないはず）

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

上記リポジトリをClone後、
npm install
npm start で動作確認。

src > index.js を編集していく。

## ② 時計を追加してタイムラインを動かす
デフォルト画面だと、タイムライン（下記画像の赤枠）は表示されているものの、時間は動かない状態になっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581044/078a4874-340d-8516-f391-f61159183bc0.png)

時間を動かすためには、clockオブジェクトを生成する必要がある。
詳細は公式サイトおよびデモサイトを参照。
[公式サイト](https://cesium.com/learn/cesiumjs/ref-doc/Clock.html)
[デモサイト](https://sandcastle.cesium.com/index.html?src=Clock.html)

以下のようにソースコードを追加する。
```index.js
// clockを定義
const clock = new Clock({
  startTime: JulianDate.fromIso8601("2020-01-01"),
  currentTime: JulianDate.fromIso8601("2022-12-25"),
  stopTime: JulianDate.fromIso8601("2022-12-25"),
  clockRange: ClockRange.LOOP_STOP, 
  clockStep: ClockStep.TICK_DEPENDENT,
  multiplier: 43200, 
  shouldAnimate: true,
});

const viewer = new Viewer('cesiumContainer', {
  terrainProvider: createWorldTerrain(),
  clockViewModel: new ClockViewModel(clock) // clockを追加
});
```

※cesium-webpack-example を使用する場合の注意点として、
JulianDateやClockViewModelなどのモジュールがデフォルトで読み込まれていないため、importに追加する必要がある。

この状態で
npm start すると、タイムラインが動くことが確認できる。 

## ③ 円オブジェクトを表示時間つきで追加する
円オブジェクトを追加する。
円オブジェクトの追加方法は下記CesiumJSのチュートリアル的なサイトが参考になる。
[オブジェクト追加の方法](https://cesium.com/learn/cesiumjs-learn/cesiumjs-creating-entities/)

```index.js
// 円オブジェクト追加
var entity = viewer.entities.add({
  availability: new TimeIntervalCollection([
    new TimeInterval({
      start: JulianDate.fromIso8601("2020-10-01"),
      stop: JulianDate.fromIso8601("2020-12-01"),
    }), // この範囲内のみ有効
  ]),
  position: Cartesian3.fromDegrees(-103.0, 40.0),
  ellipse : {
    semiMinorAxis : 250000.0,
    semiMajorAxis : 400000.0,
    material : Color.BLUE.withAlpha(0.5)
  }
});
viewer.zoomTo(viewer.entities);
```

availability のパラメータによって、指定された範囲内のみオブジェクトが有効となる。
[entityの詳細ページ](https://cesium.com/learn/cesiumjs/ref-doc/Entity.html)

この対応によって、円オブジェクトが2020/10/01～2020/12/01の間のみ表示される。

## ④ オブジェクト生成を関数化して何回も呼ぶ
後は作業。オブジェクト生成を関数化して、好きにするだけ。
サンプルコードでは、円の縦の長さ・横の長さ・生成開始時刻・生成終了時刻を引数にした関数を作成し、だんだん大きくなる様子を表現した。

最終形のソースコードは以下。
```index.js
import { TimeIntervalCollection,TimeInterval,Color,Clock,JulianDate,ClockRange,ClockStep,ClockViewModel,Ion, Viewer, createWorldTerrain, createOsmBuildings, Cartesian3, Math } from "cesium";
import "cesium/Build/Cesium/Widgets/widgets.css";
import "../src/css/main.css"

// Your access token can be found at: https://cesium.com/ion/tokens.
// This is the default access token
Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlYWE1OWUxNy1mMWZiLTQzYjYtYTQ0OS1kMWFjYmFkNjc5YzciLCJpZCI6NTc3MzMsImlhdCI6MTYyNzg0NTE4Mn0.XcKpgANiY19MC4bdFUXMVEBToBmqS8kuYpUlxJHYZxk';

// clockを定義
const clock = new Clock({
  startTime: JulianDate.fromIso8601("2020-01-01"),
  currentTime: JulianDate.fromIso8601("2022-12-25"),
  stopTime: JulianDate.fromIso8601("2022-12-25"),
  clockRange: ClockRange.LOOP_STOP, 
  clockStep: ClockStep.TICK_DEPENDENT,
  multiplier: 63200, 
  shouldAnimate: true,
});

// 表示画面を生成
const viewer = new Viewer('cesiumContainer', {
  terrainProvider: createWorldTerrain(),
  clockViewModel: new ClockViewModel(clock)
});

// オブジェクト生成
function entitySet(semiminoraxis, semimajoraxis, starttime, endtime)
{
  var entity = viewer.entities.add({
    availability: new TimeIntervalCollection([
      new TimeInterval({
        start: starttime,
        stop: endtime,
      }),
    ]),
    position: Cartesian3.fromDegrees(-103.0, 40.0),
    ellipse : {
      semiMinorAxis : semiminoraxis,
      semiMajorAxis : semimajoraxis,
      material : Color.BLUE.withAlpha(0.5)
    }
  });
}

// 良い感じで生成する
entitySet(400000.0, 400000.0, JulianDate.fromIso8601("2020-01-01"), JulianDate.fromIso8601("2020-04-01"))
entitySet(600000.0, 600000.0, JulianDate.fromIso8601("2020-04-01"), JulianDate.fromIso8601("2020-07-01"))
entitySet(800000.0, 800000.0, JulianDate.fromIso8601("2020-07-01"), JulianDate.fromIso8601("2020-10-01"))
entitySet(1000000.0, 1000000.0, JulianDate.fromIso8601("2020-10-01"), JulianDate.fromIso8601("2021-01-01"))
entitySet(1200000.0, 1200000.0, JulianDate.fromIso8601("2021-01-01"), JulianDate.fromIso8601("2021-04-01"))
entitySet(1400000.0, 1400000.0, JulianDate.fromIso8601("2021-04-01"), JulianDate.fromIso8601("2021-07-01"))
entitySet(1600000.0, 1600000.0, JulianDate.fromIso8601("2021-07-01"), JulianDate.fromIso8601("2021-10-01"))
entitySet(1800000.0, 1800000.0, JulianDate.fromIso8601("2021-10-01"), JulianDate.fromIso8601("2022-01-01"))
entitySet(2400000.0, 2400000.0, JulianDate.fromIso8601("2022-01-01"), JulianDate.fromIso8601("2022-04-01"))
entitySet(3000000.0, 3000000.0, JulianDate.fromIso8601("2022-04-01"), JulianDate.fromIso8601("2022-07-01"))
entitySet(3600000.0, 3600000.0, JulianDate.fromIso8601("2022-07-01"), JulianDate.fromIso8601("2022-10-01"))
entitySet(5000000.0, 5000000.0, JulianDate.fromIso8601("2022-10-01"), JulianDate.fromIso8601("2022-12-31"))
```

おしまい。