cesium实现点聚合效果


Cesium实战系列文章总目录传送门

1.实现效果

在这里插入图片描述

2.实现方法

2.1官方API

Cesium官方提供了EntityCluster接口,可以实现广告牌、点、标签的聚合效果。
官方API:传送门
在这里插入图片描述官方文档中EntityCluster的配置项参数:

属性说明
enabled是否开启聚合功能
pixelRange开启聚合的像素边界范围大小
minimumClusterSize最少聚合对象的数量
clusterBillboards是否聚合广告牌
clusterLabels是否聚合标签
clusterPoints是否聚合点
shows即聚合后是否显示

官方沙盒聚合例子参考:传送门

2.2聚合图标

2.2.1原始图标

Cesium提供的图标,由PinBuilder类提供
官方API:传送门
在这里插入图片描述
可以在原始图标中添加新图标或者文字的形式生成新图标,但新图标的外形样式是固定的。

2.2.2 自定义图片

也可以根据聚合数量进行分级设置不同的聚合图标。

2.2.3 图片文字合成新图标

本文使用固定的分级图标与聚合点位数量实时合成新图标的方式。

具体将图片与文字合成新图标的方法可以参考上一篇博客:传送门

2.3代码实现:

总体实现代码如下:

/**
 * @description: 点聚合功能效果
 * @param {*} viewer
 * @return {*}
 */
function initCluster(viewer) {
    new Cesium.GeoJsonDataSource().load("./data/sz_poi.geojson").then(dataSource => {
        viewer.dataSources.add(dataSource);

        // 设置聚合参数
        dataSource.clustering.enabled = true;
        dataSource.clustering.pixelRange = 60;
        dataSource.clustering.minimumClusterSize = 2;

        // foreach用于调用数组的每个元素,并将元素传递给回调函数。
        dataSource.entities.values.forEach(entity => {
            // 将点拉伸一定高度,防止被地形压盖
            entity.position._value.z += 50.0;
            // 使用大小为64*64的icon,缩小展示poi
            entity.billboard = {
                image: './icons/poi.png',
                width: 32,
                height: 32,
            };
            entity.label = {
                text: 'POI',
                font: 'bold 15px Microsoft YaHei',
                // 竖直对齐方式
                verticalOrigin: Cesium.VerticalOrigin.CENTER,
                // 水平对齐方式
                horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
                // 偏移量
                pixelOffset: new Cesium.Cartesian2(15, 0),
            }
        });

        // 添加监听函数
        dataSource.clustering.clusterEvent.addEventListener(
            function(clusteredEntities, cluster) {
                // 关闭自带的显示聚合数量的标签
                cluster.label.show = false;
                cluster.billboard.show = true;
                cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;

                // 根据聚合数量的多少设置不同层级的图片以及大小
                if (clusteredEntities.length >= 20) {
                    cluster.billboard.image = combineIconAndLabel('./icons/cluster_4.png', clusteredEntities.length, 64);
                    cluster.billboard.width = 72;
                    cluster.billboard.height = 72;
                } else if (clusteredEntities.length >= 12) {
                    cluster.billboard.image = combineIconAndLabel('./icons/cluster_3.png', clusteredEntities.length, 64);
                    cluster.billboard.width = 56;
                    cluster.billboard.height = 56;
                } else if (clusteredEntities.length >= 8) {
                    cluster.billboard.image = combineIconAndLabel('./icons/cluster_2.png', clusteredEntities.length, 64);
                    cluster.billboard.width = 48;
                    cluster.billboard.height = 48;
                } else {
                    cluster.billboard.image = combineIconAndLabel('./icons/cluster_1.png', clusteredEntities.length, 64);
                    cluster.billboard.width = 40;
                    cluster.billboard.height = 40;
                }
            }
        )
    });
}


/**
 * @description: 将图片和文字合成新图标使用(参考Cesium源码)
 * @param {*} url:图片地址
 * @param {*} label:文字
 * @param {*} size:画布大小
 * @return {*} 返回canvas
 */
function combineIconAndLabel(url, label, size) {
    // 创建画布对象
    let canvas = document.createElement('canvas');
    canvas.width = size;
    canvas.height = size;
    let ctx = canvas.getContext("2d");

    let promise = new Cesium.Resource.fetchImage(url).then(image => {
        // 异常判断
        try {
            ctx.drawImage(image, 0, 0);
        } catch (e) {
            console.log(e);
        }

        // 渲染字体
        // font属性设置顺序:font-style, font-variant, font-weight, font-size, line-height, font-family
        ctx.fillStyle = Cesium.Color.WHITE.toCssColorString();
        ctx.font = 'bold 20px Microsoft YaHei';
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(label, size / 2, size / 2);

        return canvas;
    });
    return promise;
}

  • 12
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
SuperMap是一款专业的GIS软件,而Cesium是一个开源的WebGL地球仪库,两者结合可以实现很多GIS应用,包括聚合效果。 要实现聚合效果,首先需要获取要聚合的位置信息,并将其转换成Cesium的Entity对象。然后,可以使用Cesium的Cluster绘制器,将这些Entity对象聚合成一个新的Entity对象,作为聚合后的聚合器可以根据需要配置,调整聚合的距离、样式等参数。 以下是一个简单的示例代码,演示如何使用SuperMap和Cesium实现聚合效果: ```javascript // 初始化SuperMap地图 var map = new SuperMap.Map("mapDiv"); var layer = new SuperMap.Layer.TiledDynamicRESTLayer("World", "http://localhost:8090/iserver/services/map-World/rest/maps/World"); map.addLayer(layer); map.zoomToMaxExtent(); // 获取要聚合的位置信息 var markers = [ {lon: 116.397128, lat: 39.916527}, {lon: 116.407128, lat: 39.926527}, {lon: 116.417128, lat: 39.936527}, // ... ]; // 将转换成Cesium的Entity对象 var entities = markers.map(function(marker) { return new Cesium.Entity({ position: Cesium.Cartesian3.fromDegrees(marker.lon, marker.lat), // 其他属性,如名称、图标等 }); }); // 创建聚合器 var cluster = new Cesium.Cluster({ pixelRange: 50, // 聚合距离 minimumClusterSize: 3, // 最小聚合数量 enabled: true, // 是否启用聚合 // 聚合的样式 clusterBillboard: new Cesium.BillboardGraphics({ image: 'img/cluster.png', horizontalOrigin: Cesium.HorizontalOrigin.CENTER, verticalOrigin: Cesium.VerticalOrigin.CENTER }) }); // 将添加到聚合器中 cluster.add(entities); // 将聚合后的添加到Cesium场景中 var viewer = new Cesium.Viewer('cesiumContainer'); viewer.scene.primitives.add(cluster.getPrimitive()); ``` 上述代码中,首先初始化了一个SuperMap地图,并获取了要聚合的位置信息。然后,将这些转换成Cesium的Entity对象,并使用Cluster绘制器将它们聚合成一个新的Entity对象。最后,将聚合后的添加到Cesium场景中显示出来。 需要注意的是,上述代码中的示例仅供参考,实际应用中需要根据具体需求进行调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

右弦GISer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值