いやほんとJavaScriptとか普段触ってないから無理です……
概要
Cesiumを使って3次元データを可視化したいと思い立ったのがここ数日。ま,とにかく触ってみるか,ということで公式のQuickStartを動かしてみる……動かしてみる……動かない……
ということでイライラしていたものの最終的に動いたので備忘録。
注意
新しい技術なので仕方がないことだが,Cesiumは,たびたび,破壊的に仕様が変わるらしい(未確認情報)。なので,この内容がこの先どれだけ使えるか不明。
そもそも,同様の情報が見つからないところを見ると,とんでもなく基礎的なところで私が躓いているか,私の環境特有の問題なのかもしれない。
QuickStartで詰まるまで
公式はココ
アカウントを作って,tokenを取得する。
取得したtokenに合わせてQuickStartのコードが変わるという近未来な仕様にビビる。
さて,2つのコードがサンプルで掲載されている。きちんと動けばサンフランシスコの街の様子が表示されるらしい。
ひとつは素HTMLに<script>
で,モリモリJavaScriptを食わせて動かすコード。これは簡単そうだけれども,HTMLにコードがまとまってしまうというのが嫌。
ひとつは,JavaScript。これは,Webpack, Parcel, Rollupなどのモジュールバンドラーを使う場合に良いよ,と書いてある。そんなものは知らない(かろうじてnode.jsくらいは知ってる)ので,パス。
仕方がないので,前者で試すことにする。コードをコピペして,htmlを開く。
と,……宇宙空間に浮かぶ建物の様な何かが表示される……。サンフランシスコどこ?
開発者ツールで見ると,ファイルを読みに行くときに,セキュリティではじかれているっぽい。薄々思ってたけど,これ,index.html
を作ってブラウザで開くだけではダメなのでは?
ネットで見つかる情報も色々試してみたが,トークンの読み込みが全然うまくいかない。こりゃだめだ。
QuickStartを解決するまで
実際にはあれでもないこれでもないと紆余曲折していたが,結果だけ示す。
node.jsの導入
npmとnode.jsは,ずいぶん前に何かで導入していた。詳しくは忘れた。
これを使って,ローカルにcesiumを導入して,仮想サーバーで動かして,それをブラウザから見にいけばいいんじゃないか?という発想。
npm i cesium
でcesiumは簡単にインストールできた。バージョンは1.117
。
新しいファイル構成
-
node_modules/
:npmで勝手に入った -
package.json
:npmで勝手に入った -
package-lock.json
:npmで勝手に入った -
server.js
:node.jsを使って,サーバーサイドで動くプログラム -
index.html
:server.js
から呼び出すhtmlファイル -
cliant.js
:クライアントサイドのプログラム。index.html
から呼び出し
server.js
index.html
とclient.js
を分離するために,client.js
のリクエストがあった際の対応を記載しておく必要がある。
import http from 'http'
import fs from 'fs'
const server = http.createServer((req, res) => {
if (req.url === '/'){
fs.readFile("./index.html", (err, data) => {
if (err) {
console.log(err);
} else {
res.statusCode = 200;
res.setHeader("Content-Type", "text/html");
res.end(data);
}
});
} else if (req.url === '/client.js') {
fs.readFile("./client.js", (err, data) => {
if (err) {
console.log(err);
} else {
res.statusCode = 200;
res.setHeader("Content-Type", "text/javascript");
res.end(data);
}
});
}
})
server.listen(1337)
index.html
単にCesium.js
やclient.js
を呼び出しているだけ。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- Include the CesiumJS JavaScript and CSS files -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.117/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.117/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
<div id="cesiumContainer"></div>
<script src="client.js"></script>
</div>
</body>
</html>
client.js
元のQuickStartとほぼ同じ。Cesium.Ion.defaultAccessToken
にはトークンが必要。
async function initializeCesium() {
// Your access token can be found at: https://ion.cesium.com/tokens.
// This is the default access token from your ion account
Cesium.Ion.defaultAccessToken = 'hogehoge';
// Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
const viewer = new Cesium.Viewer('cesiumContainer', {
terrain: Cesium.Terrain.fromWorldTerrain(),
});
// Fly the camera to San Francisco at the given longitude, latitude, and height.
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(-122.4175, 37.655, 400),
orientation: {
heading: Cesium.Math.toRadians(0.0),
pitch: Cesium.Math.toRadians(-15.0),
}
});
// Add Cesium OSM Buildings, a global 3D buildings layer.
const buildingTileset = await Cesium.createOsmBuildingsAsync();
viewer.scene.primitives.add(buildingTileset);
}
initializeCesium();
QuickStart(修正版)
- 上のファイル一式を用意する
- コンソールから
node server.js
を実行 - ブラウザで
localhost:1337
を開く
WELCOME TO SAN FARANCISCO!!!!
あーよかった。
Cesium完全に理解した。