Cesium 概述 (二) 空间数据可视化

来源:互联网 发布:snmp 端口 编辑:程序博客网 时间:2024/04/29 22:04

                                                              空间数据可视化

Cesium提供Entity API来绘制空间数据,例如点、标记、标签、线、3D模型、形状、立体形状(volume)。

Entity API简介

Cesium提供两类API:

  1. (1)面向图形开发人员的底层API,通常称为“Primitive API”。该API暴露最小限度的抽象,使用图形学术语,具有很大的灵活性,需要具有图形学编程的知识
  2. (2)高级别的数据驱动的API,称为“Entity API”。该API使用一致性设计的、高级别的对象来管理一组相关性的可视化对象,其底层使用Primitive API

下面是Entity API的简单例子,用红色半透明区域标记出美国怀俄明州:

var viewer = new Cesium.Viewer('cesiumContainer'); //创建一个查看器(Viewer widget)var wyoming = viewer.entities.add({  //添加一个实体,仅需要传递一个简单JSON对象,返回值是一个Entity对象  name : 'Wyoming',  polygon : {    hierarchy : Cesium.Cartesian3.fromDegreesArray([//一组地理坐标                              -109.080842,45.002073,                              -105.91517,45.002073,                              -104.058488,44.996596,                              -104.053011,43.002989,                              -104.053011,41.003906,                              -105.728954,40.998429,                              -107.919731,41.003906,                              -109.04798,40.998429,                              -111.047063,40.998429,                              -111.047063,42.000709,                              -111.047063,44.476286,                              -111.05254,45.002073]),    material : Cesium.Color.RED.withAlpha(0.5), //材质    outline : true, //是否显示轮廓    outlineColor : Cesium.Color.BLACK //轮廓的颜色  }});viewer.zoomTo(wyoming);//缩放、平移视图使实体可见 

形状与立体(Shapes and Volumes)

支持的形状与立体列表

(1) 立方体(Boxes):

var blueBox = viewer.entities.add({    name : 'Blue box',     //中心的位置    position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),    box : {        //长宽高        dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),        material : Cesium.Color.BLUE    }}); 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,        outline : true, //显示轮廓        outlineColor : Cesium.Color.BLACK    }}); var outlineOnly = viewer.entities.add({    name : 'Yellow box outline',    position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 300000.0),    box : {        dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),        fill : false,  //不显示填充        outline : true,        outlineColor : Cesium.Color.YELLOW    }});

(2)圆和椭圆(Circles Ellipses)

var viewer = new Cesium.Viewer('cesiumContainer');//浮空的绿色圆形var greenCircle = viewer.entities.add({    position: Cesium.Cartesian3.fromDegrees(-111.0, 40.0, 150000.0),    name : 'Green circle at height',    ellipse : {        semiMinorAxis : 300000.0,        semiMajorAxis : 300000.0,        height: 200000.0, //浮空        material : Cesium.Color.GREEN    }});//红色椭圆形,位于地表,带轮廓var redEllipse = viewer.entities.add({    //不带高度    position: Cesium.Cartesian3.fromDegrees(-103.0, 40.0),    name : 'Red ellipse on surface with outline',    ellipse : {        semiMinorAxis : 250000.0,        semiMajorAxis : 400000.0,        material : Cesium.Color.RED.withAlpha(0.5),        outline : true,        outlineColor : Cesium.Color.RED    }});//蓝色椭圆柱,旋转了角度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,        extrudedHeight : 200000.0,  //拉伸        rotation : Cesium.Math.toRadians(45), //旋转        material : Cesium.Color.BLUE.withAlpha(0.7),        outline : true    }}); viewer.zoomTo(viewer.entities);

(3)走廊(Corridor)

var redCorridor = viewer.entities.add({    name : 'Red corridor on surface with rounded corners and outline',    corridor : {        positions : Cesium.Cartesian3.fromDegreesArray([                                                        -100.0, 40.0,                                                        -105.0, 40.0,                                                        -105.0, 35.0                                                    ]),                                                    width : 200000.0,        material : Cesium.Color.RED.withAlpha(0.5),        outline : true,        outlineColor : Cesium.Color.RED    }}); var greenCorridor = viewer.entities.add({    name : 'Green corridor at height with mitered corners',    corridor : {        positions : Cesium.Cartesian3.fromDegreesArray(        [    -90.0, 40.0,             -95.0, 40.0,             -95.0, 35.0        ]),        height: 100000.0,        width : 200000.0,        cornerType: Cesium.CornerType.MITERED,        material : Cesium.Color.GREEN    }}); var blueCorridor = viewer.entities.add({    name : 'Blue extruded corridor with beveled corners and outline',    corridor : {        positions : Cesium.Cartesian3.fromDegreesArray(        [    80.0, 40.0,             -85.0, 40.0,             -85.0, 35.0        ]),        height : 200000.0,        extrudedHeight : 100000.0,        width : 200000.0,        cornerType: Cesium.CornerType.BEVELED,        material : Cesium.Color.BLUE.withAlpha(0.5),        outline : true,        outlineColor : Cesium.Color.BLUE    }});

(4)圆柱和圆锥(Cylinder Cones)

var greenCylinder = viewer.entities.add({    name : 'Green cylinder with black outline',    position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 200000.0),    cylinder : { //圆柱        length : 400000.0,        topRadius : 200000.0,        bottomRadius : 200000.0,        material : Cesium.Color.GREEN,        outline : true,        outlineColor : Cesium.Color.DARK_GREEN    }}); var redCone = viewer.entities.add({    name : 'Red cone',    position: Cesium.Cartesian3.fromDegrees(-105.0, 40.0, 200000.0),    cylinder : {//圆锥        length : 400000.0,        topRadius : 0.0,        bottomRadius : 200000.0,        material : Cesium.Color.RED    }});

(5) 多边形(Polygons)

var redPolygon = viewer.entities.add({    name : '贴着地表的多边形',    polygon : {        hierarchy : Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0,                                                        -115.0, 32.0,                                                        -107.0, 33.0,                                                        -102.0, 31.0,                                                        -102.0, 35.0]),        material : Cesium.Color.RED    }}); var greenPolygon = viewer.entities.add({    name : '绿色拉伸多边形',    polygon : {        hierarchy : Cesium.Cartesian3.fromDegreesArray([-108.0, 42.0,                                                        -100.0, 42.0,                                                        -104.0, 40.0]),        extrudedHeight: 500000.0,        material : Cesium.Color.GREEN    }}); var orangePolygon = viewer.entities.add({    name : '每个顶点具有不同拉伸高度的橘色多边形',    polygon : {        hierarchy : Cesium.Cartesian3.fromDegreesArrayHeights(            [-108.0, 25.0, 100000,             -100.0, 25.0, 100000,             -100.0, 30.0, 100000,             -108.0, 30.0, 300000]),        extrudedHeight: 0,        perPositionHeight : true,        material : Cesium.Color.ORANGE,        outline : true,        outlineColor : Cesium.Color.BLACK    }}); var bluePolygon = viewer.entities.add({    name : '具有挖空效果的蓝色多边形',    polygon : {        hierarchy : {            positions : Cesium.Cartesian3.fromDegreesArray(                [-99.0, 30.0,                 -85.0, 30.0,                 -85.0, 40.0,                 -99.0, 40.0]),            holes : [{                positions : Cesium.Cartesian3.fromDegreesArray([                    -97.0, 31.0,                    -97.0, 39.0,                    -87.0, 39.0,                    -87.0, 31.0                ]),                holes : [{                    positions : Cesium.Cartesian3.fromDegreesArray([                        -95.0, 33.0,                        -89.0, 33.0,                        -89.0, 37.0,                        -95.0, 37.0                    ]),                    holes : [{                        positions : Cesium.Cartesian3.fromDegreesArray([                            -93.0, 34.0,                            -91.0, 34.0,                            -91.0, 36.0,                            -93.0, 36.0                        ])                    }]                }]            }]        },        material : Cesium.Color.BLUE,        outline : true,        outlineColor : Cesium.Color.BLACK    }});

(6)多段线(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,        material : new Cesium.PolylineOutlineMaterialProperty({            color : Cesium.Color.ORANGE,            outlineWidth : 2,            outlineColor : Cesium.Color.BLACK        })    }}); var yellowLine = viewer.entities.add({    name : '不贴着地表的线',    polyline : {        positions : Cesium.Cartesian3.fromDegreesArrayHeights(            [-75, 43, 500000,-125, 43, 500000]        ),        width : 3,        followSurface : false,  //是否贴着地表        material : Cesium.Color.PURPLE    }});
(7)多段线体(Polyline Volumes)
var viewer = new Cesium.Viewer('cesiumContainer'); 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 redTube = viewer.entities.add({    name : 'Red tube with rounded corners',    polylineVolume : {        positions : Cesium.Cartesian3.fromDegreesArray(            [-85.0, 32.0,             -85.0, 36.0,             -89.0, 36.0]),        shape : computeCircle(60000.0),        material : Cesium.Color.RED    }}); 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 :[new Cesium.Cartesian2(-50000, -50000),                new Cesium.Cartesian2(50000, -50000),                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(7, 70000, 50000),        cornerType : Cesium.CornerType.MITERED,        material : Cesium.Color.BLUE,        outline : true,        outlineColor : Cesium.Color.BLACK    }}); viewer.zoomTo(viewer.entities);

(8)矩形(Rectangles)

<strong>//红色矩形var redRectangle = viewer.entities.add({    name : 'Red translucent rectangle with outline',    rectangle : {        coordinates : Cesium.Rectangle.fromDegrees(-110.0, 20.0, -80.0, 25.0),        material : Cesium.Color.RED.withAlpha(0.5),        outline : true,        outlineColor : Cesium.Color.RED    }});//绿色旋转、拉伸的矩形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    }});</strong>

(9)球和椭球(Spheres Ellipsoids)

<pre name="code" class="javascript">var blueEllipsoid = viewer.entities.add({    name : 'Blue ellipsoid',    position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),    ellipsoid : {        //可以指定三个轴的半径        radii : new Cesium.Cartesian3(200000.0, 200000.0, 300000.0),        material : Cesium.Color.BLUE    }}); var redSphere = viewer.entities.add({    name : 'Red sphere with black outline',    position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0),    ellipsoid : {        //正球体        radii : new Cesium.Cartesian3(300000.0, 300000.0, 300000.0),        material : Cesium.Color.RED,        outline : true,        outlineColor : Cesium.Color.BLACK    }}); var outlineOnly = 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, 300000.0),        fill : false,        outline : true,        outlineColor : Cesium.Color.YELLOW,        slicePartitions : 24, //横向切割线        stackPartitions : 36  //纵向切割线    }});


(10) (Walls)

//东西方向的横墙var redWall = viewer.entities.add({    name : 'Red wall at height',    wall : {        positions : Cesium.Cartesian3.fromDegreesArrayHeights(             [-115.0, 44.0, 200000.0,//坐标点              -90.0, 44.0, 200000.0]        ),        minimumHeights : [100000.0, 100000.0], //按坐标点的最小高度数组        material : Cesium.Color.RED    }});//四边围墙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]),        material : Cesium.Color.GREEN,        outline : true,        outlineColor : Cesium.Color.BLACK    }});//曲折的墙var blueWall = viewer.entities.add({    name : 'Blue wall with sawtooth heights and outline',    wall : {        //坐标点,不指定高度        positions : Cesium.Cartesian3.fromDegreesArray(            [-115.0, 50.0,             -112.5, 50.0,             -110.0, 50.0,             -107.5, 50.0,             -105.0, 50.0,             -102.5, 50.0,             -100.0, 50.0,             -97.5, 50.0,             -95.0, 50.0,             -92.5, 50.0,             -90.0, 50.0]),        maximumHeights : [ //上高            100000, 200000, 100000, 200000, 100000, 200000,             100000, 200000, 100000, 200000, 100000],        minimumHeights : [  //下高            0, 100000,  0, 100000, 0, 100000, 0, 100000, 0,            100000, 0],        material : Cesium.Color.BLUE,        outline : true,        outlineColor : Cesium.Color.BLACK    }});

材质(Material)与轮廓(Outline)

多数形状均支持通过一致的方式来设置属性、控制外观:

  1. (1)fill:布尔型,用于指定目标形状是否被填充
  2. (2)outline:布尔型,用于指定是否绘制形状的边缘
  3. (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:

//添加一个实体,并且提供IDviewer.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 )   //偏移量    }    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(经度方向)进行旋转,正数表示顺时针旋转(由于相对运动,在浏览器上看起来是地球在逆时针旋转),可以参考下图理解(人面向北面,摇头heading、点头pitch、歪头roll):

                            

属性系统

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)
















0 0
原创粉丝点击