Cesium(三) 几何图形与外观

                                                           几何图形与外观

我们可以通过Primitive API来操控几何图形及其外观,或者绘制各种特殊的形状。需要先得到Scene对象,然后在其上添加Primitive对象:

var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
 
scene.primitives.add(new Cesium.RectanglePrimitive({
    //绘制矩形
    rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
    material : Cesium.Material.fromType('Dot')  //设置材质
}));

Primitive由两个部分组成:

  1. (1)几何形状(Geometry):定义了Primitive的结构,例如三角形、线条、点等
  2. (2)外观(Appearance ):定义Primitive的着色(Sharding),包括GLSL(OpenGL着色语言,OpenGL Shading Language)顶点着色器和片段着色器( vertex and fragment shaders),以及渲染状态(render state)

Cesium支持以下几何图形:

几何图形   说明
BoxGeometry 立方体
BoxOutlineGeometry 仅有轮廓的立方体
CircleGeometry 圆形或者拉伸的圆形
CircleOutlineGeometry 只有轮廓的圆形
CorridorGeometry 走廊:沿着地表的多段线,且具有一定的宽度,可以拉伸到一定的高度
CorridorOutlineGeometry 只有轮廓的走廊
CylinderGeometry 圆柱、圆锥或者截断的圆锥
CylinderOutlineGeometry 只有轮廓的圆柱、圆锥或者截断的圆锥
EllipseGeometry 椭圆或者拉伸的椭圆
EllipseOutlineGeometry 只有轮廓的椭圆或者拉伸的椭圆
EllipsoidGeometry 椭球体
EllipsoidOutlineGeometry 只有轮廓的椭球体
RectangleGeometry 矩形或者拉伸的矩形
RectangleOutlineGeometry 只有轮廓的矩形或者拉伸的矩形
PolygonGeometry 多边形,可以具有空洞或者拉伸一定的高度
PolygonOutlineGeometry 只有轮廓的多边形
PolylineGeometry 多段线,可以具有一定的宽度
SimplePolylineGeometry 简单的多段线
PolylineVolumeGeometry 多段线柱体
PolylineVolumeOutlineGeometry 只有轮廓的多段线柱体
SphereGeometry 球体
SphereOutlineGeometry 只有轮廓的球体
WallGeometry
WallOutlineGeometry 只有轮廓的墙

使用Geometry和Appearance 具有以下优势:

  1. (1)性能:绘制大量Primitive时,可以将其合并为单个Geometry以减轻CPU负担、更好的使用GPU。合并Primitive由web worker线程执行,UI保持响应性
  2. (2)灵活性:Geometry与Appearance 解耦,两者可以分别进行修改
  3. (3)低级别访问:易于编写GLSL 顶点、片段着色器、使用自定义的渲染状态 

同时,具有以下劣势:

  1. (1)需要编写更多地代码
  2. (2)需要对图形编程有更多的理解,特别是OpenGL的知识

使用来Geometry、Appearance 改写上面的例子,代码为:

var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
//GeometryInstance是Geometry的一个容器
var instance = new Cesium.GeometryInstance({
  geometry : new Cesium.RectangleGeometry({
    rectangle : Cesium.Rectangle.fromDegrees(-100.0, 20.0, -90.0, 30.0),
    vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
  })
});
//使用抽象的Primitive而不是RectanglePrimitive
scene.primitives.add(new Cesium.Primitive({
  geometryInstances : instance,
  //使用该外观,可以使矩形覆盖在地球表面,或者悬浮一定的高度
  appearance : new Cesium.EllipsoidSurfaceAppearance({
    material : Cesium.Material.fromType('Dot')
  })
}));
合并几何图形(Combing Geometries)

合并多个GeometryInstances 为一个Primitive可以极大的提高性能,下面的例子创建了2592一颜色各异的矩形,覆盖整个地球 :

var viewer = new Cesium.Viewer( 'cesiumContainer' );
var scene = viewer.scene;
 
var instances = [];
 
for ( var lon = -180.0; lon < 180.0; lon += 5.0 )
{
    for ( var lat = -90.0; lat < 90.0; lat += 5.0 )
    {
        instances.push( new Cesium.GeometryInstance( {
            geometry : new Cesium.RectangleGeometry( {
                rectangle : Cesium.Rectangle.fromDegrees( lon, lat, lon + 5.0, lat + 5.0 )
            } ),
            attributes : {
                color : Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.fromRandom( {
                    alpha : 0.5
                } ) )
            }
        } ) );
    }
}
 
scene.primitives.add( new Cesium.Primitive( {
    geometryInstances : instances, //合并
    //某些外观允许每个几何图形实例分别指定某个属性,例如:
    appearance : new Cesium.PerInstanceColorAppearance()
} ) );
选取几何图形(Picking)

即使多个 GeometryInstance被合并为单个Primitive,让然可以独立的被访问。我们可以为每一个GeometryInstance指定一个id,并且可以通过Scene.pick来判断该实例是否被选取:

var viewer = new Cesium.Viewer( 'cesiumContainer' );
var scene = viewer.scene;
 
var instance = new Cesium.GeometryInstance( {
    geometry : new Cesium.RectangleGeometry( {
        rectangle : Cesium.Rectangle.fromDegrees( -100.0, 30.0, -90.0, 40.0 )
    } ),
    id : 'rectangle-1',
    attributes : {
        color : Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.RED )
    }
} );
 
scene.primitives.add( new Cesium.Primitive( {
    geometryInstances : instance,
    appearance : new Cesium.PerInstanceColorAppearance()
} ) );
 
var handler = new Cesium.ScreenSpaceEventHandler( scene.canvas );
//设置单击事件的处理句柄
handler.setInputAction( function( movement )
{
    var pick = scene.pick( movement.position );
    if ( Cesium.defined( pick ) && ( pick.id === 'rectangle-1' ) )
    {
        console.log( '矩形被选取' );
    }
}, Cesium.ScreenSpaceEventType.LEFT_CLICK );

几何图形实例(Geometry Instances)

上面的例子中,我们已经用到了GeometryInstances,注意GeometryInstance与Geometry的关系:前者是后者的容器,多个Instance可以共用一个Geometry,并且可以通过GeometryInstances.modelMatrix属性提供不同position、scale、rotate等位置、缩放、旋转信息。例如,下面的例子使用同一个Geometry绘制了两个Instance,一个位于另一个的上方:

var viewer = new Cesium.Viewer( 'cesiumContainer' );
var scene = viewer.scene;
 
var ellipsoidGeometry = new Cesium.EllipsoidGeometry( {
    vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
    radii : new Cesium.Cartesian3( 300000.0, 200000.0, 150000.0 )//三轴半径
} );
//下方的实例
var cyanEllipsoidInstance = new Cesium.GeometryInstance( {
    geometry : ellipsoidGeometry,
    modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame( Cesium.Cartesian3.fromDegrees( -100.0, 40.0 ) ), new Cesium.Cartesian3( 0.0, 0.0, 150000.0 ) ),
    attributes : {
        color : Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.CYAN )
    }
} );
//上方的实例
var orangeEllipsoidInstance = new Cesium.GeometryInstance( {
    geometry : ellipsoidGeometry,
    modelMatrix : Cesium.Matrix4.multiplyByTranslation( Cesium.Transforms.eastNorthUpToFixedFrame( Cesium.Cartesian3.fromDegrees( -100.0, 40.0 ) ), new Cesium.Cartesian3( 0.0, 0.0, 450000.0 ) ),
    attributes : {
        color : Cesium.ColorGeometryInstanceAttribute.fromColor( Cesium.Color.ORANGE )
    }
} );
 
scene.primitives.add( new Cesium.Primitive( {
    geometryInstances : [
        cyanEllipsoidInstance, orangeEllipsoidInstance
    ],
    appearance : new Cesium.PerInstanceColorAppearance( {
        translucent : false,
        closed : true
    } )
} ) );
更新单个GeometryInstance的属性

在添加到Primitive中以后,让然可以修改几何图形的某些属性:

  1. (1)颜色:如果Primitive设置了PerInstanceColorAppearance外观,则可以修改ColorGeometryInstanceAttribute类型的颜色
  2. (2)可见性:任何实例可以修改可见性

示例代码:

var viewer = new Cesium.Viewer( 'cesiumContainer' );
var scene = viewer.scene;
 
var circleInstance = new Cesium.GeometryInstance( {
    geometry : new Cesium.CircleGeometry( {
        center : Cesium.Cartesian3.fromDegrees( -95.0, 43.0 ),
        radius : 250000.0,
        vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
    } ),
    attributes : {
        color : Cesium.ColorGeometryInstanceAttribute.fromColor( new Cesium.Color( 1.0, 0.0, 0.0, 0.5 ) ),
        show : new Cesium.ShowGeometryInstanceAttribute( true ) //显示或者隐藏
    },
    id : 'circle'
} );
var primitive = new Cesium.Primitive( {
    geometryInstances : circleInstance,
    appearance : new Cesium.PerInstanceColorAppearance( {
        translucent : false,
        closed : true
    } )
} );
scene.primitives.add( primitive );
 
//定期修改颜色
setInterval( function()
{
    var attributes = primitive.getGeometryInstanceAttributes( 'circle' );//获取某个实例的属性集
    attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue( Cesium.Color.fromRandom( {
        alpha : 1.0
    } ) );
}, 2000 );
外观(Appearances)

Primitive由两个重要部分组成:几何图形实例、外观,一个Primitive只能有一个外观,而可以有多个实例。几何图形定义了结构,外观定义了每个像素被如何着色,外观可能使用材质(Material)。这些对象的关系如下图所示:


Cesium支持下表列出的外观:

 外观  说明
MaterialAppearance 支持各种Geometry类型的外观,支持使用材质来定义着色
EllipsoidSurfaceAppearance MaterialAppearance的一个版本。假设几何图形与地表是平行的,并且依此来进行顶点属性(vertex attributes)的计算
PerInstanceColorAppearance 让每个实例使用自定义的颜色来着色
PolylineMaterialAppearance 支持使用材质来着色多段线
PolylineColorAppearance 使用每顶点或者每片段(per-vertex or per-segment )的颜色来着色多段线

外观定义了需要在GPU上执行的完整的GLSL顶点、片段着色器,通常不需要修改这一部分,除非需要定义自己的外观。

外观还定义了完整的render state,用于在绘制Primitive时控制GPU的状态,可以直接或者通过高层API来定义render state:

//下面的外观可用于定义一个Viewer不可进入的不透明盒子
var appearance = new Cesium.PerInstanceColorAppearance( {
    translucent : false,
    closed : true
} );
//下面的代码效果同上
var translucent = new Cesium.PerInstanceColorAppearance( {
    renderState : {
        depthTest : {
            enabled : true
        },
        cull : {
            enabled : true,
            face : Cesium.CullFace.BACK
        }
    }
} );

一旦外观被创建,其render state就不可再变,但是其材质是可以替换的。另外Primitive的外观也是不可修改的。

大部分外观具有flat、faceForward属性,可以间接的控制GLSL 着色器:

  1. (1)flat:扁平化着色,不考虑光线的作用
  2. (2)faceForward:布尔值,控制光照效果
Geometry与Appearance的兼容性

需要注意,不是所有外观和所有几何图形可以搭配使用,例如EllipsoidSurfaceAppearance与WallGeometry就不能搭配,原因是后者是垂直于地表的。

即使外观与几何图形兼容,它们还必须有匹配的顶点格式(vertex formats)—— 即几何图形必须具有外观可以作为输入的数据格式,在创建Geometry时可以提供VertexFormat。

为了简便,可以让Geometry计算所有顶点属性(vertex attributes),以使之适用于任何外观,但这样做效率较差:

var geometry = new Cesium.RectangleGeometry( {
    vertexFormat : Cesium.VertexFormat.ALL
} );
而如果我们使用外观EllipsoidSurfaceAppearance,其实只需要知道位置:

var geometry = new Ceisum.RectangleGeometry( {
    vertexFormat : Ceisum.VertexFormat.POSITION_ONLY
} );
大部分外观具有vertexFormat属性或者VERTEX_FORMAT 静态常量,创建形状时只需要使用这些顶点格式即可:

var geometry = new Ceisum.RectangleGeometry( {
    vertexFormat : Ceisum.EllipsoidSurfaceAppearance.VERTEX_FORMAT
} );
 
var geometry2 = new Ceisum.RectangleGeometry( {
    vertexFormat : Ceisum.PerInstanceColorAppearance.VERTEX_FORMAT
} );
 
var appearance = new Ceisum.MaterialAppearance();
var geometry3 = new Ceisum.RectangleGeometry( {
    vertexFormat : appearance.vertexFormat
} );

此外,两个形状必须具有匹配的vertexFormat,才能被合并到一个Primitive中。















  • 14
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 要在Cesium中定位Geometry,您需要使用Cesium的实体(Entity)对象。实体对象能够让您在3D场景中创建和管理几何图形对象,例如点、线、面等。 要创建一个实体对象并定位Geometry,您可以按照以下步骤进行操作: 1. 创建一个实体对象:使用Cesium.Entity()构造函数创建一个实体对象。 2. 设置实体的位置:使用实体对象的position属性设置位置。位置可以是一个经纬度坐标,也可以是一个笛卡尔坐标。 3. 创建Geometry对象:使用Cesium.Geometry()构造函数创建一个几何图形对象。您可以选择使用Cesium提供的几何图形对象,也可以自己创建一个几何图形对象。 4. 创建Appearance对象:使用Cesium.Appearance()构造函数创建一个外观对象。外观对象定义几何图形的材质、颜色等属性。 5. 将Geometry和Appearance对象附加到实体对象中:使用实体对象的geometry和appearance属性将几何图形对象和外观对象附加到实体对象中。 6. 将实体对象添加到场景中:使用Cesium的实体管理器将实体对象添加到场景中。 下面是一个示例代码,展示如何在Cesium中定位一个圆形几何对象: ```javascript var viewer = new Cesium.Viewer('cesiumContainer'); // 创建一个实体对象 var entity = new Cesium.Entity(); // 设置实体的位置 entity.position = Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883); // 创建Geometry对象 var circleGeometry = new Cesium.CircleGeometry({ center: Cesium.Cartesian3.ZERO, radius: 100000 }); // 创建Appearance对象 var circleAppearance = new Cesium.MaterialAppearance({ material: Cesium.Material.fromType('Color', { color: Cesium.Color.RED }) }); // 将Geometry和Appearance对象附加到实体对象中 entity.geometry = circleGeometry; entity.appearance = circleAppearance; // 将实体对象添加到场景中 viewer.entities.add(entity); ``` ### 回答2: Cesium是一种广泛应用于地理信息系统(GIS)和虚拟地球领域的开源JavaScript库。它提供了一个强大的地理可视化引擎,可以在网页浏览器中实时展示和交互式探索地球表面的各种地理数据。 Cesium定位geometry是Cesium中的一个功能,用于定义和处理地理空间中的几何形状。几何形状可以是点、线、面或体,它们分别代表地球上的某个位置、路径、多边形或体积。 通过Cesium定位geometry,用户可以创建和编辑各种几何形状,并将其与其他地理数据进行关联。例如,可以使用Cesium定位geometry在地球表面上标记特定的位置,将不同位置连接起来形成路径,或者定义某个区域的边界。 除了创建和编辑几何形状Cesium定位geometry还支持与其他功能和数据进行集成。例如,可以将几何形状地图、卫星图像或其他地理数据集进行叠加显示。用户还可以通过鼠标或触摸屏等交互方式来操纵几何形状,例如平移、缩放或旋转等操作。 通过Cesium定位geometry,用户可以实现对地理数据实时的可视化和交互式探索。无论是在GIS应用中还是虚拟地球环境下,它都提供了一个强大而灵活的工具,可以帮助用户更好地理解和分析地球上的空间信息。 ### 回答3: Cesium定位geometry是一种开源的JavaScript库,用于在Cesium地理空间可视化平台上进行几何定位。它提供了丰富的功能和工具,可以处理二维和三维几何对象,并允许用户在地球表面或其他地理空间上进行定位和分析。 Cesium定位geometry支持多种几何对象,包括点、线、多段线、面和体积。用户可以通过指定坐标、属性和样式信息来创建这些对象,并将其添加到Cesium地球模型中进行显示。几何对象可以具有不同的颜色、大小和形状,以满足用户的需求。 该库还提供了一系列的几何操作和分析工具,可以对几何对象进行编辑、转换和查询。用户可以通过移动、旋转和缩放几何对象来修改其位置和形状。同时,用户可以利用空间分析工具来计算几何对象之间的距离、面积和体积等参数。 Cesium定位geometry还支持基于地理信息系统(GIS)数据的几何定位。用户可以将GIS数据导入到Cesium平台中,并将其转换为几何对象进行显示和分析。这样,用户可以在地球上展示各种地理信息,如道路、建筑物、水域等,并进行进一步的定位和分析。 总的来说,Cesium定位geometry是一个功能强大的几何定位库,它为用户提供了丰富的几何对象和操作工具,帮助他们在地理空间上进行准确的定位和分析。无论是进行数据可视化、地理信息系统开发还是地理空间分析,Cesium定位geometry都能够为用户提供高效便捷的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值