跟牛老师一起学WEBGIS——WEBGIS实现(点聚类)

2020-12-09 11:02:01 浏览数 (1)

概述

在地图上展示的点比较多的时候,我们通常会用聚类的方式来展示。本文讲述点聚类的展示方式。点聚类的实现与绘制方式代码如下:

代码语言:javascript复制
/**
 * 在地图上聚类
 * @private
 */
ClusterLayer.prototype._showCluster2Map = function () {
    const that = this;
    const features = that._data.features;
    that._clusterData = [];
    for (let i = 0; i < features.length; i  ) {
        let clustered = false;
        const feature = features[i];
        for (let j = 0; j < that._clusterData.length; j  ) {
            const _cData = that._clusterData[j];
            if (that._clusterTest(feature, _cData.feature)) {
                that._add2ClusterData(j, feature);
                clustered = true;
                break;
            }
        }
        if (!clustered) {
            that._clusterCreate(feature);
        }
    }
    that._showResult2Map();
}
/**
 * 初始化聚类
 * @param feature
 * @private
 */
ClusterLayer.prototype._clusterCreate = function (feature) {
    this._clusterData.push({
        feature: feature,
        cluster: []
    });
}
/**
 * 展示聚类结果
 * @private
 */
ClusterLayer.prototype._showResult2Map = function () {
    const that = this;
    for (let i = 0; i < that._clusterData.length; i  ) {
        const data = that._clusterData[i];
        const pixel = that._map2pixel(data.feature.geometry.coordinates);
        const x = Math.round(pixel.x), y = Math.round(pixel.y);
        const count = data.cluster.length;
        let size = Math.ceil(that._ctx.measureText(count.toString()).width);
        size  = size % 2 === 0 ? 2 : 3;
        that._ctx.beginPath();
        if (count ===1) size = 4;
        that._ctx.arc(x, y, size / 2   4, 0, Math.PI * 2, true)
        that._ctx.fillStyle = that._convertHexToRGB('#ff0000', 0.6);
        that._ctx.fill();
        if(count > 1) {
            that._ctx.fillStyle = '#fff';
            const fontSize = 12;
            const font = '微软雅黑';
            that._ctx.font=`${fontSize}px ${font}`;
            that._ctx.fillText(count.toString(), x - size / 2, y   fontSize / 2);
        }
    }
}
/**
 * 添加聚类数据
 * @param index
 * @param data
 * @private
 */
ClusterLayer.prototype._add2ClusterData = function (index, data) {
    this._clusterData[index].cluster.push(data);
};
/**
 * 判断是否聚类
 * @param feature
 * @returns {boolean}
 * @private
 */
ClusterLayer.prototype._clusterTest = function (feature, featureCluster) {
    const that = this;
    const coords0Pixel = that._map2pixel(feature.geometry.coordinates);
    const coordsPixel = that._map2pixel(featureCluster.geometry.coordinates);
    const offX = coords0Pixel.x - coordsPixel.x;
    const offY = coords0Pixel.y - coordsPixel.y;
    const dist = Math.sqrt(offX * offX   offY * offY);
    return dist < that._params.clusterDistance;
}

上面的代码中,_clusterTest方法是聚类实现的核心,里面有一个参数clusterDistance,决定了在屏幕上聚类展示的密集程度。实现后效果如下:

0 人点赞