CESIUM例子学习(十四)——Clustering

Clustering,聚合功能,单从一个例子来看,似乎没有什么作用。但是在GIS项目中是应用得比较多的功能点,当一 个区域很小,但需要显示的标注又非常多时,它就派上用场了。在C/S系统中,往往使用zoom与visible绑定来解决压盖问题,但并不能很好地解决,体验也不是很好,好久没用C/S系统了,不知道有没有平台把聚合功能整合进去。Clustering完美地解决了这个问题,再也不用担心加载的点太多而看不清楚的问题了。

一、KML数据加载

代码中是以加载KML数据为例的。首先是用KmlDataSource加载KML数据,代码如下:

function addDataSources () {
    var options = {
         camera: viewer.scene.camera,
         canvas: viewer.scene.canvas,
         clampToGround: false
    };
    var dataSourcePromise = viewer.dataSources.add(
        Cesium.KmlDataSource.load(
            "../Cesium1_71/Apps/SampleData/kml/facilities/facilities.kml",
            options
        )
    );
    dataSourcePromise.then(function (dataSource) {
        afterAddDataSource(dataSource)
    })
}

二、EntityCluster属性设置

在数据加载完成后,设置聚合功能和样式,而聚合的实现,主要有三个步骤:(1)设置数据启用聚合图标功能,并设置聚合距离;(2)首先创建设置聚合图标来渲染显示加载的数据;(3)聚合是实时更新的,所以需要一个绑定事件,把渲染的设置告诉给cesium。

1、设置启用聚合

KmlDataSource中的clustering属性是EntityCluster类型,下面代码设置启用聚合功能

    dataSource.clustering.enabled = enabled;
    dataSource.clustering.pixelRange = pixelRange;
    dataSource.clustering.minimumClusterSize = minimumClusterSize;

代码中pixelRange是聚合距离,也就是小于这个距离就会被聚合,以像素为单位;minimumClusterSize是每个聚合点的最小聚合个数,这个值最好是设置为2,因为两个图标也可能叠压。

2、创建设置聚合图标

聚合图标由PinBuilder创建的,PinBuilder内置了很多图标。如下图:

CESIUM例子学习(十四)——Clustering_第1张图片

可以通过多种方法获取这些图标,也可以通过fromUrl()方法使用自定义图标。事例代码中使用的是fromText()方法创建。

3、事件绑定

在通过clustering属性中的clusterEvent.addEventListener方法绑定渲染回调函数,即:Cesium.EntityCluster.newClusterCallback(clusteredEntities, cluster),其中clusteredEntities参数表示的是聚合Entities数据集;而cluster是一个包含了billboard、label、和point 属性的对象。

至此,EntityCluster属性设置完成,设置部份的代码如下:

var removeListener
function afterAddDataSource (dataSource) {
    var pixelRange = 59;
    var minimumClusterSize = 2;
    var enabled = true;

    dataSource.clustering.enabled = enabled;
    dataSource.clustering.pixelRange = pixelRange;
    dataSource.clustering.minimumClusterSize = minimumClusterSize;

    var pinBuilder = new Cesium.PinBuilder();
    var pin100 = pinBuilder
        .fromText("100+", Cesium.Color.RED, 48)
        .toDataURL();
    var pin50 = pinBuilder
        .fromText("50+", Cesium.Color.RED, 48)
        .toDataURL();
    var pin40 = pinBuilder
        .fromText("40+", Cesium.Color.ORANGE, 48)
        .toDataURL();
    var pin30 = pinBuilder
        .fromText("30+", Cesium.Color.YELLOW, 48)
        .toDataURL();
    var pin20 = pinBuilder
        .fromText("20+", Cesium.Color.GREEN, 48)
        .toDataURL();
    var pin10 = pinBuilder
        .fromText("10+", Cesium.Color.BLUE, 48)
        .toDataURL();
    var singleDigitPins = new Array(8);
    for (var i = 0; i < singleDigitPins.length; ++i) {
        singleDigitPins[i] = pinBuilder
            .fromText("" + (i + 2), Cesium.Color.VIOLET, 48)
            .toDataURL();
    }
    customStyle();
    function customStyle () {
        if (Cesium.defined(removeListener)) {
            removeListener();
            removeListener = undefined;
        } else {
            removeListener = dataSource.clustering.clusterEvent.addEventListener(
                function (clusteredEntities, cluster) {
                    cluster.label.show = false;
                    cluster.billboard.show = true;
                    cluster.billboard.id = cluster.label.id;
                    cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
                    if (clusteredEntities.length >= 100) {
                        cluster.billboard.image = pin100;
                    } else if (clusteredEntities.length >= 50) {
                        cluster.billboard.image = pin50;
                    } else if (clusteredEntities.length >= 40) {
                        cluster.billboard.image = pin40;
                    } else if (clusteredEntities.length >= 30) {
                        cluster.billboard.image = pin30;
                    } else if (clusteredEntities.length >= 20) {
                        cluster.billboard.image = pin20;
                    } else if (clusteredEntities.length >= 10) {
                        cluster.billboard.image = pin10;
                    } else {
                        cluster.billboard.image =
                            singleDigitPins[clusteredEntities.length - 2];
                    }
                }
            );
        }
        // force a re-cluster with the new styling
        var pixelRange = dataSource.clustering.pixelRange;
        dataSource.clustering.pixelRange = 0;
        dataSource.clustering.pixelRange = pixelRange;
    }
}

 

你可能感兴趣的:(cesium,Clustering,PinBuilder)