はじめに
GPS経路情報をCesium上で表示させましたが、Cesiumの地形情報と高度があっていなかっため、うまく表示ができませんでした。そこで、任意の座標から、Cesiumの地形情報からの高度を取得し、自動車の高度に設定してみました。高度の取得には、clampToHeight()メソッドを利用します。
提供される高度は準拠楕円体からの高さ(Ellipsoid.WGS84)楕円体高になります。
これは、平均海面からの高度である標高ではありません。なので、海でサンプリングした場合、必ずしも0.0になるとは限りません。
あと、自動車の方向が自動で変わらなかったので、自動車位置の差から角度を計算し、設定しました。角度設定には、HeadingPitchRollクラスを使いました。
実は、「Cesium」のデモサイトではほとんどか3Dモデルの角度設定にorientationのunitQuaternionを使って設定しているのですが、設定値が不明でうまくいきませんでした。そのため、あきらめて、HeadingPitchRollクラスを使いました。
このクラスではそれぞれの軸の角度を設定するだけなので、設定値が簡単に変更できました。heading,pitch,rollにそれぞれの軸の角度を設定すると、3Dモデルが回転します。Cesiumのサンプルには、なぜかこの処理がなく、自動で向きが変わっています。
以下、高度の取得及び設定プログラムです。今回は経路と自動車の位置でデータを分けています。
※czmlには、clampToGroundをtrueにしていましたが、高度の設定はされていませんでした。czmlの設定に問題があったのかもしれません。
以下参考ソースです。
<!DOCTYPE html>
<html lang="ja">`
<head>
<title>Hello World!</title>
<link rel="stylesheet" href="../Build/CesiumUnminified/Widgets/widgets.css" />
<script src="../Build/CesiumUnminified/Cesium.js"></script>
<style>
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
var viewer = new Cesium.Viewer("cesiumContainer", {
terrainProvider: Cesium.createWorldTerrain(),
});
var scene = viewer.scene;
var clock = viewer.clock;
var czmlOptions = {
clampToGround: true
};
var entity;
var positionProperty;
var prePosition;
viewer.dataSources.add(Cesium.CzmlDataSource.load('../Datas/clampToGround_load5.czml', czmlOptions)).then(function (ds) {
entity = ds.entities.getById("Vehicle");
viewer.trackedEntity = entity;
positionProperty = entity.position;
start();
});
viewer.dataSources.add(Cesium.CzmlDataSource.load('../Datas/clampToGround_load6.czml', czmlOptions));
function start() {
var objectsToExclude = [entity];
scene.postRender.addEventListener(function () {
var position = positionProperty.getValue(clock.currentTime);
if (position === undefined) {
return;
};
entity.position = scene.clampToHeight(position, objectsToExclude);
if (prePosition !== undefined) {
entity.orientation = calculateOrientation(prePosition, position);
}
prePosition = position;
});
}
function calculateOrientation(oldPosition, newPosition) {
var dX = oldPosition.x - newPosition.x;
var dY = oldPosition.y - newPosition.y;
var offSet = Cesium.Math.toRadians(135);
var heading = Math.atan2(dX, dY) - offSet;
if (heading > Cesium.Math.TWO_PI) {
heading -= Cesium.Math.TWO_PI;
}
var pitch = 0;
var roll = 0;
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var orientation = Cesium.Transforms.headingPitchRollQuaternion(oldPosition, hpr);
return orientation;
}
</script>
</body>
</html>