cesium.js官网教程之中文版本~~~~第一篇
翻译地址:https://cesiumjs.org/tutorials/Cesium-Workshop/
翻译者:嬴渠梁
概述
欢迎来到cesuim社区!很高兴你的到来。为了发展你自己的网络地图应用成为可能,本教程将会从头到尾的介绍一个简单的cesium开发过程。本教程将提及大部分重要的cesium API,但是它并不意味着全面(cesium 有很多特征)。我们的目的是介绍一下基本原理和工具,剩下由你自己探索cesium!
我们将要创建一个简单的应用程序来可视化纽约的地貌,我们将要加载多种2d和3d数据并且创建几个摄像头和显示选项让用户交互,最后,我们将加载3D模型的无人机侦察地理缓存的位置,我们充分利用我们的三维可视化。
最后,你将了解cesium工作原理和如何配置cesium、加载数据集、创建有风格的几何图形、创建3d瓦片、控制照相机、并将鼠标交互添加到应用中。
安装
只需要几步就可以搭建出开发环境
1、通过访问helloworld这个示例来确保你的浏览器跟cesium兼容,如果不兼容,请查看故障
2、安装 node.js
3、提取代码https://github.com/AnalyticalGraphicsInc/cesium-workshop,克隆或下载zip都行
4、通过cmd导航到cesium项目的根路径
5、执行 npm install
6、执行 npm start
控制台就会显示Cesium development server running locally. Connect to http://localhost:8080/,不要关闭控制台
然后,通过浏览器访问 http://localhost:8080,你应该看到项目启动和运行,卡住了?入门教程更深入的介绍了cesium的设置。
应用目录
现在参观我们的应用目录吧!注意这个应用目录尽可能设计的简单,并且忽略了今天各种不同的现代js框架,但是一旦你掌握了cesium,就可以自由使用它!
source: 我们的应用代码和数据
ThirdParty: 外部库,只是cesium库
LICENSE.md:项目使用的条款或协议
index.html: 项目主页
server.js: 服务启动文件
现在看一下index.html,里面有一个div和几个input,观察一下cesium只是一个div,跟其他div没什么两样
首先,在head标签里引入cesium.js库,它定义了cesium对象,该对象包含了cesium所有的库
<script src="ThirdParty/Cesium/Cesium.js"></script>
cesium附带了一组需要此CSS的小部件。
<style>@import url(ThirdParty/Cesium/Widgets/widgets.css);</style>
在body标签里面创建一个div存放cesium小部件。
<div id="cesiumContainer"></div>
最后,我们在body最底下创建script标签引入App.js
<script src="Source/App.js"></script>
就是这样,剩下的html用来收集用户数据,我们一会用到
开发资源
对于本概要和贯穿剩下的cesium的开发生涯,我们鼓励你依赖下列资源:
referenceDocument(参考文档):包含许多代码段的cesium API的完整指南
SandCastle(沙塔):具有大量代码库的实时编译环境
Tutorials(教程):cesium开发领域的详细介绍
Cesium Forum(cesium讨论):cesium相关问题的讨论问答资源
无论何时你陷入困境,这些资源或许会给你答案
工作流程
跟着这个教程学:
1、用你最喜欢的编辑器打开 Source/App.js ,编辑和修改内容
2、把Source/AppSkeleton.js的代码复制到Source/App.js期内容注释的版本代码
3、确定你的服务器仍然运行在根目录,如安装所述
4、导航到http://localhost:8080,你应该看到一个黑色的页面
5、按照指导,代码注释掉,保存Source/App.js,刷新页面,你将看到新变化
又卡主了?你可以通过沙塔和应用程序的简化版本来在线查看(不过没有UI)
The complete code(完整的代码)
The commented code(注释掉的代码)
好了现在让我们开始吧
创建一个观察者(查看器)
cesium应用的基础就是观察者,这是一个3d交互式的球体,他有很多功能。添加观察者到 id 为 cesiumContainer 的div里面,通过取消注释第一行。
var viewer = Cesium.viewer('cesiumContainer')
备注:你这发现上面这行代码不能显示出来地球仪,因为你需要有一个bingmap的key:我的key给大家用一下吧,代码如下:
//设置key值
Cesium.BingMapsApi.defaultKey = 'SHHFsraTruJW1WlBZo4W~Voo0XWCy1Zt2-2iAVLxvFQ~Ai_3AucRsH-FTKgfBT34iPCl128DNCGslmWLM0Hplg9UgMZoftwZFkKbhHu_RAo8' var viewer = new Cesium.Viewer('cesiumContainer');
如果大家要注册自己的key,注册地址如下:https://www.bingmapsportal.com/Application ,当然你得先注册账号并且登录进去
这一行中有很多事情发生,你将会看到像这样的一个地球仪:
默认情况下场景处理鼠标和输入事件,现在可以尝试用默认的相机来控制地球仪吧:
1、鼠标单击左键并拖动鼠标,将相机移到地球表面
2、鼠标右键单击并拖动鼠标,放大和缩小相机
3、鼠标中间轮滚动,也能放大和缩小相机
4、鼠标中间轮点击和拖动,旋转相机周围的点在地球表面。
除了地球仪之外,Viewer还附带一些默认的有用的小部件,在上面的图片中标出。
图片数字1、Geocoder(地图编码器):一个位置搜索工具,用照相飞机查询位置。默认使用bingMap地图数据
图片数字2、Home Button(主页按钮):返回默认视图
图片数字3、Scene Mode Picker(场景模式选择器):在3D、2D、哥伦布图、CV模式之间来回切换
图片数字4、Basic Layer Picer(基础层显示器):选择图像和地形显示在地球上
图片数字5、Naviagtion Help Button(导航帮助按钮):显示默认摄像头的控价
图片数字6、Animation(动画):显示视图的播放数度
图片数字7、Timeline(时间轴):指示当前时间,并允许用户使用洗刷器跳转到特定时间
图片数字8、Credits Display(显示器):数据分配点,几乎总是用到
图片数字9、Fullscreen Button(全屏):全屏
我们可以配置我们的查看器来包含或排除这些功能,而更多的是通过在创建选项对象时作为参数。 对于这个应用程序,删除第一行并通过取消注释接下来的几行来配置新的查看器:
var viewer = new Cesium.Viewer('cesiumContainer', { scene3DOnly: true, //只使用3D(图片数字3消失) selectionIndicator: false, //选择指示符 baseLayerPicker: false //基础层拾取器(图片数字4消失) });
这将创建一个没有选择指示器,基础层选取器或场景模式选择器小部件的查看器,因为这些对于我们的应用程序来说是不必要的。 有关完整的Viewer选项,请参阅Viewer文档。
添加图像
cesium应用程序下一个关键元素就是添加图像,在不同分辨率下我们将图像集平铺到虚拟球上,为了提供最佳性能,Cesium只请求和渲染在当前视图中可见并且分辨率(也称为缩放比例)适合摄像机与地球表面的距离以及地球仪的maximumScreenSpaceError的图像块。
为了更直观地了解图像如何工作,请查看Cesium Inspector。
cesium提供了很多工具来处理图像层,如颜色调整和图层混合。 一些代码示例:
1、add basic imagery; 添加基本图像
2、Adjusting imagery colors; 修改图像颜色
3、Manipulating and ordering imagery layers; 操作和订购图层
4、Splitting imagery layers; 分割图层
Cesium提供了许多不同提供商提供的图像支持。
支持的图像格式如下:
利用具有地理空间位置信息的数据制作地图。其中将地图定义为地理数据可视的表现。这个规范定义了三个操作:
(1)GetCapabitities 返回服务级元数据,它是对服务信息内容和要求参数的一种描述;
(2)GetMap 返回一个地图影像,其地理空间参考和大小参数是明确定义了的;
(3) GetFeatureInfo(可选)返回显示在地图上的某些特殊要素的信息。
- TMS
- WMTS (with time dynamic imagery)
- ArcGIS
- Bing Maps
- Google Earth
- Mapbox
- Open Street Map servers
- Single tile 单一瓦片
默认情况下,Cesium将Bing地图用于图像。 要小心,不同的数据提供者具有不同的归因要求 - 确保您有权使用来自特定提供者的数据,并将其归入信用容器(如果适用)。 与查看器一起打包的图像主要用于演示目的。 为了在我们的应用程序中使用Bing图像集,我们需要获取我们自己的Bing key。 用这样的一行设置Bing键(在我们的应用程序的顶部,在创建查看器之前):
Cesium.BingMapsApi.defaultKey = 'AsarFiDvISunWhi137V7l5Bu80baB73npU98oTyjqKOb7NbrkiuBPZfDxgXTrGtQ'; // For use in this application only. Do not reuse!
同样,不同的图像提供商对使用的要求也会有所不同。 现在我们有权使用这个图像集,我们实际上可以添加图像层。 首先,我们创建一个ImageryProvider,传入一个数据url和一些配置选项,然后将ImageryProvider添加到viewer.imageryLayers。
// Add Bing imagery viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({ url : 'https://dev.virtualearth.net', mapStyle: Cesium.BingMapsStyle.AERIAL // Can also use Cesium.BingMapsStyle.ROADS 参数如下:AERIAL_WITH_LABELS 、ROAD 、CANVAS_DARK 、CANVAS_LIGHT 、CANVAS_GRAY 、ORDNANCE_SURVEY 、COLLINS_BART }));
随着上面的代码添加,我们的应用程序应该看起来像这样,当你放大:
这实际上与默认图像样式相同,但可以随意使用 BingMapsStyle 来查看差异。
有关图像的更多信息,请参阅我们的图像图层教程。
添加地形
cesium支持对海洋,湖泊和河流的全球高分辨率地形和水影响进行流式传输和可视化。 与2D地图相比,山峰,山谷和其他地形特征确实显示出3D地球的优势。 像图像一样,cesium引擎将从服务器传输地形数据,只根据当前摄像机的位置请求和渲染瓦片。
以下是地形数据集和配置选项的一些演示:
- ArcticDEM : 高分辨率的北极地形
- PATerrain : 高分辨率宾夕法尼亚地形
- Terrain display options : 一些地形配置选项和格式
- Terrain exaggeration : 使地形高程差异更加显着
支持的地形格式:
- Our own quantized-mesh format 我们自己量化的网格格式
- Heightmap 高度图
- Google Earth Enterprise 谷歌地球企业版
为了添加地形数据,我们创建一个 CesiumTerrainProvider,,指定一个数据url和一些配置选项,然后将这个提供者添加为viewer.terrainProvider。
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ url : 'https://assets.agi.com/stk-terrain/world', requestWaterMask : true, // required for water effects requestVertexNormals : true // required for terrain lighting });
requestWaterMask和requestVertexNormals是配置选项,告诉Cesium为水和灯光效果请求额外的数据。 默认情况下,这些设置为false。
最后,现在我们已经有地形了,我们只需要再多一行来确保地形背后的物体被正确地遮挡。 只有最前面的对象才可见。
我们现在有地形和生气的水。 纽约是相当平坦的,所以随时探索,以便看到新的地形在行动。 举一个特别明显的例子,您可以导航到更加崎岖的地区,如大峡谷或旧金山。
配置场景
现在只需稍微安装一下,即可在适当的位置和时间启动查看器。 这涉及与viewer.scene交互,这是查看器中所有图形元素的容器。
首先,我们可以配置我们的场景,以根据太阳的位置使用此线来选择性地启用照明。
// Enable lighting based on sun/moon positions (根据太阳/月亮位置启用照明) viewer.scene.globe.enableLighting = true;
这将使我们的场景中的照明随着时间的变化而变化,这样当太阳不能看的时候,你可以看到地球的一部分变暗。
接下来,在我们开始设置初始视图之前,让我们回顾一下几个基本的Cesium类型:
- Cartesian3 : a 3D Cartesian point – when used as a position it is relative to the center of the globe in meters using the Earth fixed-frame (ECR)
- 三维笛卡尔点 - 当用作位置时,它使用地球固定框架(ECR)以米为单位,相对于地球的中心
- Cartographic : a position defined by latitude/longitude (in radians) and height off the globe’s surface
- 由纬度/经度(弧度)和地球表面的高度定义的位置
- Heading Pitch Roll : A rotation (in radians) about the local axes in the East-North-Up frame. Heading is the rotation about the negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about the positive x axis.
- 帧中围绕本地轴的旋转(以弧度表示)。 标题是围绕负z轴的旋转。 间距是围绕负y轴的旋转。 滚动是围绕正x轴的旋转。
- Quaternion : A 3D rotation represented as 4D coordinates.
- 3D旋转表示为4D坐标。
这些是在场景中定位和定位铯物体所需的基本类型,并且有许多有用的转换方法。
现在让我们把我们的场景放在我们的数据所在的纽约市。
相机控制
Camera是viewer.scene 的一个属性,并控制当前可见的内容。 我们可以通过直接设置摄像机的位置和方向来控制摄像机,也可以使用Cesium摄像机API来设置摄像机的位置和方向。
一些最常用的方法是:
- Camera.setView(options) : set camera at specific position and orientation immediately
- 立即将相机置于特定的位置和方向
- Camera.zoomIn(amount) : move camera forward along the view vector
- 沿相机向前移动相机
- Camera.zoomOut(amount) : move camera backwards along the view vector
- 沿相机向后移动相机
- Camera.flyTo(options) : animates movement from current position to a new position
- 将动作从当前位置移动到新的位置
- Camera.lookAt(target, offset) : orient and position the camera to look at target point with given offset
- 定位和定位相机以给定偏移量来查看目标点
- Camera.move(direction, amount) : move the camera in any direction
- 向任何方向移动相机
- Camera.rotate(axis, angle) : rotate the camera about any axis
- 围绕任何轴旋转相机
要了解API可以做什么,请查看这些相机演示:
- Camera API Demo 相机API演示
- Custom Camera Controls Demo 定制相机控制演示
现在让我们通过将相机移动到纽约来尝试其中的一种方法。 使用camera.setView()设置初始视图,使用Cartesian3和HeadingPitchRoll作为位置和方向:
// Create an initial camera view var initialPosition = new Cesium.Cartesian3.fromDegrees(-73.998114468289017509, 40.674512895646692812, 2631.082799425431); var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949054, 0.025883251314954971306); var homeCameraView = { destination : initialPosition, orientation : { heading : initialOrientation.heading, pitch : initialOrientation.pitch, roll : initialOrientation.roll } }; // Set the initial view viewer.scene.camera.setView(homeCameraView);
摄像机现在定位和定位,以低头曼哈顿,我们的视图参数保存在一个对象,我们可以传递给其他相机的方法。
实际上,我们可以使用这个相同的视图来更新按下主页按钮的效果。 而不是让我们从远处返回到地球的默认视图,我们可以覆盖按钮,使我们能够看到曼哈顿的初始视图。 我们可以通过添加更多选项来调整动画,然后添加一个取消默认航班的事件侦听器,并调用flyTo()我们的新主视图:
// Add some camera flight animation options homeCameraView.duration = 2.0; homeCameraView.maximumHeight = 2000; homeCameraView.pitchAdjustHeight = 2000; homeCameraView.endTransform = Cesium.Matrix4.IDENTITY; // Override the default home button viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function (e) { e.cancel = true; viewer.scene.camera.flyTo(homeCameraView); });
有关基本相机控件的更多信息,请查看我们的相机教程。
时钟控制
接下来,我们可以配置观看者时钟和时间线来控制场景中的时间流逝。
这里是时钟API的行动。
在特定时间工作时,Cesium使用JulianDate类型,该类型存储自公元前4712年1月1日(公元前4713年)中午以来的天数。 为了提高精确度,该类将日期的整数部分和日期的秒部分存储在单独的组件中,为了算术安全并表示闰秒,日期总是存储在国际原子时间标准中。
以下是我们如何设置场景时间选项的示例:
// Set up clock and timeline. viewer.clock.shouldAnimate = true; // default viewer.clock.startTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z"); viewer.clock.stopTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:20:00Z"); viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z"); viewer.clock.multiplier = 2; // sets a speedup viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; // tick computation mode viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // loop at the end viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime); // set visible range
这将设置场景动画的速率,开始和结束时间,并告诉时钟在到达结束时间时循环。 它还将时间线设置为适当的时间范围。 看看这个时钟的例子代码来试验时钟设置。
这就是我们最初的场景配置! 现在,当您运行应用程序时,您应该看到以下内容: