在使用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)来控制图标是否需要聚合