Cesium在空间数据可视化方面提供了两种类型的API,一种是面向图形开发人员的低级(原始)API,通过Primitive类实现,对于那些对计算机图形学知识很了解的同学可以采用Primitive API;另一种是用于数据驱动的高级(实体)API,通过Entity类实现,相对于Primitive API,Entity API实现起来更简单一些,特别建议初学者使用。Entity API 实际上是对Primitive API的二次封装,底层调用的仍然是Primitive API,目的就是为我们提供灵活的、易学、易用的高性能可视化界面。使用Cesium的Entity API我们可以去绘制空间数据,如点,图标,文字标注,折线,模型,图形和立体图形。
Entity支持的图形类型
通过在Cesium API文档中查看Entity类的构造函数,我们发现Entity支持的图形类型都是以Graphics结尾的,一共有17种类型:
billboard 广告牌
var entity = viewer.entities.add({ name: "billboard", position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), billboard: { show: true, image: "./images/Cesium_Logo_overlay.png", scale: 2.0, pixelOffset: new Cesium.Cartesian2(0, -50), eyeOffset: new Cesium.Cartesian3(0.0, 0.0, 0.0), horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.BOTTOM, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, color: Cesium.Color.LIME, rotation: Cesium.Math.PI_OVER_FOUR, alignedAxis: Cesium.Cartesian3.ZERO, width: 100, height: 25, scaleByDistance: new Cesium.NearFarScalar(1.0e3, 2.0, 2.0e3, 1.0), translucencyByDistance: new Cesium.NearFarScalar( 1.0e3, 1.0, 1.5e6, 0.5 ), pixelOffsetScaleByDistance: new Cesium.NearFarScalar( 1.0e3, 1.0, 1.5e6, 0.0 ), disableDepthTestDistance: Number.POSITIVE_INFINITY, }, }); viewer.zoomTo(entity); var billboard = entity.billboard; billboard.scale = 3.0; billboard.color = Cesium.Color.WHITE.withAlpha(0.25);View Code
box 盒子
var entity = viewer.entities.add({ name: "box", position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0), box: { show: true, dimensions: new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), heightReference: Cesium.HeightReference.NONE, fill: true, material: Cesium.Color.RED.withAlpha(0.5), outline: true, outlineColor: Cesium.Color.BLACK, outlineWidth: 1.0, shadows: Cesium.ShadowMode.DISABLED, }, }); viewer.zoomTo(entity);View Code
corridor 走廊
var entity = viewer.entities.add({ name: "corridor", corridor: { // 指定定义走廊中心线的 Cartesian3 位置的数组 type: Cartesian3 positions: Cesium.Cartesian3.fromDegreesArray([ -80.0, 40.0, -85.0, 40.0, -85.0, 35.0, ]), width: 200000.0, height: 200000.0, heightReference: Cesium.HeightReference.NONE, extrudedHeight: 100000.0, extrudedHeightReference: Cesium.HeightReference.NONE, // 拐角的样式 type:CornerType default:CornerType.ROUNDED // ROUNDED 角有光滑的边缘;MITERED 拐角点是相邻边的交点;BEVELED 角被修剪 cornerType: Cesium.CornerType.ROUNDED, // 每个纬度和经度之间的距离 granularity: Cesium.Math.RADIANS_PER_DEGREE, fill: true, // 材质 type:MaterialProperty|Color default:Color.WHITE material: Cesium.Color.BLUE.withAlpha(0.5), outline: true, outlineColor: Cesium.Color.WHITE, outlineWidth: 1.0, shadows: Cesium.ShadowMode.DISABLED, // 走廊在地面上时将对地形,3D tiles还是对两者进行分类 type:ClassificationType default:ClassificationType.BOTH // TERRAIN 将仅对地形进行分类;CESIUM_3D_TILE 将仅对3D Tiles进行分类;BOTH 将同时对Terrain和3D Tiles进行分类。 classificationType: Cesium.ClassificationType.BOTH, }, });View Code
cylinder 圆柱、圆锥
var entity = viewer.entities.add({ name: "cylinder", position: Cesium.Cartesian3.fromDegrees(-105.0, 40.0, 200000.0), cylinder: { length: 400000.0, topRadius: 200000.0, bottomRadius: 200000.0, heightReference: Cesium.HeightReference.NONE, fill: true, material: Cesium.Color.GREEN.withAlpha(0.5), outline: true, outlineColor: Cesium.Color.DARK_GREEN, outlineWidth: 1.0, // 沿轮廓的周长绘制的垂直线的数量 numberOfVerticalLines: 16, shadows: Cesium.ShadowMode.DISABLED, // 圆柱周围的边缘数量 slices: 128, }, });View Code
ellipsoid 椭球体
var entity = viewer.entities.add({ name: "Spheres and Ellipsoids", position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0), ellipsoid: { show: true, radii: new Cesium.Cartesian3(200000.0, 200000.0, 300000.0), minimumClock: 0.0, maximumClock: 2 * Math.PI, minimumCone: 0.0, maximumCone: Math.PI, heightReference: Cesium.HeightReference.NONE, fill: true, material: Cesium.Color.BLUE.withAlpha(0.5), outline: true, outlineColor: Cesium.Color.YELLOW, outlineWidth: 1.0, stackPartitions: 64, slicePartitions: 64, subdivisions: 128, shadows: Cesium.ShadowMode.DISABLED, }, });View Code
label 标签
var citizensBankPark = viewer.entities.add({ name : 'Citizens Bank Park', position : Cesium.Cartesian3.fromDegrees(-75.166493, 39.9060534), label : { text : 'Citizens Bank Park', font : '14pt monospace', style: Cesium.LabelStyle.FILL_AND_OUTLINE, outlineWidth : 2, verticalOrigin : Cesium.VerticalOrigin.BOTTOM, pixelOffset : new Cesium.Cartesian2(0, -9) } });View Code
model 模型
var position = Cesium.Cartesian3.fromDegrees( -123.0744619, 44.0503706, 5000.0 ); var heading = Cesium.Math.toRadians(135); var pitch = 0; var roll = 0; var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); var orientation = Cesium.Transforms.headingPitchRollQuaternion( position, hpr ); var url = "./data/models/CesiumAir/Cesium_Air.glb"; var entity = viewer.entities.add({ name: "model", position: position, orientation: orientation, model: { show: true, uri: url, scale: 1.0, minimumPixelSize: 128, maximumScale: 20000, incrementallyLoadTextures: true, runAnimations: true, clampAnimations: true, shadows: Cesium.ShadowMode.DISABLED, heightReference: Cesium.HeightReference.NONE, silhouetteColor: Cesium.Color.RED, silhouetteSize: 0.0, color: Cesium.Color.WHITE, colorBlendMode: Cesium.ColorBlendMode.HIGHLIGHT, colorBlendAmount: 0.5, imageBasedLightingFactor: new Cesium.Cartesian2(1.0, 1.0), lightColor: undefined, }, });View Code
tileset 3D Tiles瓦片集
var entity = viewer.entities.add({ name: "3D Tiles", position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0), tileset: { show: true, uri: "./data/Cesium3DTiles/Tilesets/Tileset/tileset.json", }, });View Code
plane 平面
var entity= viewer.entities.add({ name: "Blue plane", position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0), plane: { show: true, plane: new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0), dimensions: new Cesium.Cartesian2(400000.0, 300000.0), fill: true, material: Cesium.Color.BLUE, outline: false, outlineColor: Cesium.Color.BLACK, outlineWidth: 1.0, shadows: Cesium.ShadowMode.DISABLED, }, });View Code
point 点
var entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883), point: { show: true, pixelSize: 10, // 像素大小 heightReference: Cesium.HeightReference.NONE, color: Cesium.Color.YELLOW, outlineColor: Cesium.Color.BLACK, outlineWidth: 0, scaleByDistance: new Cesium.NearFarScalar(1.0e3, 10.0, 2.0e3, 1.0), translucencyByDistance: new Cesium.NearFarScalar( 1.0e3, 1.0, 1.5e6, 0.5 ), // distanceDisplayCondition: new Cesium.DistanceDisplayCondition( // 1.0e3, // 2.0e3 // ), // 获取或设置与相机的距离,在深度处禁用深度测试,例如,以防止剪切地形。 // 设置为零时,将始终应用深度测试。设置为Number.POSITIVE_INFINITY时,永远不会应用深度测试。 disableDepthTestDistance: Number.POSITIVE_INFINITY, }, });View Code
polygon 多边形
var entity = viewer.entities.add({ name: "Red polygon on surface", polygon: { show: true, hierarchy: Cesium.Cartesian3.fromDegreesArray([ -115.0, 37.0, -115.0, 32.0, -107.0, 33.0, -102.0, 31.0, -102.0, 35.0, ]), height: 0, heightReference: Cesium.HeightReference.NONE, stRotation: 0.0, granularity: Cesium.Math.RADIANS_PER_DEGREE, fill: true, material: Cesium.Color.RED, outline: false, outlineColor: Cesium.Color.BLACK, outlineWidth: 1.0, perPositionHeight: false, closeTop: true, closeBottom: true, arcType: Cesium.ArcType.GEODESIC, shadows: Cesium.ShadowMode.DISABLED, classificationType: Cesium.ClassificationType.BOTH, zIndex: 0, }, });View Code
polyline 多线段
var entity= viewer.entities.add({ name: "Red line on terrain", polyline: { show: true, positions: Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]), width: 5, material: Cesium.Color.RED, clampToGround: true, shadows: Cesium.ShadowMode.DISABLED, classificationType: Cesium.ClassificationType.BOTH, }, });View Code
polylineVolume 多线段柱体
function computeCircle(radius) { var positions = []; for (var i = 0; i < 360; i++) { var radians = Cesium.Math.toRadians(i); positions.push( new Cesium.Cartesian2( radius * Math.cos(radians), radius * Math.sin(radians) ) ); } return positions; } var entity= viewer.entities.add({ name: "Red tube with rounded corners", polylineVolume: { show: true, positions: Cesium.Cartesian3.fromDegreesArray([ -85.0, 32.0, -85.0, 36.0, -89.0, 36.0, ]), shape: computeCircle(60000.0), cornerType: Cesium.CornerType.ROUNDED, fill: true, material: Cesium.Color.RED, outline: false, outlineColor: Cesium.Color.BLACK, outlineWidth: 1.0, shadows: Cesium.ShadowMode.DISABLED, }, });View Code
rectangle 矩形
var entity= viewer.entities.add({ name: "Red translucent rectangle", rectangle: { show: true, coordinates: Cesium.Rectangle.fromDegrees(-110.0, 20.0, -80.0, 25.0), rotation: 0.0, stRotation: 0.0, granularity: Cesium.Math.RADIANS_PER_DEGREE, fill: true, material: Cesium.Color.RED.withAlpha(0.5), outline: false, outlineColor: Cesium.Color.BLACK, outlineWidth: 1.0, shadows: Cesium.ShadowMode.DISABLED, classificationType: Cesium.ClassificationType.BOTH, zIndex: 0, }, });View Code
wall 墙
var entity= viewer.entities.add({ name: "Red wall at height", wall: { show: true, positions: Cesium.Cartesian3.fromDegreesArrayHeights([ -115.0, 44.0, 200000.0, -90.0, 44.0, 200000.0, ]), minimumHeights: [100000.0, 100000.0], granularity: Cesium.Math.RADIANS_PER_DEGREE, fill: true, material: Cesium.Color.RED, outline: false, outlineColor: Cesium.Color.BLACK, outlineWidth: 1.0, shadows: Cesium.ShadowMode.DISABLED, }, });View Code
材质和边线
无论各种几何体有什么不同,所有形状和体都有一系列相同的属性来控制它们的外观。fill
为boolean类型,控制表面是否填充。 outline
属性控制是否有外边界。当 fill
=true
,material
属性决定了用什么材质填充表面。
半透明
var entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0), ellipse : { semiMinorAxis : 250000.0, semiMajorAxis : 400000.0, material : Cesium.Color.BLUE.withAlpha(0.5) } }); viewer.zoomTo(entity);View Code
图片
var entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0), ellipse : { semiMinorAxis : 250000.0, semiMajorAxis : 400000.0, material : './images/Cesium_Logo_overlay.png' } }); viewer.zoomTo(entity);View Code
网格
var entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0), ellipse: { semiMinorAxis: 250000.0, semiMajorAxis: 400000.0, material: new Cesium.CheckerboardMaterialProperty({ evenColor: Cesium.Color.WHITE, oddColor: Cesium.Color.BLACK, repeat: new Cesium.Cartesian2(4, 4), }), }, }); viewer.zoomTo(entity);View Code
条纹
var entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0), ellipse: { semiMinorAxis: 250000.0, semiMajorAxis: 400000.0, material: new Cesium.StripeMaterialProperty({ evenColor: Cesium.Color.WHITE, oddColor: Cesium.Color.BLACK, repeat: 32, }), }, }); viewer.zoomTo(entity);View Code
网格
var entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0), ellipse: { semiMinorAxis: 250000.0, semiMajorAxis: 400000.0, material: new Cesium.GridMaterialProperty({ color: Cesium.Color.YELLOW, cellAlpha: 0.2, lineCount: new Cesium.Cartesian2(8, 8), lineThickness: new Cesium.Cartesian2(2.0, 2.0), }), }, }); viewer.zoomTo(entity);View Code
边线
和fill
属性不太一样,outline
没有对应的材质配置,而是用两个独立的属性outlineColor
和outlineWidth
。注意
outlineWidth
属性仅仅在非windows系统上有效,比如Android, iOS, Linux, 和OS X。Windows系统上边线宽度永远为1
var entity = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0), ellipse: { semiMinorAxis: 250000.0, semiMajorAxis: 400000.0, fill:false, outlineColor:Cesium.Color.RED, outlineWidth:2.0, outline:true, }, }); viewer.zoomTo(entity);View Code
折线
ar entity = viewer.entities.add({ polyline: { positions: Cesium.Cartesian3.fromDegreesArray([77, 35, 75, 34, 60, 30]), width: 5, material: new Cesium.PolylineOutlineMaterialProperty({ color: Cesium.Color.ORANGE, outlineWidth: 3, outlineColor: Cesium.Color.BLUE, }), }, }); viewer.View Code
高度和垂直挤压
所有的面形状都是平铺在地球上,当前 圆(circles)、椭圆(ellipses)、多边形(polygons)、矩形(rectangles)可以有一个高程属性 或者 垂直挤压变成体。这两种情况种,这些面或者体仍然会贴合地球曲率。上面我们列出的所有图形,都是只需要在图形对象(graphics )上设置一个高度属性即可。这里顺便说明下,除非在函数上明确说明,否则Cesium总是使用米、弧度、秒做为标准单位。如Cartesian3.fromDegrees. 把图形挤压为体,也非常简单。仅仅需要设置
extrudedHeight
属性。将会创建一个在height
和extrudedHeight
之间的体块。如果 height
没有定义, 体块从 0高程开始。下面代码创建一个从200,000米到 250,000米的体 。也就是说这个体的高度是50000米。
var entity = viewer.entities.add({ polygon: { hierarchy: Cesium.Cartesian3.fromDegreesArray([ -109.080842, 45.002073, -105.91517, 45.002073, -111.047063, 42.000709, -111.047063, 44.476286, -111.05254, 45.002073, ]), height: 200000, extrudedHeight: 250000, material: Cesium.Color.RED.withAlpha(0.5), outline: true, outlineColor: Cesium.Color.BLACK, }, }); viewer.zoomTo(viewer.entities);View Code
管理Entity集合
EntityCollection类是一个Entity数组集合,用来它管理和控制一组entity非常方便。我们已经见过它的一个实例 viewer.entities 属性。EntityCollection 提供了基本的数组方法 add, remove, 和 removeAll;同时还有下面我们要讨论的一些特有方法或者属性。很多项目的数据实际都是存在服务端的,只有客户端需要的时候才会加载。有时候需要更改一个我们已经创建的entity。所有entity对象都有一个独一无二的 id 属性,这种情况情况下就非常有用。前面的示例里,我们并没有指定这个id,Cesium会自动生成一个 GUID 类似
182bdba4-2b3e-47ae-bf0b-83f6fde285fd
填充到id属性里。服务端的数据一般都有自己主键id属性,所以可以在enity创建的时候指定这个id。
随后,可以通过 getById来获取Entity对象。如果没有找到对应的id,那么该方法返回 undefined
。
最后,简单的通过 add就可以新建一个Entity实例。这种情况下,add函数会检测如果传入了一个已经存在的id,那么会报异常。
EntityCollection 最强大的功能其实是collectionChanged Event,我们用它来接收集合里entity被添加、删除甚至更新的通知。当项目里的用户界面或者某个功能需要监控集合里的对象改变的时候,这个功能非常有用。var viewer = new Cesium.Viewer("cesiumContainer"); function onChanged(collection, added, removed, changed) { var msg = "Added ids"; for (var i = 0; i < added.length; i++) { msg += "\n" + added[i].id; } console.log(msg); } viewer.entities.collectionChanged.addEventListener(onChanged); var entity = viewer.entities.add({ id: "test", polygon: { hierarchy: Cesium.Cartesian3.fromDegreesArray([ -109.080842, 45.002073, -105.91517, 45.002073, -111.047063, 42.000709, -111.047063, 44.476286, -111.05254, 45.002073, ]), height: 200000, extrudedHeight: 250000, material: Cesium.Color.RED.withAlpha(0.5), outline: true, outlineColor: Cesium.Color.BLACK, }, }); viewer.zoomTo(viewer.entities);View Code