Cesium:入门教程(四)之 Entities

Entities

   为了便于可视化,Cesium 支持流行的矢量格式 ① GeoJson② KML(最初为Google定义的文件格式),以及一种 Cesium 团队自己开源的格式,专门开发用于描述Cesium场景的 ③ CZML

    无论最初是什么格式,所有的空间矢量数据在Cesium里都是使用Entity 相关API去展示的。Entity API 使用了灵活高效的可视化渲染方式。Entity 是一种对几何图形做空间和时间展示的数据对象。

    不同 Entity 类型:Polygon    Polyline    Billboard    Label (注:POI点默认都是使用 BillboardsLabels 显示

    为了读取数据文件,需要根据你的数据格式创建一个合适的 DataSource ,它将负责解析你配置的url里的数据,然后创建一个EntityCollection用来存储从数据里加载的每一个Entity 。DataSource 只是定义一些接口,依据数据格式的不同会有不同的解析过程。比如,KML 使用 KmlDataSourceGeoJson 使用 GeoJsonDataSourceCZML 使用 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模型的基础上,看该属性的结果: 

TERRAIN(左);BOTH(中);CESIUM_3D_TILE(右)

    添加文字标注 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的区别在于它可以带符号、颜色、样式信息 [链接​​​​​​​]。

     其他:python读取kml为geojson

  📍 KMZ 是一个经过ZIP格式压缩过的 KML 文件,其文件自身可以包含图标,影像和模型等。KMZ/KML 可以被 Google Earth、Google Map 和 ArcGIS Earth 等识别并显示。

    这里直接用解压文件夹下 ./APP/SampleData/kml/bikeRide.kml 

    对于KmlDataSource,cameracanvas 选项必须要配置。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 入门-13

参考

    使用 Cesium 动态加载 GeoJSON 点数据

    Cesium加载geojson线数据

    官方完整实例代码 

    cesium之城市行政划分 - 努力啊少年 - 博客园 (cnblogs.com)

系列

    Cesium:入门教程(一)之 Hello World

    Cesium:入门教程(二)之数据源加载

    Cesium:入门教程(三)之视窗配置

    Cesium:入门教程(四)之 Entities

    Cesium:入门教程(五)之 3D Tiles

    Cesium:入门教程(六)之 交互性(Interactivity)

   ⭐希望大家多多点赞、收藏!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值