场景

Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合:

Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合_BADAO_LIUMANG_QIZHI的博客-CSDN博客

上面实现缩放地图时元素在指定距离内实现聚合效果。

实际场景中点位是变化的,不是静态的点位,当多个点位在动态更新的过程中如果出现了重合则自动实现聚合效果

注:

博客:
BADAO_LIUMANG_QIZHI的博客_霸道流氓气质_CSDN博客-C#,SpringBoot,架构之路领域博主
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

1、首先模拟多个点位坐标的数据,实际场景可能是从后台或其他地方获取点位信息

        //定位数据源var positionData = [[{x: '-11561139.941628069',y: '5538515.7834814',carNumber: '霸道的程序猿'},{x: '-11552039.941628069',y: '5531515.7834814',carNumber: '公众号'}],[{x: '-11560039.941628069',y: '5537515.7834814',carNumber: '霸道的程序猿'},{x: '-11553039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11559039.941628069',y: '5536515.7834814',carNumber: '霸道的程序猿'},{x: '-11554039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11558039.941628069',y: '5535515.7834814',carNumber: '霸道的程序猿'},{x: '-11557039.941628069',y: '5534515.7834814',carNumber: '公众号'}],[{x: '-11557039.941628069',y: '5534515.7834814',carNumber: '霸道的程序猿'},{x: '-11556039.941628069',y: '5535515.7834814',carNumber: '公众号'}],[{x: '-11556039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11557039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11555039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11558039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11554039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11559039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11553039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11560039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11552039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11561039.941628069',y: '5536515.7834814',carNumber: '公众号'}]];

这里模拟两组坐标的点位数据,会在中间某个时刻有距离特别相近的点位。

2、创建聚合图层要素

        // 创建聚合图层要素var clusterSource = new ol.source.Vector();

3、新建聚合图层数据源

        // 聚合图层数据源var clusterSourceForLayer = new ol.source.Cluster({source: clusterSource,distance: 50})

这里的distance就是指的聚合的距离。

实际上就是将原来的普通的new ol.source.Vector图层数据源更换为ol.source.Cluster

4、新建聚合图层

        var clusterLayer = new ol.layer.Vector({source: clusterSourceForLayer,style: function (feature, resolution) {var size = feature.get('features').length;if (size == 1) {return new ol.style.Style({image: new ol.style.Icon({scale: 0.8,src: './icon/house.png',anchor: [0.48, 0.52]}),text: new ol.style.Text({font: 'normal 12px 黑体',// // 对其方式textAlign: 'center',// 基准线textBaseline: 'middle',offsetY: -35,offsetX: 0,backgroundFill: new ol.style.Stroke({color: 'rgba(0,0,255,0.7)',}),// 文本填充样式fill: new ol.style.Fill({color: 'rgba(236,218,20,1)'}),padding: [5, 5, 5, 5],text: `霸道的程序猿`,})});} else {return new ol.style.Style({image: new ol.style.Circle({radius: 30,stroke: new ol.style.Stroke({color: 'white'}),fill: new ol.style.Fill({color: 'blue'})}),text: new ol.style.Text({text: size.toString(),fill: new ol.style.Fill({color: 'white'})})});}}});

实际上实现聚合与不聚合效果的关键代码就是这部分的style改为函数并且根据条件动态返回。

如果包含多个元素,则返回聚合的style效果,否则就是返回普通的style效果。

5、map上添加图层

        var map = new ol.Map({layers: [layer],target: 'map',view: view});this.map.addLayer(this.clusterLayer);

其中layer是地图图层。

然后新建一个定时器模拟定时获取点位数据

        //定时器循环模拟后台获取数据实现定位效果var index = 0;setInterval(() => {//坐标数据到头了 就重新开始if (index > this.positionData.length - 2) {index = 0;}//根据索引获取数据var item = this.positionData[index];//清除上次的数据源if (this.positonSource) {this.positonSource.clear();}if (item) {clusterSource.clear();for (var i = 0; i < item.length; ++i) {var feature = new ol.Feature({geometry: new ol.geom.Point([Number(item[i].x), Number(item[i].y)])})//数据源添加要素clusterSource.addFeature(feature);}}   //移到下个点index++;}, 1000);

在定时器中将聚合图层的数据源先清理,然后再将坐标要素添加进聚合图层数据源中。

其他相关代码就是离线加载地图显示的功能,可以参考

Openlayers中实现地图上打点并显示图标和文字:

Openlayers中实现地图上打点并显示图标和文字_BADAO_LIUMANG_QIZHI的博客-CSDN博客_openlayers 打点

6、完整示例代码

<!doctype html>
<html lang="en"><head><meta charset="UTF-8"><title>缩放地图实现聚合与取消聚合-动态</title><link rel="stylesheet" href="lib/ol65/ol.css" type="text/css"><style>html,body,#map {padding: 0;margin: 0;width: 100%;height: 100%;overflow: hidden;}</style>
</head><body><div id="map"></div><script type="text/javascript" src="lib/ol65/ol.js"></script><script type="text/javascript">//定位数据源var positionData = [[{x: '-11561139.941628069',y: '5538515.7834814',carNumber: '霸道的程序猿'},{x: '-11552039.941628069',y: '5531515.7834814',carNumber: '公众号'}],[{x: '-11560039.941628069',y: '5537515.7834814',carNumber: '霸道的程序猿'},{x: '-11553039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11559039.941628069',y: '5536515.7834814',carNumber: '霸道的程序猿'},{x: '-11554039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11558039.941628069',y: '5535515.7834814',carNumber: '霸道的程序猿'},{x: '-11557039.941628069',y: '5534515.7834814',carNumber: '公众号'}],[{x: '-11557039.941628069',y: '5534515.7834814',carNumber: '霸道的程序猿'},{x: '-11556039.941628069',y: '5535515.7834814',carNumber: '公众号'}],[{x: '-11556039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11557039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11555039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11558039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11554039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11559039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11553039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11560039.941628069',y: '5536515.7834814',carNumber: '公众号'}],[{x: '-11552039.941628069',y: '5533515.7834814',carNumber: '霸道的程序猿'},{x: '-11561039.941628069',y: '5536515.7834814',carNumber: '公众号'}]];var source = new ol.source.XYZ({tileUrlFunction: function (xyz, obj1, obj2) {if (!xyz)return "";var z = xyz[0];var x = Math.abs(xyz[1]);var y = Math.abs(xyz[2]);var xyz_convert = self.convert_(z, x, y);x = xyz_convert[0];y = xyz_convert[1];z = xyz_convert[2];var shift = z / 2;var half = 2 << shift;var digits = 1;if (half > 10)digits = parseInt(Math.log(half) / Math.log(10)) + 1;var halfx = parseInt(x / half);var halfy = parseInt(y / half);x = parseInt(x);y = parseInt(y) - 1;var url = "./images/EPSG_900913" + "_" + self.padLeft_(2, z) + "/" + self.padLeft_(digits,halfx) + "_" + self.padLeft_(digits, halfy) + "/" + self.padLeft_(2 * digits, x) +"_" + self.padLeft_(2 * digits, y) + "." + 'png';return url;}});//projections投影坐标系转换相关的操作var projection = new ol.proj.Projection({code: 'EPSG:900913',units: 'm',axisOrientation: 'neu'});//Layers 图层管理类,用来管理图层信息。主要包括Tile,Image,Vector,VectorTile等图层。var layer = new ol.layer.Tile({source: source});// 创建聚合图层要素var clusterSource = new ol.source.Vector();// 聚合图层数据源var clusterSourceForLayer = new ol.source.Cluster({source: clusterSource,distance: 50})// 聚合图层var clusterLayer = new ol.layer.Vector({source: clusterSourceForLayer,style: function (feature, resolution) {var size = feature.get('features').length;if (size == 1) {return new ol.style.Style({image: new ol.style.Icon({scale: 0.8,src: './icon/house.png',anchor: [0.48, 0.52]}),text: new ol.style.Text({font: 'normal 12px 黑体',// // 对其方式textAlign: 'center',// 基准线textBaseline: 'middle',offsetY: -35,offsetX: 0,backgroundFill: new ol.style.Stroke({color: 'rgba(0,0,255,0.7)',}),// 文本填充样式fill: new ol.style.Fill({color: 'rgba(236,218,20,1)'}),padding: [5, 5, 5, 5],text: `霸道的程序猿`,})});} else {return new ol.style.Style({image: new ol.style.Circle({radius: 30,stroke: new ol.style.Stroke({color: 'white'}),fill: new ol.style.Fill({color: 'blue'})}),text: new ol.style.Text({text: size.toString(),fill: new ol.style.Fill({color: 'white'})})});}}});//View 视图管理器,主要用来管理地图视图,分辨率或旋转,中心、投影、分辨率、缩放级别等。var view = new ol.View({//中心点center: [-11549894, 5533433],//缩放等级zoom: 11,//投影坐标系projection: projection,//边界extent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34]});//Map Openlayers的核心组件,包含图层、交互事件、UI控制元素等。var map = new ol.Map({layers: [layer],target: 'map',view: view});this.map.addLayer(this.clusterLayer);//定时器循环模拟后台获取数据实现定位效果var index = 0;setInterval(() => {//坐标数据到头了 就重新开始if (index > this.positionData.length - 2) {index = 0;}//根据索引获取数据var item = this.positionData[index];//清除上次的数据源if (this.positonSource) {this.positonSource.clear();}if (item) {clusterSource.clear();for (var i = 0; i < item.length; ++i) {var feature = new ol.Feature({geometry: new ol.geom.Point([Number(item[i].x), Number(item[i].y)])})//数据源添加要素clusterSource.addFeature(feature);}}   //移到下个点index++;}, 1000);//xy行列转换function convert_(zoomLevel, x, y) {var extent = Math.pow(2, zoomLevel);if (x < 0 || x > extent - 1) {console.log("The X coordinate is not sane: " + x);return;}if (y < 0 || y > extent - 1) {console.log("The Y coordinate is not sane: " + y);return;}// openlayers 6.0版本var gridLoc = [x, extent - y, zoomLevel];// openlayers 4.5版本// var gridLoc = [x, extent - y + 1, zoomLevel];return gridLoc;}//字符截取function padLeft_(num, val) {return (new Array(num).join('0') + val).slice(-num);}</script>
</body></html>

Openlayers中使用Cluster实现点位元素重合时动态聚合与取消聚合相关推荐

  1. Openlayers中使用Cluster+Overlay实现点击单个要素和聚合要素时显示不同弹窗

    场景 Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合: Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合_BADAO_LIUMANG_QIZHI的博客 ...

  2. Openlayers中使用Cluster实现缩放地图时图层聚合与取消聚合

    场景 Openlayers中实现地图上打点并显示图标和文字: Openlayers中实现地图上打点并显示图标和文字_BADAO_LIUMANG_QIZHI的博客-CSDN博客_openlayers 打 ...

  3. Openlayers中使用Overlay实现点击要素显示html内容弹窗并且动态更改弹窗内容

    场景 Openlayers中使用Overlay实现点击要素弹窗并且弹窗随之移动: Openlayers中使用Overlay实现点击要素弹窗并且弹窗随之移动_BADAO_LIUMANG_QIZHI的博客 ...

  4. Openlayers中使用Overlay实现点击要素弹窗并且弹窗随之移动

    场景 Vue+Openlayer使用overlay实现弹窗弹出显示与关闭: Vue+Openlayer使用overlay实现弹窗弹出显示与关闭_BADAO_LIUMANG_QIZHI的博客-CSDN博 ...

  5. Openlayers中使用Image的rotation实现车辆定位导航带转角(判断车辆图片旋转角度)

    场景 Openlayers中使用animate实现车辆定位导航效果(以当前车辆为中心移动): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/det ...

  6. Openlayers中使用animate实现车辆定位导航效果(以当前车辆为中心移动)

    场景 Openlayers中加载Geoserver切割的EPSG:900913离线瓦片地图并显示: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/ ...

  7. Openlayers中多图层遮挡时调整图层上下顺序

    场景 Openlayers中加载Geoserver切割的EPSG:900913离线瓦片地图并显示: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/ ...

  8. Openlayers中实现地图上添加一条红色直线

    场景 Openlayers中加载Geoserver切割的EPSG:900913离线瓦片地图并显示: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/ ...

  9. 如何在openlayers中使用iconfont或font Awesome字体图标

    目录 前言 1.准备工作 2.新建一个最简单的helloworld页面 3.看看效果 4.注意点1-需使用Unicode写法 4.注意点2-需注意iconfott.woff2的请求顺序 5.特殊图标的 ...

最新文章

  1. snowflake mysql_snowflake数据库
  2. 视频分割--Learning to Segment Instances in Videos with Spatial Propagation Network
  3. 计算机导论第一章试题及答案,计算机导论第一章测试题
  4. SQL SERVER SQLOS的任务调度--微软亚太区数据库技术支持组 官方博客
  5. openEuler系统配置yum镜像源
  6. Mybatis实现物理分页
  7. MySQL数据库自动添加时间戳
  8. android学习笔记17——对话框(PopupWindow)
  9. Java 集合-集合介绍
  10. 阻止事件冒泡——商品编辑
  11. API – MultiByteToWideChar的用法
  12. 一眼中毒!雷军晒小米9官方高清真机图:全息幻彩惊艳无比
  13. 数据创建表 修改列 新增列
  14. element-UI:el-table 表格排序
  15. 微信小程序入门 ——增删改查+页面跳转+传值取值+布局样式
  16. 统计过程控制图SPC(2)
  17. IDEA新手使用教程(详解)
  18. IDEA 2020 返回上一步快捷键
  19. 织梦dedecms蓝色商务学院职业技术学校网站模板
  20. 微信公众号--授权相关

热门文章

  1. CanalAdapter启动过程分析(源码详解)
  2. java中dateformat类的作用_java-SimpleDateFormat类中可用的日期格式是什么?
  3. 文件服务器文件多备份方案,windows文件服务器冗余备份方案.doc
  4. html主题居中用什么命令,html – 如何居中的元素 – 使用什么而不是align:center属性?...
  5. tarjan算法_【朝夕的ACM笔记】树上问题-最近公共祖先-倍增算法
  6. access 导入 txt sql语句_从零开始学习 MySQL 系列索引、视图、导入和导出
  7. 银河麒麟v10更新异常问题
  8. 计算机硬件价钱分配,电脑基础知识计算机硬件基础课件.ppt
  9. yum php devel_yum源里找不到 php54w-devel,求可用yum源
  10. 华为手机怎么看图片属性_华为手机音量小怎么办