Cesium Entity API简单例子 - cytggit/Map-openlayers GitHub Wiki
Entity API简介
Cesium提供两类API:
(1)面向图形开发人员的底层API,通常称为“Primitive API”。该API暴露最小限度的抽象,使用图形学术语,具有很大的灵活性,需要具有图形学编程的知识
(2)高级别的数据驱动的API,称为“Entity API”。该API使用一致性设计的、高级别的对象来管理一组相关性的可视化对象,其底层使用Primitive API
下面是Entity API的简单例子
一、形状与立体(Shapes and Volumes)
支持的形状与立体列表
-
立方体(Boxes):
var redBox = viewer.entities.add({ name : 'Red box with black outline', position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0), box : { dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0), material : Cesium.Color.RED, fill : true, //显示填充,false时空心 outline : true, //显示轮廓 outlineColor : Cesium.Color.BLACK } });
-
圆和椭圆(Circles Ellipses)
// 蓝色椭圆柱,旋转了角度 var blueEllipse = viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-95.0, 40.0, 100000.0), name : 'Blue translucent, rotated, and extruded ellipse', ellipse : { semiMinorAxis : 150000.0,//半径 semiMajorAxis : 300000.0,//半径 height:200000.0,//浮空高度,不带高度时不用设置 extrudedHeight : 400000.0, //拉伸高度,不带高度时不用设置 rotation : Cesium.Math.toRadians(45), //旋转 material : Cesium.Color.BLUE.withAlpha(0.7), outline : true, outlineColor : Cesium.Color.RED } });
-
走廊(Corridor)
var blueCorridor = viewer.entities.add({ name : 'Blue extruded corridor with beveled corners and outline', corridor : { positions : Cesium.Cartesian3.fromDegreesArray( [ -70.0, 50.0, -80.0, 50.0, -80.0, 40.0, -85.0, 40.0, -85.0, 35.0 ]), height : 200000.0,//浮空高度,不带高度时不用设置 extrudedHeight : 210000.00,//拉伸高度,不带高度时不用设置 width : 100000.0, // cornerType: Cesium.CornerType.BEVELED,// 控制端点形状 material : Cesium.Color.YELLOW.withAlpha(0.5), // outline : true, // outlineColor : Cesium.Color.BLUE } });
-
圆柱和圆锥(Cylinder Cones)
var yellowCone = viewer.entities.add({ name : 'yellow cone', position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 298000.0), cylinder : {//圆锥 length : 222000.0, topRadius : 60000.0, bottomRadius : 60000.0, //topRadius和bottomRadius相等时,圆柱 material : Cesium.Color.YELLOW } }); // 灯笼的流苏 function shape(lon,lat,increaseradians,radius,increaseradius){ var i = 0; var newradius = radius; var yellowCones = []; var yellowConel = 0; for (newradius;newradius>0;newradius-=increaseradius){ console.log(newradius); for(i;i < 360;i+=increaseradians ){ console.log(i); var radians = Cesium.Math.toRadians(i); var newlon = lon + newradius * Math.cos(radians); var newlat = lat + newradius * Math.sin(radians)/2; yellowCones[yellowConel++] = viewer.entities.add({ name : 'yellow cone', position: Cesium.Cartesian3.fromDegrees(newlon, newlat, 150000.0), cylinder : {//圆锥 length : 200000.0, topRadius : 500.0, bottomRadius : 500.0, //topRadius和bottomRadius相等时,圆柱 material : Cesium.Color.RED } }); } i = i%360; } } // 经度、纬度、循环弧度、半径、循环半径 shape(-100.0,40.0,10,0.54,0.2);
-
多边形(Polygons)
var Polygon = viewer.entities.add({ name : '每个顶点具有不同拉伸高度的具有挖空效果的橘色多边形', polygon : { // hierarchy : Cesium.Cartesian3.fromDegreesArrayHeights( // 普通不带挖空效果的polygon // [-108.0, 42.0, 100000, // -106.0, 45.0, 300000, // -104.0, 46.0, 100000, // -100.0, 42.0, 300000, // -104.0, 40.0, 200000, // -106.0, 41.0, 400000 // ]), hierarchy : { positions : Cesium.Cartesian3.fromDegreesArrayHeights( // 高度相同时,不用z值,可以直接指定extrudedHeight,使用fromDegreesArray [-99.0, 30.0, 100000, -85.0, 30.0, 100000, -85.0, 40.0, 100000, -99.0, 40.0, 100000]), holes : [{ positions : Cesium.Cartesian3.fromDegreesArrayHeights([ -97.0, 31.0, 200000, -97.0, 39.0, 200000, -87.0, 39.0, 200000, -87.0, 31.0, 200000 ]), holes : [{ positions : Cesium.Cartesian3.fromDegreesArrayHeights([ -95.0, 33.0, 300000, -89.0, 33.0, 300000, -89.0, 37.0, 300000, -95.0, 37.0, 300000 ]), holes : [{ positions : Cesium.Cartesian3.fromDegreesArrayHeights([ -93.0, 34.0, 400000, -91.0, 34.0, 400000, -91.0, 36.0, 400000, -93.0, 36.0, 400000 ]) }] }] }] }, extrudedHeight: 0, //高度在坐标里设置! perPositionHeight : true, //指定使用每个坐标自带的高度! material : Cesium.Color.ORANGE, outline : true, outlineColor : Cesium.Color.BLACK } });
-
多段线(Polylines)
var redLine = viewer.entities.add({ name : '沿着地球表面的红线', polyline : { positions : Cesium.Cartesian3.fromDegreesArray( [-75, 35, -125, 35]), width : 5, material : Cesium.Color.RED } }); var glowingLine = viewer.entities.add({ name : '具有发光效果的线', polyline : { positions : Cesium.Cartesian3.fromDegreesArray( [-75, 37, -125, 37] ), width : 10, material : new Cesium.PolylineGlowMaterialProperty({ glowPower : 0.2, color : Cesium.Color.BLUE }) } }); var orangeOutlined = viewer.entities.add({ name : '具有一定高度的线', polyline : { positions : Cesium.Cartesian3.fromDegreesArrayHeights( [-75, 39, 250000,-125, 39, 250000] ), width : 5, followSurface : true, //控制是否贴着地表 material : new Cesium.PolylineOutlineMaterialProperty({ color : Cesium.Color.ORANGE, outlineWidth : 2, outlineColor : Cesium.Color.BLACK }) } });
-
多段线体(Polyline Volumes)
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; } function computeStar(arms, rOuter, rInner) { var angle = Math.PI / arms; var length = 2 * arms; var positions = new Array(length); for (var i = 0; i < length; i++) { var r = (i % 2) === 0 ? rOuter : rInner; positions[i] = new Cesium.Cartesian2( Math.cos(i * angle) * r, Math.sin(i * angle) * r); } return positions; } var greenBox = viewer.entities.add({ name : 'Green box with beveled corners and outline', polylineVolume : { positions : Cesium.Cartesian3.fromDegreesArrayHeights( [-90.0, 32.0, 0.0, -90.0, 36.0, 100000.0, -94.0, 36.0, 0.0]), // shape : computeCircle(60000.0), shape :[new Cesium.Cartesian2(-10000, -10000), // 横截面形状,相对值,中心点距离边界的值 new Cesium.Cartesian2(50000, -10000), new Cesium.Cartesian2(50000, 50000), new Cesium.Cartesian2(-50000, 50000)], cornerType : Cesium.CornerType.BEVELED, // 控制端点形状 material : Cesium.Color.GREEN, outline : true, outlineColor : Cesium.Color.BLACK } }); var blueStar = viewer.entities.add({ name : 'Blue star with mitered corners and outline', polylineVolume : { positions : Cesium.Cartesian3.fromDegreesArrayHeights( [-95.0, 32.0, 0.0, -95.0, 36.0, 100000.0, -99.0, 36.0, 200000.0]), shape : computeStar(8, 70000, 50000), // 横截面形状,相对值,中心点距离边界的值 cornerType : Cesium.CornerType.MITERED, // 控制端点形状 material : Cesium.Color.BLUE, outline : true, outlineColor : Cesium.Color.BLACK } });
-
矩形(Rectangles)
//绿色旋转、拉伸的矩形 应该不会用到的吧。。。。。 var greenRectangle = viewer.entities.add({ name : 'Green translucent, rotated, and extruded rectangle', rectangle : { coordinates : Cesium.Rectangle.fromDegrees(-100.0, 30.0, -90.0, 40.0), material : Cesium.Color.GREEN.withAlpha(0.5), rotation : Cesium.Math.toRadians(45), extrudedHeight : 300000.0, height : 100000.0, outline : true, outlineColor : Cesium.Color.GREEN } });
-
球和椭球(Spheres Ellipsoids)
var yellowEllipsoid = viewer.entities.add({ name : 'Yellow ellipsoid outline', position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0), ellipsoid : { radii : new Cesium.Cartesian3(200000.0, 200000.0, 100000.0), fill : true, material : Cesium.Color.RED, outline : true, outlineColor : Cesium.Color.YELLOW, slicePartitions : 24, //横向切割线 不能小于3 stackPartitions : 24 //纵向切割线 不能小于3 } });
-
墙(Walls)
var greenWall = viewer.entities.add({ name : 'Green wall from surface with outline', wall : { positions : Cesium.Cartesian3.fromDegreesArrayHeights( [-107.0, 43.0, 100000.0, -97.0, 43.0, 100000.0, -97.0, 40.0, 100000.0, -107.0, 40.0, 100000.0, -107.0, 43.0, 100000.0]), fill: false, // material : Cesium.Color.RED, // minimumHeights : [100000.0, 100000.0], // 下高 // maximumHeights: [200000.0, 200000.0], // 上高 outline : true, outlineColor : Cesium.Color.RED , outlineWidth: 2.0 } });
说明
- 材质(Material)与轮廓(Outline)
多数形状均支持通过一致的方式来设置属性、控制外观:
(1)fill:布尔型,用于指定目标形状是否被填充
(2)outline:布尔型,用于指定是否绘制形状的边缘
(3)material:如果fill为true,该属性可以控制填充的材质类型
一个例外是多段线,可以设置outlineWidth 、outlineColor、glowPower 等属性。
- 高度与拉伸(Extrusion)
所有的形状均默认均是沿着地表的,目前圆形、椭圆、矩形可以在一定高度浮空显示,或者拉伸为Volume。
需要注意:Cesium总是使用米、弧度、秒为度量单位。下面是一个例子:
wyoming.polygon.height = 200000; //设置高度
wyoming.polygon.extrudedHeight = 250000; //设置拉伸高度
- 在Viewer中可用的Entity特性
除非气泡窗口被禁用,点击实体后会显示SelectionIndicator小器件,以及一个信息框。通过设置Entity.description,可以在信息框中显示任何HTML内容。
- 镜头控制
zoomTo方法可以立即定位到某个位置,而flyTo则是通过动画方式转移到某个位置,这两个方法均可以传递EntityCollection对象,并且均是异步方法,返回一个Promises对象
默认情况下,镜头是朝北、45度倾斜查看地球。下面的代码可以让镜头朝东、倾斜三十度查看:
//镜头顺时针旋转九十度,即东向
var heading = Cesium.Math.toRadians(90);
//镜头倾斜30度俯视
var pitch = Cesium.Math.toRadians(-30);
viewer.zoomTo(wyoming, new Cesium.HeadingPitchRange(heading, pitch)).then(function(result){
//执行完毕后,进行的动作
if (result) { //如果镜头切换成功,则result=true
viewer.selectedEntity = wyoming;
}
});
有时需要镜头跟踪某个实体(使居中)而不是地球,可以使用如下代码:
wyoming.position = Cesium.Cartesian3.fromDegrees(-107.724, 42.68);
viewer.trackedEntity = wyoming; //跟踪某个实体。如果调用zoomTo、flyTo自动取消跟踪
- 管理Entity
EntityCollection对象是一个从Entity Id到Entity的关联数组,其提供例如add、remove、removeAll之类的常规函数,用于添加或者删除某个Entity:
//添加一个实体,并且提供ID
viewer.entities.add({
id : '182bdba4-2b3e-47ae-bf0b-83f6fde285fd'
});
//获取一个实体
var entity = viewer.entities.getById('uniqueId')
//获取一个实体,如果不存在则创建之
var entity = viewer.entities.getOrCreateEntity('uniqueId');
//当添加、删除、修改EntityCollection中的Entity时,可以获得事件通知
function onChanged(collection, added, removed, changed){
//add、removed、changed是增删改的Entity数组
for(var i = 0; i < added.length; i++) {
}
}
viewer.entities.collectionChanged.addEventListener(onChanged);
//大批量操作时,临时禁用事件可以提高性能
viewer.entities.suspendEvents();
//执行各种Entity操作
viewer.entities.resumeEvents();
二、点、图标和标签
添加一个点、标签或者图标:
var viewer = new Cesium.Viewer( 'cesiumContainer' );
var citizensBankPark = viewer.entities.add( {
name : 'Citizens Bank Park',
position : Cesium.Cartesian3.fromDegrees( -75.166493, 39.9060534 ),
point : { //点
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2
},
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 ), //偏移量
NearFarScalar : scaleByDistance: new Cesium.NearFarScalar(2000, 1, 8000, 0),图标或文字随视角缩放
}
billboard : { //图标
image : 'http://localhost:81/images/2015/02-02/Philadelphia_Phillies.png',
width : 64,
height : 64
},
} );
viewer.zoomTo( viewer.entities );
三、3D模型
Cesium支持glTF格式的3D模型,glTF是WebGL、 OpenGL ES、 OpenGL的一种运行时模型格式,在Cesium中创建3D模型:
var viewer = new Cesium.Viewer('cesiumContainer');
var entity = viewer.entities.add({
position : Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706),
model : {
uri : '../../SampleData/models/CesiumGround/Cesium_Ground.gltf'
},
scale : 1,//和原始大小相比的缩放比例
minimumPixelSize :100 //最小尺寸,防止太小而看不见
});
viewer.trackedEntity = entity;
默认情况下,模型竖直放置、并且面向东面。可以指定四元组(Quaternion)给Entity.orientation属性,以改变放置的方向:
var viewer = new Cesium.Viewer('cesiumContainer');
var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706); //位置
var heading = Cesium.Math.toRadians(45.0);//绕垂直于地心的轴旋转
var pitch = Cesium.Math.toRadians(15.0); //绕纬度线旋转
var roll = Cesium.Math.toRadians(0.0); //绕经度线旋转
var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, heading, pitch, roll);
var entity = viewer.entities.add({
position : position,
orientation : orientation,
model : {
uri : '../../SampleData/models/CesiumGround/Cesium_Ground.gltf'
}
});
viewer.trackedEntity = entity;
例子中的heading(yaw)、pitch、roll对应了绕Z(垂直轴)、Y(维度方向)、X(经度方向)进行旋转,正数表示顺时针旋转(由于相对运动,在浏览器上看起来是地球在逆时针旋转)
四、属性系统
Cesium提供了一些快捷方式来设置属性,例如outline:true,但是尝试使用e.polygon.outline这样的形式来获取轮廓时,会得到一个ConstantProperty对象,如果不使用快捷方式,则需要编写更多的代码,例如:
polygon.outline = new Cesium.ConstantProperty(true);
polygon.outlineColor = new Cesium.ConstantProperty(Cesium.Color.BLACK);
所有属性的实例均是Property的子类型,引入属性类层次而不是使用基本类型的原因是,某些属性是随着时间而变化的。
要得到属性的原始值,需要调用Property.getValue()方法,例如:
//获取当前时间点,多边形轮廓是否存在
polygon.outline.getValue(viewer.clock.currentTime)