Posted at

Cesiumで動的にオブジェクトを追加する(見せかけ)

More than 1 year has passed since last update.


Cesiumで遊んだ記録

用意するもの



  • ここからダウンロード

  • コンソールを開いて

python -m SimpleHTTPServer


test.html

<!DOCTYPE html>

<html lang="jp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>mapping</title>
<script src="Build/Cesium/Cesium.js"></script>
<style>
@import url(Build/Cesium/Widgets/widgets.css);
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
var viewer = new Cesium.Viewer('cesiumContainer');
</script>
</body>
</html>

earth1.PNG

わぁ!?なんかしゅごいね!しゅごい!ああっこれしゅごいのおぉ!

マウスでクルクル回せるしマップを切り替えられるし・・・これは遊べる!!...

いろいろオブジェクトを追加できるみたい 一覧

適当に日本の上に円柱を立ててみる


test.html

var viewer = new Cesium.Viewer('cesiumContainer' , {navigationHelpButton: true, animation: false, timeline: false, infoBox: false, fullscreenButton: true,});

//object sample
viewer.entities.add({name : 'Cylinder',position: Cesium.Cartesian3.fromDegrees(139.691717, 35.689568, 2000000),cylinder : {length : 4000000,topRadius : 100000, bottomRadius : 100000,material : Cesium.Color.BROWN.withAlpha(0.5),}});


e2.PNG

これをアニメーションみたいな動かせたら面白い

ここでドキュメントのアニメーションを見るとガッカリするので見ないこと!


本題

アニメーション風にオブジェクトを追加したい

本当はczmlを使うらしい データを作るのが面倒そう

せや!1秒毎に呼び出せばいいや(´・_・`)

データはどうしようかな・・・Apacheのアクセスログ使ったろ


準備


コード


<!DOCTYPE html>
<html lang="jp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>mapping</title>
<script src="Build/Cesium/Cesium.js"></script>
<style>
@import url(Build/Cesium/Widgets/widgets.css);
@import url(mapping.css);
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
</style>
</head>
<body>
<div id="buttonContainer">
<input type="number" name="jikan" size=3 id="jikan" value="1000" step="10" min="1" max="10000">
<button onclick="start_animation()" class="cesium-button">Start Animation</button>
</div>
<div id="cesiumContainer"></div>
<script>
//cesium
var viewer = new Cesium.Viewer('cesiumContainer' , {navigationHelpButton: true, animation: false, timeline: false, infoBox: false, fullscreenButton: true,});
var defLen = 10000;

function start_animation() {
var cc_cnt = {}
loopSleep(cc_list.length-1, document.getElementById ('jikan').value, function(i) {
try {
var cc_s = new String(cc_list[i]).split(',');
console.log(cc_s);
for (var i in cc_s) {
var cc = cc_s[i];
var c_code = wl[cc_s[i]].split(',');
var lat = c_code[1];
var lon = c_code[0];
console.log(lat + "," + lon);
if (cc in cc_cnt) {
tl = cc_cnt[cc] + defLen;
cc_cnt[cc] = tl;
} else {
cc_cnt[cc] = defLen;
}
var center = cc_cnt[cc];
var len = center * 2;
ent = {id : cc,position: Cesium.Cartesian3.fromDegrees(lat, lon, center),cylinder : {length : len,topRadius : 100000, bottomRadius : 100000,material : Cesium.Color.BROWN.withAlpha(0.5),}}
try {
viewer.entities.add(ent);
}catch(e){
et = viewer.entities.getById(cc);
viewer.entities.remove(et);
viewer.entities.add(ent);
}
}
}catch(e){}
});
}

function loopSleep(_loopLimit,_interval, _mainFunc) {
var loopLimit = _loopLimit;
var interval = _interval;
var mainFunc = _mainFunc;
var i = 0;
var loopFunc = function () {
var result = mainFunc(i);
if (result === false) {return;}
i = i + 1;
if (i < loopLimit) {setTimeout(loopFunc, interval);}
}
loopFunc();
}

//load cc data
var cc_list = []
function load_cc(file_name){
var req = new XMLHttpRequest();
req.open("get", file_name, true);
req.send(null);
req.onload = function(){
var tmp = req.responseText.split("\n");
for (var i = 0; i < tmp.length; i++) {
cc_list[i] = tmp[i].split(',');
//console.log(tmp[i].split(',')[2]);
}
}
}
load_cc('demo.csv')

//load location data
var wl = {}
function load_wl(file_name) {
var req = new XMLHttpRequest();
req.open("get", file_name, true);
req.send(null);
req.onload = function() {
var tmp = req.responseText.split("\n");
for (var i = 0; i < tmp.length; i++) {
var ch = tmp[i].split(",");
wl[ch[0]] = ch[1] + "," + ch[2];
}
}
}
load_wl('world_location.csv');

</script>
</body>
</html>

左上のStart Animationのボタンを押すとCSVを左の数値ミリ秒毎読み込み累積するように表示する

e5.gif


地球儀を回転させたい

ほぼこぴぺ以下を追加


<div id="buttonContainer">
<input type="number" name="sokudo" size=3 id="sokudo" value="0.5" step="0.1" min="0.1" max="10">
<button onclick="start_rotation()" class="cesium-button">Start Rotation</button>
<button onclick="stop_rotation()" class="cesium-button">Stop Rotation</button>
<br>
<input type="number" name="jikan" size=3 id="jikan" value="1000" step="10" min="1" max="10000">
<button onclick="start_animation()" class="cesium-button">Start Animation</button>
</div>

var camera = viewer.camera;
var clock = viewer.clock;
var eventHelper = new Cesium.EventHelper();
var removeCallback;
var rot_flag = false;
var defLen = 10000;

function start_rotation() {
if (!rot_flag) {
rot_flag = true;
removeCallback = eventHelper.add(clock.onTick, onTick);
}
}

function stop_rotation() {
if (rot_flag) {
removeCallback();
rot_flag = false;
}
}

function onTick() {
var horizontalDegrees = document.getElementById ('sokudo').value;
var viewRect = camera.computeViewRectangle();
if (Cesium.defined(viewRect)) {
horizontalDegrees *= Cesium.Math.toDegrees(viewRect.east - viewRect.west) / 360.0;
}
camera.rotateRight(Cesium.Math.toRadians(horizontalDegrees));
}

Start Rotationで回転Stop Rotationで停止

左の数値で回転速度の調整

e6.gif

以上です。すぐに遊べるようGitに一式うp


余談

みんなgifアニメーションってどうやってるんだろう・・・って思って自分なりの確立したやり方書きます

環境はwindows10


  • win + g

無1.png

を表示させ、はい、これを・・・にチェックを入れる


  • 再びwin + g

無2.png

で赤いボタンを押して録画開始


  • 必要に応じてAviUtlなど使って画面を切り取る

  • mp4ファイルをgifに変換する

  • 最初はConvertioを使って20MB程度にしてアップしたが再生されず


  • Free Video to GIF Converterを使い画像サイズを小さくしたり、不要な画像を削除したりして作成しました