> 文章列表 > Openlayers(五)点位聚合Cluster

Openlayers(五)点位聚合Cluster

Openlayers(五)点位聚合Cluster

Openlayers(五)点位聚合Cluster

1.业务问题

由于点位在地图上显示过多,会造成页面卡顿、点位标注信息相互叠加导致看不清

在这里插入图片描述

优化后效果

在这里插入图片描述
不断放大层级
在这里插入图片描述

2.聚合类Cluster

OpenLayers 中聚合是通过 ol.source.Cluster 实现,聚合的原理是将距离比较近的点位合并为一个点,并计算合并后点位的属性值。

在聚合源 ol.source.Cluster 中,当一个点被添加进来时,会检查该点与已有聚合点的距离是否在指定的聚合距离之内,如果是,则将该点加入到该聚合点中,同时更新聚合点的属性值(例如点数等)。如果该点与已有聚合点的距离都超出聚合距离,则将该点作为新的聚合点,加入到聚合源中。

在渲染时,对于聚合后的点,可以根据聚合点的属性值设置不同的样式,以区别于普通的点位。

重要参数说明

let clusterPondSource = new  Cluster({distance: 100, source: new Vector()
});

distance: 聚合的距离,单位是像素

在聚合时,OpenLayers会计算每个点在屏幕上的像素位置,并根据像素位置计算聚合距离。因此,聚合距离不是以地理距离的方式计算的,而是以屏幕上的像素距离为基础。聚合距离的大小取决于地图缩放级别、地图分辨率和聚合距离参数的值。

聚合代码

在原本代码基础上,只需要把VectorLayer中数据源source替换成聚合类Cluster

import Cluster from "ol/source/Cluster"//加载前端图片地址const iconTag   = reactive({title: `/public/title.png`,pond:`/public/pond.svg`
})let clusterPondSource = new  Cluster({distance: 100, source: new Vector()
});let layerPondIcon = new VectorLayer({id: "layerPondIcon",title: 'layerPondIcon',source: clusterPondSource,zIndex: 1000,style: function (feature, resolution) {return  clusterStyle(feature,iconTag.pond,'#33C7CCFF')}
})

聚合样式

其中

let count = feature.get(“features”).length;

获取点位个数,判断当前点位如果数量大于1为聚合点,加载自定义圆。如果只有一个点位,显示我们原本点位。

function clusterStyle(feature,imgSrc,fillColor){let count = feature.get("features").length;if (count > 1) {//聚合样式return new Style({image: new Circle({ // 圆形radius: 15, // 半径stroke: new Stroke({ // 边框color: '#fff'}),fill: new Fill({ // 填充color: fillColor})}),text: new Text({fill: new Fill({//文本填充样式(即文字颜色)color: "#ffffff",}),font: "bold 14px sans-serif",text: count > 1 ? count.toString() : feature.get("features")[0].values_.name}),});} else {//默认样式return new Style({image: new Icon({src: imgSrc,}),text: new Text({textAlign: 'center',            //位置textBaseline: 'middle',         //基准线font: 'normal 13px 微软雅黑',    //文字样式offsetY: -25,    // Y轴偏置text: feature.get("features")[0].values_.name,      //文本内容fill: new Fill({       //文本填充样式(即文字颜色)color: '#FFF89A'}),stroke: new Stroke({color: '#12a2ee',width: 2})})});}
}

Select事件替换

在监听select事件的回调函数中判断当前选中的是单个点还是聚合点,如果是聚合点位,点击会放大地图层级,如果是单个点位,加载之前业务。

  let selectSingleClick = new Select({ style: null });myMap.value.addInteraction(selectSingleClick);// feature点击事件selectSingleClick.on("select", (e) => {let selectedFeatures = e.selected;if (selectedFeatures.length > 0) {let feature = selectedFeatures[0];let features = feature.get('features');if (features.length === 1) {// 单个点位// 执行之前的业务逻辑console.log('之前业务')} else {// 聚合点// 放大地图层级myMap.value.getView().animate({center: feature.getGeometry().getCoordinates(),zoom: myMap.value.getView().getZoom() + 1});}}