本篇文章请搭配
[3D地图-CesiumJS系列] 一、快速上手
不知道大家在飞机上时会不会好奇飞机行进到哪里?
飞行高度多少?飞行轨迹如何?
身为好奇宝宝的我们,常常会盯着座位萤幕前的3D飞航示意图呢!
今天就要来介绍怎麽使用CesiumJS来制作一个飞航轨迹图。
本篇文章使用官方范例来介绍。
复习一下昨天介绍的初始化地图的方式吧!如果还不会CesiumJS专案建置的人,请参考昨天的文章。
在根目录下建立一个html页面,取名为Cesium_airplane.html。
↓ 建立一个存放地图的div
<div id="cmap"></div>
↓ 引入Cesium.js
<script src="../Build/Cesium/Cesium.js"></script>
↓ 引入css
<link rel="stylesheet" href="../Build/Cesium/Widgets/widgets.css" />
↓ css让地图满版
<style>
html,
body,
#cmap {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
↓ 设定API Key,如果想要载入自己上传的图层或模型,就要载入自己的key,官网注册连结。
Cesium.Ion.defaultAccessToken = yourAPIKey;
↓ 初始化地图,新建一个Cesium.Viewer的物件,第一个参数存放地图的容器Id,第二个参数为设定(选填)。
const viewer = new Cesium.Viewer('cmap', {
terrainProvider: Cesium.createWorldTerrain() // 建立地形
});
↓ 结果
↓ 花东纵谷,未使用Cesium.createWorldTerrain()
↓ 花东纵谷,使用Cesium.createWorldTerrain()
明显较能感受到地形高低起伏。
↓ 建立3D建物的图层
const osmBuildings = viewer.scene.primitives.add(Cesium.createOsmBuildings());
↓ 台北信义区,未使用Cesium.createOsmBuildings()
顶多出现高楼层建筑物的阴影。
↓ 台北信义区,使用Cesium.createOsmBuildings()
只要有登记3D建模的建筑物都会清楚呈现。
这边为求方便,直接使用范例航班数据下载。
↓ 资料格式
const data = [{ "longitude": 121.523333, "latitude": 25.15, "height": 3000 }, { "longitude": 120.3508, "latitude": 23, "height": 12000 }]
↓ 把读取的json资料格式转为物件/阵列後,即可使用。
const flightData = JSON.parse(data);
↓ 设定时间区间、起始时间、时间轴动画
const timeSpan = 30;
const totalSeconds = timeSpan * (flightData.length - 1);
const start = Cesium.JulianDate.fromIso8601("2020-10-13T21:10:00Z");
const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate());
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.timeline.zoomTo(start, stop);
viewer.clock.multiplier = 50;
viewer.clock.shouldAnimate = true;
↓ 时间轴由设定的时间开始跑
↓ 刚刚设定的时间区间及每个点座标资讯,用Cesium.SampledPositionProperty()建立的物件来储存。
const timeSpan = 30;
const positionProperty = new Cesium.SampledPositionProperty();
↓ 跑回圈,设定每个点的时间区间、座标、高度,并把它们加入positionProperty物件中,最後并把点加入地图(viewer)中。
flightData.forEach((item, index) => {
const time = Cesium.JulianDate.addSeconds(start, index * timeSpan, new Cesium.JulianDate());
const position = Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, item.height);
positionProperty.addSample(time, position);
viewer.entities.add({
description: `经度: ${item.longitude}, 纬度: ${item.latitude}, 海拔高度: ${item.height})`,
position: position,
point: { pixelSize: 10, color: Cesium.Color.ORANGE }
});
});
↓ 飞航轨迹
↓ 从侧面看,飞航轨迹横越大西洋
↓ 把地图投影成平面後,会发现最短距离在平面地图上是弧形的
可以在Cesium的官方平台上,上传飞机模型,上传完毕後会得到一组飞行模型的Id。
↓ 上传介面
↓ 选择GITF格式
↓ 上传成功,获得该飞行模型的Id。
↓ 地图载入飞机模型,并将它设定至飞航轨迹的实体。
const airPlaneId = 164161;
async function LoadAirPlaneModel() {
const airplaneUri = await Cesium.IonResource.fromAssetId(airPlaneId);
const airplane = {
availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: stop })]),
position: positionProperty,
model: { uri: airplaneUri },
orientation: new Cesium.VelocityOrientationProperty(positionProperty),
path: new Cesium.PathGraphics({ width: 3 })
}
viewer.trackedEntity = viewer.entities.add(airplane);
}
↓ airplaneUri也可以直接读取官网的范例飞机模型连结。
const airplaneUri = 'https://sandcastle.cesium.com/SampleData/models/CesiumAir/Cesium_Air.glb';
↓ 呼叫
LoadAirPlaneModel();
↓ 机场中滑行
↓ 空中转向
↓ 快速飞越陆地
↓ 海面上飞行
看着飞机再飞是不是很疗癒呢?
大家赶快也来玩看看吧!
<<: 资安这条路 28 - [作业系统] Windows、Linux
>>: [Day 28] - Gatsby feat. EC ( 下 )
前言: Kotlin Coroutine , Coroutin (中文翻 “协程” )这个词在and...
这个章节的重点在於资讯管理系统的实体环境的保护。 不是这种保护 XD 不过,比较常跟受稽方讨论到乖乖...
原因: pyinstaller 的一些版本是这样的; 打包的是PIE executable的执行档案...
今天要来介绍的部分是资料流重新导向的部分,这个东西其实就是字面上的意思,就是将某个指令成功执行後所要...
一、认识RPA之後,最想处理文件类型的自动化 已经研究了解RPA基本概念与逻辑的企业,接下来都会开始...