什么是cesium?
Cesium是一款开源的基于JavaScript的3D地图框架。其实他就是一个地图可视化框架
CesiumJS 是一款用于创建虚拟场景的3D地理信息平台。目标是用于创建以基于Web的地图动态数据可视化。目前尽力提升平台的性能、准确率、虚拟化能力、易用性以及平台的各种支持。
数据格式与功能特性
Cesium支持3D Tiles、Terrain and Imagery Layers、3D Models(glTF)、Vectors and Geometry(Load KML, GeoJSON, TopoJSON, and CZML)、Time-Dynamic Visualization、3D, 2D, and 2.5D Columbus View
支持2D,2.5D,3D 形式的地理(地图)数据展示,
可以绘制各种几何图形、高亮区域,支持导入图片,甚至三维模型等多种数据可视化展示
可用于动态数据可视化并提供良好的触摸支持,支持绝大多数的浏览器和移动端浏览器。
支持基于时间轴的动态流式数据展示
cesium环境搭建及第一个示例
Cesium需要浏览器支持WebGL,可以通过CesiumJS官网提供的一个HelloWorld例子来测试自己的浏览器是否支持Cesium。(推荐使用Chrome) 测试地址: https://cesiumjs.org/Cesium/Apps/HelloWorld.html
下载最新的cesium源码,然后用vscode打开。
然后安装server端:
Cesium是纯前端的代码,官方给出的源代码中,配套了nodejs的server端,以及可以通过nodejs进行安装部署。实际上可以将Cesium部署进入tomcat(geoserver)、apache、nginx等服务器中。
官网推荐的是nodejs
从官网中下载Node.js(https://nodejs.org/en/), 实际上nodejs有一些参数可是配置,使用默认的参数即可。.
在Cesium所在的文件夹目录,打开cmd或者bash敲入命令
npm install
下载依赖的npm模块,比如express等。如果成功,会在Cesium文件夹中床架 ‘node_modules’文件夹。
然后npm start启动服务器
不能关闭控制台,保持一直运行状态。打开浏览器,输入 http://localhost:8080 即可访问Cesium.
如果你不想用nodejs
Cesium是一个开源项目,GitHub上的下载地址为:https://github.com/AnalyticalGraphicsInc/cesium 最简单的安装方式,就是普通的JS文件加载,只需要从Github中下载其js代码,放到自己的项目中,在html页面中引用即可。如下:
新建一个helloworld.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello 3D Earth</title>
<script src="CesiumUnminified/Cesium.js"></script>
<style>
@import url(CesiumUnminified/Widgets/widgets.css);
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script src="app.js"></script>
</body>
</html>
新建一个app.js
viewer = new Cesium.Viewer('cesiumContainer');
其中cesiumContainer为html中的地图显示div的id。就是这么简单,浏览器打开上述html页面,便可看到一个三维地球。底图为微软影像只是加载到了三维地球上,包含放大、缩小、平移等基本在线地图功能,同时还包含了时间轴等与时间有关的控件,这是Cesium的一个特色,其地图、对象以及场景等能与时间相关联。
cesiumwidget分析
如上图我们可以看到cesium.view包含了ui以及一些其他组件。
如上图,cesiumwidget是一个更纯粹的三维地球,我们来看看他包含了什么?
比如我构建了一个地球,我需要在地球上放一些东西,那么就放到primitives和groundprimitives,前者就是普通的放在地面上,而后者是与地面贴合。
billboards指的是图片,当我把3d地图放大或缩小时,该图片都不会随着我的操作变大变小,就像照相一样,距离隔得越远,物体看起来越小,billboard就是让物体跟正常一样大小,不论远近。
labels是指文字,这是3维的文字,可能会很模糊。
points就是点。
注意都是加了s的,也就是cesium并不是一个一个为我们渲染的,比如billboards里面有很多billboard对象,为了达到渲染效率,则底层是一次性渲染。
primitive可以自定义集合体,比如三角形之类的。
model是飞机,小车,小人这种模型。
model的使用
如上图,使用scene.primitives.add创建的,就是往图元里加东西。
url填gltf文件的路径,modelMatrix控制模型的姿态, minimumPixelSize: 128是指模型缩放最小为128个像素。
var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
origin,
hpr
);
来看看modelMatrix是怎样定义的,headingPitchRoll是一个欧拉角,heading是表示航向,pitch是飞机往上冲还是往下冲,roll我们一般不用。
var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
var origin = Cesium.Cartesian3.fromDegrees(
-123.0744619,
44.0503706,
height
);
origin表示飞机的xyz坐标。
然后必须要要经过如下的readyPromise才能有显示。
model.readyPromise
.then(function (model) {
model.color = Cesium.Color.fromAlpha(
getColor(viewModel.color),
Number(viewModel.alpha)
);
model.colorBlendMode = getColorBlendMode(
viewModel.colorBlendMode
);
model.colorBlendAmount = viewModel.colorBlendAmount;
// Play and loop all animations at half-speed
model.activeAnimations.addAll({
multiplier: 0.5,
loop: Cesium.ModelAnimationLoop.REPEAT,
});
var camera = viewer.camera;
相机用来观察模型。
camera.lookAt(
center,
new Cesium.HeadingPitchRange(heading, pitch, r * 2.0)
);
lookat函数是让相机从哪种姿态观察,是围绕一个中心点观察。
然后camera.lootAtTransform(cesium.Matrix4.IDENTITY);可以解除中心点。
如果想看上述文档,要执行npm run generateDocumentation
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function (movement) {
var pick = scene.pick(movement.endPosition);
if (
Cesium.defined(pick) &&
Cesium.defined(pick.node) &&
Cesium.defined(pick.mesh)
) {
// Output glTF node and mesh under the mouse.
console.log(
"node: " + pick.node.name + ". mesh: " + pick.mesh.name
);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
上述代码使指当鼠标移动到model时,拾取一些信息。
不一定每个model都有node和mesh信息。
上图是toolbar对应的窗口
<select data-bind="options: colorBlendModes, value: colorBlendMode"></select>
colorBlendModes代表model里有几项,而value表示每一项是什么。
下面定义了viewModel,里面所含属性就是data-bind里的。
var viewModel = {
color: "White",
colors: ["White", "Red", "Green", "Blue", "Yellow", "Gray"],
alpha: 1.0,
colorBlendMode: "Highlight",
colorBlendModes: ["Highlight", "Replace", "Mix"],
colorBlendAmount: 0.5,
colorBlendAmountEnabled: false,
};
// Convert the viewModel members into knockout observables.
Cesium.knockout.track(viewModel);
上述代码就是将普通的viewModel变成响应式对象,用户动,它也动。
// Bind the viewModel to the DOM elements of the UI that call for it.
var toolbar = document.getElementById("toolbar");
Cesium.knockout.applyBindings(viewModel, toolbar);
上述代码就是将viewModel将toolbar关联。
Cesium.knockout
.getObservable(viewModel, "colorBlendMode")
.subscribe(function (newValue) {
var colorBlendMode = getColorBlendMode(newValue);
model.colorBlendMode = colorBlendMode;
viewModel.colorBlendAmountEnabled =
colorBlendMode === Cesium.ColorBlendMode.MIX;
});
上述代码的意思是当检测到colorBlendMode变化后,将三维窗口中的colorBlendModel更新为刚刚变化的。
上图是一次性创建多个飞机,值得注意的是该类在documentation中是查不到的,只能从vscode里面看这个类的实现方式。
从上图我们可以看到model也可有若干节点组成。
// enumerate nodes and add options
var options = Object.keys(model._runtime.nodesByName).map(function (
nodeName
) {
return {
text: nodeName,
onselect: function () {
viewModel.nodeName = nodeName;
},
};
});
上述代码是获取节点名从而获取节点。