Cesium简介

2年前前端教程31688
Cesium简介 floating_heart 已于2022-07-03 16:15:05修改 4053 收藏 20 分类专栏: Cesium 文章标签: 3d html5 javascript 前端 于2022-06-26 10:07:05首次发布 Cesium 专栏收录该内容 1 篇文章 1 订阅 订阅专栏 Cesium笔记

对于Cesium,笔者看了一些教程,这些教程各有特色,笔者从其中获得思路,结合文档和示例补充了自己关心的内容,整理如下

关注的重点:

1.Cesium的渲染方式或流程

2.Cesium的结构

3.Cesium不同结构支持的功能

cesium具有一系列对象和方法来进行三维地球方面的框架搭建,它凭借现有的数据类或自定义的独有的数据类型作为内容来为框架补充内容,其本质上依赖于WebGL相关方式进行渲染。

笔者在了解Cesium之后总结了以下笔记,藉以巩固相关知识。

1. 从CesiumWidget了解基本构建流程

CesiumWidget是官网示例之一,是最基本的封装最弱的cesium窗口,窗口能够显示一个地球(具有贴图的球体),代码如下:

<div id="cesiumContainer"></div> <script> const widget = new Cesium.CesiumWidget("cesiumContainer"); </script>

CesiumWidget()的基本语法如下:

new Cesium.CesiumWidget(container, options) NameTypeDescriptioncontainerElement|String将要包含widget的DOM元素或idoptionObject通过Object的方式定义的各种属性(properties)

在本示例中,我们可以在控制台中打印widget来了解CesiumWidget的结构。

详细语法和结构见链接:https://cesium.com/learn/cesiumjs/ref-doc/CesiumWidget.html?classFilter=wid

CesiumWidget的简单结构如下图所示:

结构说明:

clock属于Cesium.Clock类,是一个用于跟踪模拟时间的简单时钟,方便动态展示的内容通过时间来确定某一帧的内容;container是DOM元素,是通过参数传递或获取的,用于承载此CesiumWidget类的DOM盒子;canvas则是在container上构建的Canvas类的对象,用于获取WebGL绘图上下文;screenSpaceEventHandler属于Cesium.ScreenSpaceEventHandler类,是对Cesium场景中事件的封装;screen属于Cesium.Scene类,包含了cesium中所有三维对象和状态(通常,screen不是直接创建的,而是通过CesiumWidget隐式创建的),每一个独立的三维对象被称为一个图元。Scene中有一些内置的图元对象:地球(globe)、skyBox(天空盒)、sun(太阳)、moon(月亮)等等; 另外还有两个用来由用户自行控制存放对象的数组:primitives和groundPrimitives。

创建流程:

示例中没有传递options,它将DOM元素的id传递给构造函数CesiumWidget,函数内部获取了这个元素,在元素中创建了canvas,引入webgl上下文,再通过webgl进行三维渲染。在Cesium中,浏览器一直在使用requestAnimateFrame()进行刷新。

scene是Cesium中非常重要的部分,它装载了所有的三维对象。

小结:

cesium通过CesiumWidget类来管理DOM元素;通过Scene来管理所有的三维对象;三维对象通过图元进行创建,图元分为不同的种类。 2. 图元的基本说明

前文已经说明,图元类对应于一个三维渲染对象,在此处首先根据其它资料进行如下说明:

图元没有基类,不同类型的图元有不同的定义;每个图元都有update函数,用于Viewer或CesiumWidget渲染场景时调用,以获取渲染此基本体所需的绘制命令;

图元包含的内容如下图所示:

大致分类如下:

Globe:地形和影像的对象;Model:glTF三维模型的对象;Primitive:内置几何体(虽然翻译为“图元”,但此图元非彼图元),Primitive由Geometry和Appearance组成;Billboards/Lavels/Points:广告牌(图片)/标签(文字)/点;ViewportQuad:视口 3. 图元:Globe

在官方文档中,Globe的说明如下:

new Cesium.Globe(ellipsoid) Scene/Globe.js 42

The globe rendered in the scene, including its terrain (Globe#terrainProvider) and imagery layers (Globe#imageryLayers). Access the globe using Scene#globe.

NameTypeDefaultDescriptionellipsoidEllipsoidEllipsoid.WGS84optionalDetermines the size and shape of the globe.

此处明确说明了,globe处于scene之内,由地形terrain和影像imagery layers两部分组成。

一般来说,我们不需要自己创建globe,不论是CesiumWidget还是Viewer,都会在scene下初始一个globe对象,就像最开始的例子。

3.1 地形terrainProvider

在Cesium中,地形数据由TerrainProvider提供,TerrainProvider被解释为:

Provides terrain or other geometry for the surface of an ellipsoid. The surface geometry is organized into a pyramid of tiles according to a TilingScheme. This type describes an interface and is not intended to be instantiated directly.

有以下关键信息:

TerrainProvider为椭球体表面提供地形或其它几何图形;TerrainProvider设计了金字塔结构;TerrainProvider并不是一个基本类,它是由多种不同的类组成的。

我们可以从Tutorials-Terrain示例了解到TerrainProvider的不同分类。示例中囊括了许多不同的CesiumTerrainProvider,涉及了很多交互操作。如果我们只看最简单的Terrain设置,那部分代码如下:

# 创建了一个CesiumTerrainProvider类并赋值给worldTerrain const worldTerrain = Cesium.createWorldTerrain({ requestWaterMask: true, requestVertexNormals: true, }); .... # Viewer中地形的配置如下 viewer.terrainProvider = worldTerrain; ...

实际上,terrainProvider挂载在globe下,Viewer下只是提供了一个连接到terrainProvider原本位置的地址,其本质上是:

viewer.scene.globe.terrainProvider = worldTerrain

所以,地形的加载可以理解为,为globe下的terrainProvider提供一个terrainProvider相关类。示例中包含有很多种地形数据相关类,如下图所示:

CesiumTerrainProvider new Cesium.CesiumTerrainProvider(options)

A TerrainProvider that accesses terrain data in a Cesium terrain format. Terrain formats can be one of the following:Quantized Mesh、Height Map.

可以简单理解为Cesium提供的地形格式。

options是一个对象,关于它的键值对介绍如下:

NameTypeDefaultDescriptionurlResource | String | Promise.<Resource> | Promise.<String>The URL of the Cesium terrain server.requestVertexNormalsBooleanfalseFlag that indicates if the client should request additional lighting information from the server, in the form of per vertex normals if available.requestWaterMaskBooleanfalseFlag that indicates if the client should request per tile water masks from the server, if available.requestMetadataBooleantrueFlag that indicates if the client should request per tile metadata from the server, if available.ellipsoidEllipsoidThe ellipsoid. If not specified, the WGS84 ellipsoid is used.creditCredit | StringA credit for the data source, which is displayed on the canvas.

可以简单理解为:

url:Cesium terrain server的urlrequestVertexNormals:是否需要顶点法线(webgl中,顶点法线与光照计算有关)requestWaterMask:是否包含水面(是否需要渲染水面波浪)ellipsoid:椭球体,默认为WGS84椭球体

其还有很多属性和方法,详情可见文档。

关于CesiumTerrainProvider,文档中给出了如下实例化的例子:

// Create Arctic DEM terrain with normals. const viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider : new Cesium.CesiumTerrainProvider({ url : Cesium.IonResource.fromAssetId(3956), requestVertexNormals : true }) });

Cesium提供了一个快速创建CesiumTerrainProvider的方法,createWorldTerrain(),说明如下:

createWorldTerrain(options) → CesiumTerrainProvider

Creates a CesiumTerrainProvider instance for the Cesium World Terrain.

options中包含两个属性,requestVertexNormals和requestWaterMask,均默认为false,分别对应于CesiumTerrainProvider中的二者。

所以,在日常使用中,我们可以不记IonResource中的资源id,直接使用createWorldTerrain()更为方便创建CesiumTerrainProvider。

*补充说明:IonResource

顾名思义,IonResource是Cesium自行封装的一些资源,这些资源往往不直接通过Cesium.IonResource(endpoint, endpointResource)进行实例化获取,而是通过Cesium.IonResource.fromAssetId(assetId, options)创建,因为获取资源需要时间,所以该函数封装了一个Promise对象进行异步创建,相关说明如下:

Cesium.IonResource.fromAssetId(assetId, options) → Promise.<IonResource>

异步创建一个实例。

asserId:Number, The Cesium ion asset id.options:Object NameTypeDefaultDescriptionaccessTokenStringIon.defaultAccessTokenThe access token to use.serverString | ResourceIon.defaultServerThe resource to the Cesium ion API server.

返回值:A Promise to am instance representing the Cesium ion Asset.

EllipsoidTerrainProvider new Cesium.EllipsoidTerrainProvider(options)

提供一个非常简单的没有起伏的椭球体表面

关于options对象说明如下:

NameTypeDescriptiontilingSchemeTilingSchemeoptionalThe tiling scheme specifying how the ellipsoidal surface is broken into tiles. If this parameter is not provided, a GeographicTilingScheme is used.ellipsoidEllipsoidoptionalThe ellipsoid. If the tilingScheme is specified, this parameter is ignored and the tiling scheme’s ellipsoid is used instead. If neither parameter is specified, the WGS84 ellipsoid is used. tilingScheme:将椭球体表面拆分为瓦片的方式(平铺方案),默认为GeographicTilingScheme ,一个参考地理投影创建的方案。ellipsoid :椭球体,如果指定制定了tilingScheme,会按照前者规定的投影方案创建椭球体,如果未指定,默认为WGS84椭球体。

所以,直接使用new Cesium.EllipsoidTerrainProvider()就可以使用WGS84椭球体了。

其它地形provider GoogleEarthEnterpriseTerrainProvider

Provides tiled terrain using the Google Earth Enterprise REST API.

VRTheWorldTerrainProvider

A TerrainProvider that produces terrain geometry by tessellating height maps retrieved from a VT MÄK VR-TheWorld server.

ArcGISTiledElevationTerrainProvider

A TerrainProvider that produces terrain geometry by tessellating height maps retrieved from Elevation Tiles of an an ArcGIS ImageService.

3.2 影像imageryLayers

从示例Tutorials-Imagery Layers,可以了解影像图层的简单加载。

const viewer = new Cesium.Viewer("cesiumContainer", { imageryProvider: Cesium.createWorldImagery({ style: Cesium.IonWorldImageryStyle.AERIAL_WITH_LABELS, }), baseLayerPicker: false, }); const layers = viewer.scene.imageryLayers; const blackMarble = layers.addImageryProvider( new Cesium.IonImageryProvider({ assetId: 3812 }) ); blackMarble.alpha = 0.5; blackMarble.brightness = 2.0; layers.addImageryProvider( new Cesium.SingleTileImageryProvider({ url: "../images/Cesium_Logo_overlay.png", rectangle: Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75), }) );

关于imageryLayers需要了解以下主要内容:

影像数据保存在imageryLayers属性中,通过数组的方式单个影像数据由ImageryLayer类(实例)提供每个ImageryLayer实例都保存了ImageryProvider作为数据源 imageryLayers

imagerys实际上位于scene/globe/imageryLayers,在Viewer、CesiumWidget、Scene下均有imageryLayers的引用。

imageryLayers用于获取被渲染到globe上的图层,其指向了一个ImageryLayerCollection实例:

new Cesium.ImageryLayerCollection()

An ordered collection of imagery layers.

在ImageryLayerCollection内部存在_layers私有属性,_layers是Array类型,内部存储了一系列imageryProvider代表系列图层。

作为图层的集合,ImageryLayerCollection封装了一些相关方法,如add()、addImageryProvider()、contains()、remove()等,现将部分常用api摘录如下:

add(layer, index)

Adds a layer to the collection.

通过ImageryLayer添加图层。

NameTypeDescriptionlayerImageryLayerthe layer to add.indexNumberthe index to add the layer at. If omitted, the layer will be added on top of all existing layers.

addImageryProvider(imageryProvider, index) → ImageryLayer

Creates a new layer using the given ImageryProvider and adds it to the collection.

直接通过imageryProvider添加图层,返回新的ImageryLayer

NameTypeDescriptionimageryProviderImageryProviderthe imagery provider to create a new layer for.indexNumberoptionalthe index to add the layer at. If omitted, the layer will added on top of all existing layers.

Returns:

The newly created layer.

remove(layer, destroy) → Boolean

Removes a layer from this collection, if present.

移除某一图层,移除成功返回true,图层不存在返回false

NameTypeDefaultDescriptionlayerImageryLayerThe layer to remove.destroyBooleantruewhether to destroy the layers in addition to removing them.

Returns:

true if the layer was in the collection and was removed, false if the layer was not in the collection.

removeAll(destroy)

Removes all layers from this collection.

移除全部图层

NameTypeDefaultDescriptiondestroyBooleantrueoptionalwhether to destroy the layers in addition to removing them. imageryLayer

Cesium提供了ImageryLayer类,作为图层来展示瓦片数据,图层的数据源、透明度、亮度甚至显示范围等属性都设置在这里。可以通过add()方法添加到ImageryLayerCollection中

new Cesium.ImageryLayer(imageryProvider, options)

An imagery layer that displays tiled image data from a single imagery provider on a Globe.

参数说明:

imageryProvider,ImageryProvider类的实例,是图层的提供者options,Object类型,键值对保存了很多属性,仅列举少数进行说明: alpha:Number | function,默认为1.0,取值范围在[0.0,1.0]。作为number时,它代表了该层的α值,作为function时,它的参数为(frameState, layer, x, y, level),返回α值。brightness:Number | function,默认为1.0,表示图层的亮度,大于1.0更亮,小于1.0更暗。作为number时,它直接代表亮度值,作为function时,它的参数为(frameState, layer, x, y, level),返回亮度值。rectangle:Rectangle类型,默认为数据源中给出的rectangle(imageryProvider.rectangle),图层在这一矩形框中显示。show:Boolean,默认为true,图层是否显示

补充:

new Cesium.Rectangle(west, south, east, north)

由经纬度坐标限制的矩形区域

NameTypeDefaultDescriptionwestNumber0.0The westernmost longitude, in radians, in the range [-Pi, Pi].southNumber0.0The southernmost latitude, in radians, in the range [-Pi/2, Pi/2].eastNumber0.0The easternmost longitude, in radians, in the range [-Pi, Pi].northNumber0.0The northernmost latitude, in radians, in the range [-Pi/2, Pi/2].

单独计算弧度比较麻烦,Rectangle中也提供了经纬度的方法:

Cesium.Rectangle.fromDegrees(west, south, east, north, result) → Rectangle

NameTypeDefaultDescriptionwestNumber0.0optionalThe westernmost longitude in degrees in the range [-180.0, 180.0].southNumber0.0optionalThe southernmost latitude in degrees in the range [-90.0, 90.0].eastNumber0.0optionalThe easternmost longitude in degrees in the range [-180.0, 180.0].northNumber0.0optionalThe northernmost latitude in degrees in the range [-90.0, 90.0].resultRectangleoptionalThe object onto which to store the result, or undefined if a new instance should be created.

Returns:

The modified result parameter or a new Rectangle instance if none was provided.

Example:

const rectangle = Cesium.Rectangle.fromDegrees(0.0, 20.0, 10.0, 30.0);

imageryLayer类中保存了众多属性,通过私有属性**_imageryProvider保存了相应的imageryProvider**对象。

ImageryProvider new Cesium.ImageryProvider()

与TerrainProvider类似,Cesium中ImageryProvider也是一个抽象的类,它不直接表示一个数据结构,而是代表了所有的为椭球体提供图片的类,它代表了很多提供图片的类,如下图所示:

这些众多的provider可以在ImageryProvider中看到,根据图层不同的源选择合适的方式,所有的provider都可以通过addImageryProvider()方法直接添加到ImageryLayerCollection中,或者通过new新建一个ImageryLayer。下面介绍一些基础的ImageryProvider:

Cesium.IonImageryProvider()

new Cesium.IonImageryProvider(options)

通过Cesium ion REST API提供tiled imagery

NameTypeDescriptionoptionsIonImageryProvider.ConstructorOptionsObject describing initialization options

IonImageryProvider.ConstructorOptions 包含的属性如下:

NameTypeAttributesDefaultDescriptionassetIdNumberAn ion imagery asset IDaccessTokenStringIon.defaultAccessTokenThe access token to use.serverString | ResourceIon.defaultServerThe resource to the Cesium ion API server.

举例:

new Cesium.IonImageryProvider({ assetId: 3812 })

Cesium.SingleTileImageryProvider()

new Cesium.SingleTileImageryProvider(options)

提供一个简单的图像瓦片,该图片采用某一种投影方式放置到椭球体上

NameTypeDescriptionoptionsSingleTileImageryProvider.ConstructorOptionsObject describing initialization options

SingleTileImageryProvider.ConstructorOptions包含的属性如下:

NameTypeAttributesDefaultDescriptionurlResource | StringThe url for the tile.rectangleRectangleRectangle.MAX_VALUEThe rectangle, in radians, covered by the image.creditCredit| StringA credit for the data source, which is displayed on the canvas.ellipsoidEllipsoidThe ellipsoid. If not specified, the WGS84 ellipsoid is used.

举例:

new Cesium.SingleTileImageryProvider({ url: "../images/Cesium_Logo_overlay.png", rectangle: Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75), }) 其它

如果想要了解多图层的协同方式,可以参照示例Imagery Layers Mainpulation

如果想要了解其它效果,可以参考Imagery Color To Alpha、Imagery Cutout、Imagery Layers Split、Imagery Layers Texture Filters等等

其它

globe中还有很多其它属性和方法,此处将了解到的部分收集如下:

enableLighting属性

出现在Tutorials-Terrain示例中,是一个Boolean值,Enable lighting the globe with the scene’s light source.

理论上来说,它需要CesiumTerrainProvider中requestVertexNormals的支持,在示例中时间变化可以看到光照效果的变化。

4.图元:Model(glTF)

首先给出文档中对Cesium.Model()类的说明:

Model是A 3D model based on glTF, the runtime asset format for WebGL, OpenGL ES, and OpenGL.

Cesium具有对geometry和material的支持,对glTF animations和glTF skinning的支持。

单个glTF节点可以通过scene#pick拾取,使用Model#getNode设置动画

目前不支持glTF摄像头和灯光?

Model.fromGltf()可用于通过glTF创建模型,在程序运行中也可以将glTF JSON传入构造函数

Model#Promise是resolved状态时,model才准备好进行渲染(在上述Promise中对model进行准备)

关于Model,可以从示例development/3D Models进行了解。

Model的存储位置

model一般存储在scene.primitives下。

scene.primitives属于PrimitiveCollection类,该类提供了一个add()方法来添加primitive:

add(primitive,index) → Object

Adds a primitive to the collection.

NameTypeDescriptionprimitiveObjectThe primitive to add.indexNumberThe index to add the layer at. If omitted, the primitive will be added at the bottom of all existing primitives.

Returns:

The primitive added to the collection.

Example:

const billboards = scene.primitives.add(new Cesium.BillboardCollection()); Model的创建

Model类提供了fromGltf()方法对glTF格式进行加载

Cesium.Model.fromGltf(options) → Model

Creates a model from a glTF asset.

The model can be a traditional glTF asset with a .gltf extension or a Binary glTF using the .glb extension.

options中提供了非常多的属性进行设置,此处仅列举一些可能常用的属性:

NameTypeDefaultDescriptionurlResource | StringThe url to the .gltf file.showBooleantrueDetermines if the model primitive will be shown.modelMatrixMatrix4Matrix4.IDENTITYThe 4x4 transformation matrix that transforms the model from model to world coordinates.minimumPixelSizeNumber0.0The approximate minimum pixel size of the model regardless of zoom.

大部分的参数都很好理解,modelMatrix完成了模型到世界坐标系的转换,在development/3D Models示例中,它的计算过程(封装的函数)如下:

... function createModel(url, height, heading, pitch, roll) { height = Cesium.defaultValue(height, 0.0); heading = Cesium.defaultValue(heading, 0.0); pitch = Cesium.defaultValue(pitch, 0.0); roll = Cesium.defaultValue(roll, 0.0); const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); const origin = Cesium.Cartesian3.fromDegrees( -123.0744619, 44.0503706, height ); const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame( origin, hpr ); scene.primitives.removeAll(); // Remove previous model model = scene.primitives.add( Cesium.Model.fromGltf({ url: url, modelMatrix: modelMatrix, minimumPixelSize: 128, }) ); ... } ...

逐步分析如下:

第一步:自身姿态带来的旋转

Cesium.defaultValue()函数

在文档中,该函数挂载在Globe下,此处估计是在Cesium下提供了一个引用(其实都是引用,无所谓);

在源码中,该函数位于cesium/Source/Core/defaultValue.js目录

该函数源码如下:

function defaultValue(a, b) { if (a !== undefined && a !== null) { return a; } return b; }

​ 用处是:

​ Returns the first parameter if not undefined, otherwise the second parameter. ​ Useful for setting a default value for a parameter.

heading, pitch, roll是模型的欧拉角(姿态角),通过HeadingPitchRoll函数创建一个HeadingPitchRoll对象来保存:

HeadingPitchRoll对象具有如下结构:

new Cesium.HeadingPitchRoll(heading, pitch, roll) Core/HeadingPitchRoll.js

A rotation expressed as a heading, pitch, and roll. 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。

这样的说明还涉及到了Cesium中坐标系的说明,网上有很多大佬对此进行了总结,此处先放一个引用https://www.jianshu.com/p/5839f615bb94,笔者在之后尝试进行引用或补充。

heading, pitch, roll:航向、俯仰角、翻滚角,从示例中看,此处的xyz轴是针对模型本身的,以飞机为例,飞机原始航向为东,机翼面平行于地表,z轴垂直于地表向上、y轴指向北、x轴指向东。

NameTypeDefaultDescriptionheadingNumber0.0The heading component in radians.pitchNumber0.0The pitch component in radians.rollNumber0.0The roll component in radians.

补充:此处使用的是弧度,所以往往需要Cesium.Math.toRadians()将角度转换为弧度。

第二步:空间位置的移动

这一步非常直接:

const origin = Cesium.Cartesian3.fromDegrees( -123.0744619, 44.0503706, height );

将经纬度和高度转换为笛卡尔坐标

第三步:构建模型矩阵

可以通过姿态变化、位置变化构建模型矩阵(原始位置位于笛卡尔坐标系中心)

const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame( origin, hpr );

返回The modified result parameter or a new Matrix4 instance if none was provided.

补充:

Cesium.Transforms下挂载了一系列矩阵生成函数,用于模型坐标到参考坐标系的转换。这些函数有形象的命名方式,方便查询和调用,返回Cesium需要的矩阵。

批量模型的快速渲染

ModelInstanceCollection

加速渲染的方式

5.图元:Billboards/Labels/Points Billboards

简述

billboard,意为广告牌,表现为一个image或canvas,始终面向视角。

示例development/Billboards中有基础的Billboards用法,整体与Model类似:

其加载同样使用scene.primitives.add()方法

const billboards = scene.primitives.add( new Cesium.BillboardCollection() )

在collection中添加对象,使用BillboardCollection.add

billboards.add({ image: "../images/Cesium_Logo_overlay.png", position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), })

options详解

BillboardCollection.add(options)中,billboard的options总结如下:

// Example 1: Add a billboard, specifying all the default values. const b = billboards.add({ show : true, position : Cesium.Cartesian3.ZERO, // 如Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883) pixelOffset : Cesium.Cartesian2.ZERO,// 偏移如new Cesium.Cartesian2(0.0, -facilityHeight) eyeOffset : Cesium.Cartesian3.ZERO,// 如new Cesium.Cartesian3(0.0, 0.0, 0.0) heightReference : Cesium.HeightReference.NONE, horizontalOrigin : Cesium.HorizontalOrigin.CENTER, verticalOrigin : Cesium.VerticalOrigin.CENTER, scale : 1.0, image : 'url/to/image', //url或canvas,如用canvas2D画个点 imageSubRegion : undefined,// 类似精灵图的用法如new Cesium.BoundingRectangle(67, 80, 14, 14) color : Cesium.Color.WHITE, id : undefined, rotation : 0.0,// 如Cesium.Math.PI_OVER_FOUR alignedAxis : Cesium.Cartesian3.ZERO, width : undefined,// 如100 height : undefined,// 如25 scaleByDistance : undefined, // 设置大小随距离变化如new Cesium.NearFarScalar(1.5e2, 2.0, 1.5e7, 0.5) translucencyByDistance : undefined, // 根据距离设置透明度如new Cesium.NearFarScalar(1.5e2,1.0,1.5e7,0.2) pixelOffsetScaleByDistance : undefined,// 根据距离设置偏移如new Cesium.NearFarScalar(1.0e3,1.0,1.5e6,0.0) sizeInMeters : false,// 是否用米而不是像素作为单位,米会随距离变化大小(透视效果) distanceDisplayCondition : undefined }); // Example 2: Specify only the billboard's cartographic position. const b = billboards.add({ position : Cesium.Cartesian3.fromDegrees(longitude, latitude, height) }); // Example 3: 独立的坐标系BillboardCollection.modelMatrix const billboards = scene.primitives.add( new Cesium.BillboardCollection() ); const center = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); billboards.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame( center ); const facilityUrl = "../images/facility.gif"; // center billboards.add({ image: facilityUrl, position: new Cesium.Cartesian3(0.0, 0.0, 0.0), }); ...

创建完成后,仍然可以修改:

const billboards = scene.primitives.add( new Cesium.BillboardCollection() ); // add() returns a Billboard object containing functions to change // the billboard's position and appearance. const b = billboards.add({ image: "../images/Cesium_Logo_overlay.png", }); b.position = Cesium.Cartesian3.fromDegrees( -75.59777, 40.03883, 300000.0 ); b.scale = 3.0; b.color = new Cesium.Color(1.0, 1.0, 1.0, 0.25); Labels

简述

label,意为标签,相当于把billboard中的图片变为了文字,其它方面类似。

可见示例development/Labels

label以LabelCollection的形式添加在primitive下,通过add添加新的labels:

const labels = scene.primitives.add(new Cesium.LabelCollection()); labels.add({ position: Cesium.Cartesian3.fromDegrees(-75.1641667, 39.9522222), text: "Philadelphia", });

options

此处同样列出Cesium.LabelCollection.add(options)中options的一些设置,很多options与billboard类似,可以通过示例查看:

// Example 1: Add a label, specifying all the default values. const l = labels.add({ show : true, position : Cesium.Cartesian3.ZERO, text : '', // 内容,一些文字 font : '30px sans-serif', // 文字格式 fillColor : Cesium.Color.WHITE, // 文字颜色 outlineColor : Cesium.Color.BLACK, // 文字边缘颜色 outlineWidth : 1.0,// 边缘宽度 showBackground : false, backgroundColor : new Cesium.Color(0.165, 0.165, 0.165, 0.8), backgroundPadding : new Cesium.Cartesian2(7, 5), style : Cesium.LabelStyle.FILL,// global.LabelStyle,共三种类型,确定了label的绘制方式 FILL、OUTLINE、FILL_AND_OUTLINE pixelOffset : Cesium.Cartesian2.ZERO, eyeOffset : Cesium.Cartesian3.ZERO, horizontalOrigin : Cesium.HorizontalOrigin.LEFT, verticalOrigin : Cesium.VerticalOrigin.BASELINE, scale : 1.0, translucencyByDistance : undefined, pixelOffsetScaleByDistance : undefined, heightReference : HeightReference.NONE, distanceDisplayCondition : undefined }); // Example 2: Specify only the label's cartographic position, // text, and font. const l = labels.add({ position : Cesium.Cartesian3.fromRadians(longitude, latitude, height), text : 'Hello World', font : '24px Helvetica', }); Points

简述

points意为点,其用法与前两者类似,使用PointPrimitiveCollection保存点集:

const pointPrimitives = scene.primitives.add( new Cesium.PointPrimitiveCollection() ); pointPrimitives.add({ color: Cesium.Color.YELLOW, position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), });

options

PointPrimitiveCollection.add(options)可以添加的key如下:

// Example 1: Add a point, specifying all the default values. const p = pointPrimitives.add({ show : true, position : Cesium.Cartesian3.ZERO, pixelSize : 10.0, color : Cesium.Color.WHITE, outlineColor : Cesium.Color.TRANSPARENT, outlineWidth : 0.0, id : undefined }); // Example 2: Specify only the point's cartographic position. const p = pointPrimitives.add({ position : Cesium.Cartesian3.fromDegrees(longitude, latitude, height) }); 6.图元:polylines 6.1 PolylineCollection

polyline的一种用法与前面三者类似,所以放在这里。

简单的示例可见development/Polylines,其通过PolylineCollection储存对象,使用如下:

const polylines = scene.primitives.add( new Cesium.PolylineCollection() ); // A simple polyline with two points. const polyline = polylines.add({ positions: Cesium.PolylinePipeline.generateCartesianArc({ positions: Cesium.Cartesian3.fromDegreesArray([ -120.0, 40.0, -110.0, 30.0, ]), }), material: Cesium.Material.fromType("Color", { color: new Cesium.Color(1.0, 1.0, 1.0, 1.0), }), });

一些options如下:

// Example 1: Add a polyline, specifying all the default values. const p = polylines.add({ show : true, positions : ellipsoid.cartographicArrayToCartesianArray([ Cesium.Cartographic.fromDegrees(-75.10, 39.57), Cesium.Cartographic.fromDegrees(-77.02, 38.53)]), width : 1 });

position的设置如下:

polyline位于地球表面,如果直接使用两个坐标,可能出现穿过球体的情况,所以使用一些方法计算球面上的点,点集组成的几何形态取决于PolylinePipeline,如:

Cesium.PolylinePipeline.generateCartesianArc() // 提供最短线的点集 Cesium.PolylinePipeline.generateCartesianRhumbArc() // 提供同向线的点集

material的设置如下:

需要Cesium.Material

6.2 通过primitive相关方法

通过new Cesium.GroundPolylinePrimitive()或new Cesium.Primitive()等primitive方式创建图元,可以设置几何实例和表面材质,与后文Primitive类似,该方式更加灵活。

可见development/Simple Polyline、development/Ground Polyline Material,等很多示例

6.图元:Primitive

primitive提供了很多几何体的绘制方式,一个primitive调用一次webgl draw函数,一个primitive中可以通过数组的方式配置多个instance。示例有很多。

Primitive的组成

上图结构的简单示例代码如下:

// Create a geometry instance using the geometry // and model matrix created above. const boxGeometryInstance = new Cesium.GeometryInstance({ geometry: boxGeometry, modelMatrix: boxModelMatrix, attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor( new Cesium.Color(1.0, 0.0, 0.0, 0.5) ), }, }); // Add the geometry instance to primitives. scene.primitives.add( new Cesium.Primitive({ geometryInstances: boxGeometryInstance, appearance: new Cesium.PerInstanceColorAppearance({ closed: true, }), }) );

其中涉及到了一些问题:

geometry的构建问题(如Cesium.BoxGeometry)modelMatrix的构建问题(与model中的matrix相同)attributes中包含哪些属性,可以进行怎样的配置appearance中包含哪些方式,可以如何配置id的用法

这些问题可以通过实例进行了解,实际生产中可能需要翻阅文档。后面会有一些简单说明。

补充:scene.primitives的多层次结构

scene.primitives本身指向PrimitiveCollection对象,其下可以挂载Primitive或PrimitiveCollection。

PrimitiveCollection中的属性:

destroyPrimitives : Booleanlength : Numbershow : Boolean

PrimitiveCollection中的方法:

add、get、remove、removeAll、raise系列、lower系列、destroy、isDestroy等 6.图元:Primitive 7.图元:

相关文章

YOLOv5 小目标检测、无人机视角小目标检测

YOLOv5 小目标检测、无人机视角小目标检测...

【毕业季】在校的我是这样看待毕业

【毕业季】在校的我是这样看待毕业...

Vue+Element UI-el-date-picker时间日期选择器组件(实现向后端传值)

Vue+Element UI-el-date-picker时间日期选择器组件(实现向后端传值)...

【JavaScript】五个常用功能/案例:判断特定结尾字符串 | 获取指定字符串 | 颜色字符串转换 | 字符串转驼峰格式 | 简易购物车

【JavaScript】五个常用功能/案例:判断特定结尾字符串 | 获取指定字符串 | 颜色字符串转换 | 字符串转驼峰格式 | 简易购物车...

TOP命令参数详解---10分钟学会top用法

TOP命令参数详解---10分钟学会top用法...

SpringCloud入门教程(全集)

SpringCloud入门教程(全集)...