首页 > 其他分享 >Openlayers中使用Cluster实现点位元素重合时动态聚合与取消聚合

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

时间:2023-03-24 15:38:09浏览次数:35  
标签:carNumber style ol 聚合 Cluster Openlayers 霸道 var new


场景

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

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

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

Openlayers中使用Cluster实现点位元素重合时动态聚合与取消聚合_公众号

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

Openlayers中使用Cluster实现点位元素重合时动态聚合与取消聚合_图层_02

注:

博客:BADAO_LIUMANG_QIZHI的博客_霸道流氓气质_-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的博客-_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>

标签:carNumber,style,ol,聚合,Cluster,Openlayers,霸道,var,new
From: https://blog.51cto.com/BADAOLIUMANGQZ/6147327

相关文章

  • Jmeter Aggregate report(聚合报告)
     本文主要介绍了聚合报告的一些参数信息。Jmeter的Aggregatereport(聚合报告)比较重要的参数报告的保存文件格式为jtl。timestamp:请求发出的绝对时间elapsed:响应时间......
  • OpenLayers change 事件获取当前值
    这里有个change:resolution事件但是事件的内容没有value,只有oldValueZc {type:'change:resolution',target:F,key:'resolution',oldValue:9786.603971778399......
  • CentOS7.9快速配置服务器网卡聚合双bond方法
    说明:服务器双口,分别为em1-2个口em1、em21、 开启 NetworkManagersystemctlstart NetworkManageryuminstallbridge-utils 2、备份配置文件mkdir-p /data/b......
  • SQL之聚合函数
    1、countselectcount(*)fromstudent;2、maxselectmax(age)fromstudent;3、minselectsname,min(age)fromstudent;4、sumselectsum(age)fromstude......
  • Predixy 代理 Redis Cluster 集群
    1、环境服务器名称IP地址备注predixy-161-13010.32.161.130Predixyredis-161-13110.32.161.131redis节点redis-161-13210.32.161.132redis节点red......
  • Twemproxy(nutcracker)代理 Redis Cluster 集群
    1、环境服务名称IP地址备注twemproxy-161-13010.32.161.130twemproxy(nutcracker)redis-161-13110.32.161.131redis节点redis-161-13210.32.161.132......
  • Vue+Openlayers实现绘制线段并测量距离显示
    场景在上面已经实现交互式绘制线段基础上,怎样实现测量距离。注:关注公众号霸道的程序猿获取编程相关电子书、教程推送与免费下载。实现1、页面上添加按钮与map<template>......
  • linq实现聚合分组
    List<ChemicalInventory>listInventory=new List<ChemicalInventory>();                    foreach (varitemin response.EX_TAB)   ......
  • Dubbo——集群(Cluster)容错原理
    摘要集群中的单个节点有一定概率出现一些问题,例如,磁盘损坏、系统崩溃等,导致节点无法对外提供服务,因此在分布式RPC框架中,必须要重视这种情况。为了避免单点故障,我们的Prov......
  • Maven聚合工程
    Maven聚合工程Maven聚合工程概念概述:Maven聚合工程:就是可以在一个Maven父工程中创建多个组件,这个多个组件之间可以相互依赖,实现组件的复用创建Maven聚合工程2.1创......