Cesium:入门教程(四)之 Entities
Entities
为了便于可视化,Cesium 支持流行的矢量格式 ① GeoJson 和 ② KML(最初为Google定义的文件格式),以及一种 Cesium 团队自己开源的格式,专门开发用于描述Cesium场景的 ③ CZML。
无论最初是什么格式,所有的空间矢量数据在Cesium里都是使用Entity 相关API去展示的。Entity API 使用了灵活高效的可视化渲染方式。Entity 是一种对几何图形做空间和时间展示的数据对象。
不同 Entity 类型:Polygon Polyline Billboard Label (注:POI点默认都是使用 Billboards 和 Labels 显示
为了读取数据文件,需要根据你的数据格式创建一个合适的 DataSource ,它将负责解析你配置的url里的数据,然后创建一个EntityCollection
用来存储从数据里加载的每一个Entity
。DataSource 只是定义一些接口,依据数据格式的不同会有不同的解析过程。比如,KML 使用 KmlDataSource;GeoJson 使用 GeoJsonDataSource;CZML 使用 CzmlDsataSource。
因为数据是异步加载的,所以 .load 这个函数实际返回一个 Promise , 最后使用 xxxDataSource 存储我们新创建的Entity。Promise
是一种异步处理机制,这里的“异步”是指需要在.then
函数里操作数据,而不是直接在 .load
函数之后立即操作。为了能在scene中使用这些载入的 Entity,只有当这个promise的then回调中才可以把 xxxDataSource
添加到 viewer.datasources。
这些新加入到场景的 Entity 默认有很多功能。单击它们会在 Infobox 显示属性, 双击它相机转换为居中观察模式(look at)。使用HOME按钮或者infobox旁边的相机按钮可以停止这种模式。
官方案例的数据
https://github.com/CesiumGS/cesium-workshop
注:之前没找到官方案例的数据源,所以在学习时用了自己已有的数据,现在找到官方数据源了,就不用那么麻烦了。
GeoJson
面数据
这里使用 阿里云DATAV GeoAtlas 的全国数据为例,把数据下载到本地 /Cesium-1.62/Source/Data/china.json,浏览器打开 http://localhost:8080/Apps/HelloWorld.html 后,漫游到 China
var geojsonOptions = {
clampToGround : true
};
var neighborhoodsPromise = Cesium.GeoJsonDataSource.load('../Source/Data/全国.json', geojsonOptions);
var neighborhoods;
neighborhoodsPromise.then(function(dataSource) {
viewer.dataSources.add(dataSource);
neighborhoods = dataSource.entities;
// 获取enity列表遍历
var neighborhoodEntities = dataSource.entities.values;
for (var i = 0; i < neighborhoodEntities.length; i++) {
var entity = neighborhoodEntities[i];
if (Cesium.defined(entity.polygon)) {
// 设置每个entity的name属性和行政区的名称相同
// entity.name = entity.properties.name;
entity.polygon.material = Cesium.Color.fromRandom({ // 通过ColorMaterialProperty设置随机颜色Color,而不是把所有的区域都设置成一样的颜色。
red : 0.1,
maximumGreen : 0.5,
minimumBlue : 0.5,
alpha : 0.6
});
}
}
});
点击会弹出相应的属性信息(文件含中文要注意编码格式
classificationType属性为Terrain(贴地形),3D Tile(贴模型) 或 Both(默认)
// BOTH 或 CESIUM_3D_TILE 或 TERRAIN
entity.polygon.classificationType = Cesium.ClassificationType.BOTH;
在再加载一个3d tiles模型的基础上,看该属性的结果:
添加文字标注 Label。 为了保证显示效果清晰,我们设置了一个 disableDepthTestDistance 确保这个标注不会被其他对象盖住。(之前尝试时Label一直没显示,用官方案例数据 sampleNeighborhoods.geojson 时放大到一定程度才看得到
但用自己的数据不知道为什么会出现重复一样的Label,留个坑....2020年8月更新:查看了一下全国.json数据,应该是因为里面包含子区域,每个省由几个市组织而成,每个市被当作一个Polygon构成省的MultiPolygon,所以 neighborhoodEntities.length 的值不是预想的35,而是288,所以在添加标注时会显示多个同样的市名称。
其他链接:【GeoJson Type】 【EntityCollection】
var polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;
var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
entity.position = polyCenter;
// Generate labels
entity.label = {
text : entity.name,
showBackground : true, // 文字后是否显示背景
// fillColor:Cesium.Color.BLACK, // 字体颜色
// backgroundColor:Cesium.Color.AQUA, // 背景颜色
scale : 0.4,
horizontalOrigin : Cesium.HorizontalOrigin.CENTER,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
// distanceDisplayCondition : new Cesium.DistanceDisplayCondition(10.0, 8000.0),
// disableDepthTestDistance : Number.POSITIVE_INFINITY,
// pixelOffset : new Cesium.Cartesian2(0.0, -15.0), // 向上移(x向右为正,y向下为正)
};
点数据
用cesium解压文件夹下 /APP/SampleData/simplestyles.geojson 为例加载一下点数据
Cesium.GeoJsonDataSource.load('./SampleData/simplestyles.geojson').then(function(dataSource) {
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
entity.billboard = undefined;
entity.point = new Cesium.PointGraphics({
color: Cesium.Color.WHITE,
pixelSize: 10
});
}
});
需要先设置 entity.billboard = undefined
,否则会显示一个图标而不是点,就像这样:
线数据
cesium自带的数据里没看到线数据,就用自己的shp数据转换成geojson(深圳福田区的区划线)(注:可以通过mapshaper转换得到geojson数据
Cesium.GeoJsonDataSource.load('../Source/Data/福田区划线.json').then(function(dataSource) {
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
entity.polyline.width = 10; //添加默认样式
entity.polyline.material = new Cesium.PolylineGlowMaterialProperty({
glowPower: .1, //一个数字属性,指定发光强度,占总线宽的百分比。
color: Cesium.Color.ORANGERED.withAlpha(.9)
});
}
});
KML
KML文件是谷歌公司创建的一种地标性文件。用于记录某一地点、或连续地点的时间、经度、纬度、海拔等地理信息数据 [KML文件打开方式]。kml是xml格式的一种特殊化,原来用于Google Earth的数据交互,它与geojson的区别在于它可以带符号、颜色、样式信息 [链接]。
📍 KMZ 是一个经过ZIP格式压缩过的 KML 文件,其文件自身可以包含图标,影像和模型等。KMZ/KML 可以被 Google Earth、Google Map 和 ArcGIS Earth 等识别并显示。
这里直接用解压文件夹下 ./APP/SampleData/kml/bikeRide.kml
对于KmlDataSource,camera
和 canvas
选项必须要配置。clampToGround
选项控制数据是否贴地,贴地效果是最常见的矢量数据可视化效果,保证数据紧贴地形起伏,而不是仅仅相对WGS84绝对球表面。
var kmlOptions = {
camera : viewer.scene.camera,
canvas : viewer.scene.canvas,
clampToGround : true
};
var geocachePromise = Cesium.KmlDataSource.load('./SampleData/kml/bikeRide.kml', kmlOptions);
geocachePromise.then(function(dataSource) {
viewer.dataSources.add(dataSource);
var entities = dataSource.entities.values;
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
if (Cesium.defined(entity.billboard)) {
// entity.label = undefined; // 去掉文字的显示
entity.point = new Cesium.PointGraphics({
color: Cesium.Color.BLUE,
pixelSize: 10
});
}
}
});
Infobox的标题栏显示的是entity的name属性, 它的内容显示的是description属性(使用HTML文本显示)。
CZML
CZML是一种在Cesium里描述时序图形场景的文件格式。它包含折线(lines)、点(points)、图标(billboards)、模型(models)和其他图形元素,以及他们随时间变化的属性。如同Google Earth的KML,CZML通过一种描述性语言(基于json格式)来存储Cesium大部分的功能。
Cesium支持加载 gltf 格式的三维模型格式。我们可以用一个三维模型去表示,而不是仅仅用一个简单的点。
var dronePromise = Cesium.CzmlDataSource.load('../Source/Data/sampleFlight.czml');
var drone;
dronePromise.then(function(dataSource) {
viewer.dataSources.add(dataSource);
// 使用id获取在CZML 数据中定义的无人机entity
drone = dataSource.entities.getById('Aircraft/Aircraft1');
// 附加一些三维模型
drone.model = {
uri : '../Source/Data/CesiumDrone.gltf',
minimumPixelSize : 100,
maximumScale : 500,
silhouetteColor : Cesium.Color.WHITE,
silhouetteSize : 2
};
// 实时计算飞行时,模型的巡航角度
drone.orientation = new Cesium.VelocityOrientationProperty(drone.position);
// 圆滑路径,使路径相对平滑过渡 插值过渡
drone.position.setInterpolationOptions({
interpolationAlgorithm : Cesium.HermitePolynomialApproximation, //插值算法
interpolationDegree : 2
});
// drone.viewFrom = new Cesium.Cartesian3(0, -30, 30);
// viewer.trackedEntity = drone;
});
Cesium:入门教程(三)之 视窗配置 中提到了Drone Mode(无人机模式),即我们可以使用摄像机的内置实体跟踪功能来定位摄像机。
drone.viewFrom = new Cesium.Cartesian3(0, -30, 30);
viewer.trackedEntity = drone;
注:场景动画默认不开启,运行后可以点击 ,或者设置开启场景动画
var viewer = new Cesium.Viewer('cesiumContainer',{shouldAnimate: true});
Entities 可见性
参考
cesium之城市行政划分 - 努力啊少年 - 博客园 (cnblogs.com)
系列
Cesium:入门教程(六)之 交互性(Interactivity)
⭐希望大家多多点赞、收藏!
更多推荐
所有评论(0)