vue中openlayer聚合图层实现指定图标脱离聚合效果

                在使用openlayer的cluster实现聚合效果的时候. 发现图标无法自由控制是否聚合,  定位到指定图标时,无法让图标显示出来。 阅读了cluster类的源码之后 发现可以进行扩展, 直接上代码

ol源码中控制聚合的方法实现如下

    Cluster.prototype.cluster = function () {
        if (this.resolution === undefined || !this.source) {
            return;
        }
        var extent = createEmpty();
        var mapDistance = this.distance * this.resolution;
        var features = this.source.getFeatures();
        /**
         * @type {!Object<string, boolean>}
         */
        var clustered = {};
        for (var i = 0, ii = features.length; i < ii; i++) {
            var feature = features[i];


            if (!(getUid(feature) in clustered)) {
                var geometry = this.geometryFunction(feature);
                if (geometry) {

                    //根据分辨率和指定的聚合距离计算一个feature的聚合范围坐标

                    var coordinates = geometry.getCoordinates();
                    createOrUpdateFromCoordinate(coordinates, extent);
                    buffer(extent, mapDistance, extent);
                    
                    //获取范围内的所有feature

                    var neighbors = this.source.getFeaturesInExtent(extent);

                    //过滤掉已被聚合的feature
                    neighbors = neighbors.filter(function (neighbor) {
                        var uid = getUid(neighbor);
                        if (!(uid in clustered)) {
                            clustered[uid] = true;
                            return true;
                        }
                        else {
                            return false;
                        }
                    });
                    this.features.push(this.createCluster(neighbors));
                }
            }
        }
    };

 重写cluster,实现自己的聚合逻辑

    cluster() {
        if (this.resolution === undefined || !this.source) {
            return;
        }
        const extent      = createEmpty();
        const mapDistance = this.distance * this.resolution;
        const features    = this.source.getFeatures();
        const clustered   = {};

        for (let i = 0, ii = features.length; i < ii; i++) {
            const feature = features[i];
            if (!(getUid(feature) in clustered)) {
                const geometry = this.geometryFunction(feature);
                if (geometry) {
                     // 通过isolated判断feature是否需要脱离聚合   
                    if (feature.get("isolated")) {
                        let cluster = new Feature(new Point(geometry.getCoordinates()));
                        cluster.set('features', [feature]);
                        const uid      = getUid(feature);
                        clustered[uid] = true;
                        this.features.push(cluster);

                    } else {
                        const coordinates = geometry.getCoordinates();
                        createOrUpdateFromCoordinate(coordinates, extent);
                        buffer(extent, mapDistance, extent);

                        let neighbors = this.source.getFeaturesInExtent(extent);
                        neighbors     = neighbors.filter(function (neighbor) {
                            const uid = getUid(neighbor);
                            if (neighbor.get("isolated") || uid in clustered) {
                                return false;
                            } else {
                                clustered[uid] = true;
                                return true;
                            }
                        });
                        this.features.push(this.createCluster(neighbors));
                    }
                }
            }
        }
    }

所有代码

/**
 * 扩展cluster类
 * */
import { Cluster } from 'ol/source'
import { buffer, createEmpty, createOrUpdateFromCoordinate } from "ol/extent";
import { getUid } from "ol/util";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";

class CustomCluster extends Cluster {

    // eslint-disable-next-line no-useless-constructor
    constructor(options) {
        super(options);
    }

    /**
     * 重写聚合方法,若图标不需要聚合则单独拎出
     * */
    cluster() {
        if (this.resolution === undefined || !this.source) {
            return;
        }
        const extent      = createEmpty();
        const mapDistance = this.distance * this.resolution;
        const features    = this.source.getFeatures();
        const clustered   = {};

        for (let i = 0, ii = features.length; i < ii; i++) {
            const feature = features[i];
            if (!(getUid(feature) in clustered)) {
                const geometry = this.geometryFunction(feature);
                if (geometry) {
                    if (feature.get("isolated")) {
                        let cluster = new Feature(new Point(geometry.getCoordinates()));
                        cluster.set('features', [feature]);
                        const uid      = getUid(feature);
                        clustered[uid] = true;
                        this.features.push(cluster);

                    } else {
                        const coordinates = geometry.getCoordinates();
                        createOrUpdateFromCoordinate(coordinates, extent);
                        buffer(extent, mapDistance, extent);

                        let neighbors = this.source.getFeaturesInExtent(extent);
                        neighbors     = neighbors.filter(function (neighbor) {
                            const uid = getUid(neighbor);
                            if (neighbor.get("isolated") || uid in clustered) {
                                return false;
                            } else {
                                clustered[uid] = true;
                                return true;
                            }
                        });
                        this.features.push(this.createCluster(neighbors));
                    }
                }
            }
        }
    }
}

export default CustomCluster;

使用时只需要把 ol.source.Cluster换成CustomCluster就行啦,然后通过feature.set("isolated",true) 或者feature.set("isolated",false)来控制图标是否需要聚合

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值