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
        });
      }
    }
  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现在 Vue 中使用 OpenLayers 实现聚合点位击事件,可以按照以下步骤进行: 1. 在 Vue 中安装 OpenLayers:可以使用命令 `npm install ol` 安装 OpenLayers。 2. 在 Vue 中创建地图容器:可以在 Vue 的 `template` 中创建一个 `div` 容器作为地图容器。 3. 在 Vue 中使用 OpenLayers 创建地图:可以在 Vue 的 `methods` 中创建一个函数,使用 OpenLayers 创建地图。 4. 在地图中添加聚合点位图层:在创建地图的过程中,可以添加一个聚合点位图层。 5. 监听聚合点位图层的击事件:可以在创建地图的过程中,使用 OpenLayers 提供的 `on` 方法监听聚合点位图层的击事件。 6. 在击事件中获取聚合点位的信息:在监听到聚合点位图层的击事件后,可以获取聚合点位的信息并进行相应处理。 以下是一个基本的 Vue 组件代码示例,用于实现 OpenLayers聚合点位击事件: ```html <template> <div id="map"></div> </template> <script> import 'ol/ol.css'; import { Map, View } from 'ol'; import { fromLonLat } from 'ol/proj'; import { Cluster, OSM, Vector } from 'ol/source'; import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'; import Feature from 'ol/Feature'; import Point from 'ol/geom/Point'; export default { name: 'Map', mounted() { this.initMap(); }, methods: { initMap() { const source = new Cluster({ distance: 40, source: new Vector({ url: 'data/kml/2012_Earthquakes_Mag5.kml', format: new KML({ extractStyles: false, }), }), }); const clusterLayer = new VectorLayer({ source: source, }); const map = new Map({ target: 'map', layers: [ new TileLayer({ source: new OSM(), }), clusterLayer, ], view: new View({ center: fromLonLat([-117.1497, 32.6965]), zoom: 12, }), }); clusterLayer.getSource().on('addfeature', function (event) { const cluster = event.feature; if (cluster.get('features').length > 1) { const coordinates = cluster.getGeometry().getCoordinates(); const feature = new Feature(new Point(coordinates)); feature.set('cluster', cluster); source.addFeature(feature); } }); clusterLayer.getSource().on('click', function (event) { const feature = map.forEachFeatureAtPixel(event.pixel, function (feature) { return feature; }); if (feature && feature.get('cluster')) { const cluster = feature.get('cluster'); const features = cluster.get('features'); const coordinate = cluster.getGeometry().getCoordinates(); console.log(features); console.log(coordinate); } }); }, }, }; </script> <style> #map { height: 400px; } </style> ``` 在上述代码示例中,我们使用 OpenLayers 创建了一个聚合点位图层,并在地图中添加了该图层。然后,我们使用 `on` 方法来监听聚合点位图层的击事件,并在击事件中获取聚合点位的信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值