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)