Cesium中文教程-Cesium Workshop(三)

目录

(8)加载和设计实体(Loading and Styling Entities)

(9)3D瓦片(3D Tiles)

(10)交互(Interactivity)

(11)相机模式(Camera Modes)

(12)附加内容(Extras)

(13)下一步工作(Next Steps)

开发资源(Development Resources)

Showcase your work on cesiumjs.org(展示你的作品)

Discover and process content on Cesium ion


 

(8)加载和设计实体(Loading and Styling Entities)

既然我们已经使用视图配置、影像和地形,这已经为应用程序做好了准备,那么我们可以添加应用程序的主焦点--样例geocache数据(藏宝点数据)。

为了简单可视化,Cesium支持流行的矢量格式数据GeoJson和KML,还有我们特地为描述Cesium中场景所开发的开源数据格式CZML

无论初始化格式如何,Cesium中所有空间数据都使用实体API表示(the Entity API)。实体API提供了一种灵活可视化格式,这种格式对于Cesium的展现非常有效。一个Cesium实体(Entity)是一种数据对象,它可以与样式化的图形表示形式配对,并定位于空间和时间上,沙堡长廊提供了许多简单实体的例子(many examples of simple entities)。为了快速进入实体API的基础,从这些应用程序中抽出时间来阅读可视化空间数据的(Visualizing Spatial Data)教程。

下面是一些不同实体类型的示例:

一旦你掌握了实体的样子,那么使用Cesium加载数据集就变得很好理解。为了读入一个数据文件,需要创建一个适合数据格式的数据源(DataSource),其将解析托管在指定url中的数据文件,并创建一个实体收集器(EntityCollection),其包含数据集中每个地理空间对象的实体。数据源仅仅定义了数据接口-你需要的确切数据源类型取决于数据格式。例如,KML使用KmlDataSource,它是这样的:

var kmlOptions = {  
    camera : viewer.scene.camera,  
    canvas : viewer.scene.canvas,  
    clampToGround : true  
};  
// Load geocache points of interest from a KML file  
// Data from : http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods/resource/91778048-3c58-449c-a3f9-365ed203e914  
var geocachePromise = Cesium.KmlDataSource.load('./Source/SampleData/sampleGeocacheLocations.kml', kmlOptions);  

这段代码通过使用几个选项,调用KmlDataSource.load(options)来从一个KML文件中读取我们样例的藏宝点数据。对于一个KmlDataSource,相机和画布选项是必须的,clampToGround选项支持地面贴近(ground clampling),这是一种流行的显示选项,它使地面几何实体(如多边形和椭圆)符合地形,而不是曲线符合WGS84椭球面。

由于该数据是异步加载的,因此它向KmlDataSource返回一个承诺(Promise),KmlDataSource将保存我们创建的所有实体。

如果对异步函数的Promise API不熟悉的话,这里的异步主要意思是,应该对提供给.then回调函数中的数据做需要做的事情。实际上为了给场景增加这样的实体收集器,我们必须要等promise解决,然后向viewer.datasources增加KmlDataSource。 取消注释下面代码:

// Add geocache billboard entities to scene and style them  
geocachePromise.then(function(dataSource) {  
    // Add the new data as entities to the viewer  
    viewer.dataSources.add(dataSource);  
});  
 

默认情况下,新创建的实体具备可用的功能。点击将显示与实体相关的元数据信息框(Infobox),双击放大并查看实体。要停止查看实体的话,可以点击home按钮,或者点击信息框的关闭相机图标。接下来,我们将添加定制样式来改进应用程序的外观。

对于KML和CZML文件,声明样式已经创建到了文件中。然而,对于这个应用来说,我们将练习手工设置实体的样式。要这样做的话,通过等待数据源加载完成,采取一种相似的方法来实现样式例子(this styling example),然后遍历数据源中的所有实体,修改和增加属性。默认情况下,我们藏宝点标记是作为广告牌(Billboards)和标签(Labels)创建的,因此为了修改这些实体的外观,我们这样做:

// Add geocache billboard entities to scene and style them  
geocachePromise.then(function(dataSource) {  
    // Add the new data as entities to the viewer  
    viewer.dataSources.add(dataSource);  
  
    // Get the array of entities  
    var geocacheEntities = dataSource.entities.values;  
  
    for (var i = 0; i < geocacheEntities.length; i++) {  
        var entity = geocacheEntities[i];  
        if (Cesium.defined(entity.billboard)) {  
            // Entity styling code here  
        }  
    }  
});  
 

我们可以通过调整标记的锚点、移除标签以减少混乱及设置displayDistanceCondition来改善标记的外观,这样只有在相机设置的距离范围内的点才能可见。

// Add geocache billboard entities to scene and style them  
  
        if (Cesium.defined(entity.billboard)) {  
            // Adjust the vertical origin so pins sit on terrain  
            entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;  
            // Disable the labels to reduce clutter  
            entity.label = undefined;  
            // Add distance display condition  
            entity.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20000.0);  
        }  
 

更多distanceDisplayCondition的帮助,可以查看沙堡例子(sandcastle example)。

接下来,让我们改进每个藏宝点实体的Infobox。信息盒子的标题是实体的名字,内容是实体的表述,显示为HTML。

你可能注意到了,默认的描述不是很有用。由于我们正在显示藏宝点的位置,所以更新用来显示点的经纬度信息。

首先,将实体的位置转化为地图,然后从地图中读取经纬度,再增加到HTML表的描述中。

当点击的时候,藏宝点实体将显示一个格式好的信息框(Infobox),其中包含我们需要的数据。

// Add geocache billboard entities to scene and style them  
        if (Cesium.defined(entity.billboard)) {  
            // Adjust the vertical origin so pins sit on terrain  
            entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;  
            // Disable the labels to reduce clutter  
            entity.label = undefined;  
            // Add distance display condition  
            entity.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20000.0);  
            // Compute longitude and latitude in degrees  
            var cartographicPosition = Cesium.Cartographic.fromCartesian(entity.position.getValue(Cesium.JulianDate.now()));  
            var longitude = Cesium.Math.toDegrees(cartographicPosition.longitude);  
            var latitude = Cesium.Math.toDegrees(cartographicPosition.latitude);  
            // Modify description  
            // Modify description  
            var description = '<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>' +  
                '<tr><th>' + "Longitude" + '</th><td>' + longitude.toFixed(5) + '</td></tr>' +  
                '<tr><th>' + "Latitude" + '</th><td>' + latitude.toFixed(5) + '</td></tr>' +  
                '</tbody></table>';  
            entity.description = description;  
        }  
 

我们的藏宝点标记现在看起来应该是这样的:

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值