我的编程空间,编程开发者的网络收藏夹
学习永远不晚

OpenLayers实现点要素图层的聚合显示的方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

OpenLayers实现点要素图层的聚合显示的方法

1、前言

在很多情况下,点要素图层中的要素数量可能会成百上千,这时候如果不做任何处理直接加载到地图上不仅会使用户视觉体验下降,而且也会造成地图界面的卡顿。下面这段代码创建了1000个随机点进行显示:


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script class="lazy" data-src="libs/ol/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 随机创建1000个要素
        var source = new ol.source.Vector();
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }

        // 创建图层
        var layer = new ol.layer.Vector({
            source: source,
            style: function (feature, resolution) {
                var style = new ol.style.Style({
                    image: new ol.style.Icon({
                        class="lazy" data-src: 'img/location.png'
                    })
                })
                return style;
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 10,
                minZoom: 5,
                maxZoom: 14
            })
        });
    </script>
</body>
</html>

运行结果如下图所示:

在这里插入图片描述

这么多点挤在一起,是不是感觉很恶心?一般来说,如果一个点要素图层中的点数量很多,我们就会采取图层聚合的方式对其进行处理。但需要注意:图层聚合只对点要素图层有效,对线和面图层无效

2、点要素图层的聚合

openlayers中,图层聚合的一般步骤如下:

  • 创建要素
  • 创建数据源添加要素
  • 创建聚合数据源,设置聚合的距离
  • 创建图层,将数据源设置为聚合数据源
  • 创建地图,添加聚合图层

图层聚合代码如下:


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script class="lazy" data-src="libs/ol/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 随机创建1000个要素
        var source = new ol.source.Vector();
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }

        // 聚合
        var cluster = new ol.source.Cluster({
            source: source,
            distance: 100
        })

        // 创建图层
        var layer = new ol.layer.Vector({
            source: cluster,
            style: function (feature, resolution) {
                var size = feature.get('features').length;
                var style = 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'
                        })
                    })
                })
                return style;
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 10,
                minZoom: 5,
                maxZoom: 14
            })
        });
    </script>
</body>
</html>

运行结果如下图所示:

在这里插入图片描述

3、聚合特殊处理一

上面的代码虽然实现了点要素图层的聚合,但其实存在着一个问题:地图缩放层级最大时仍然保持着聚合效果,如下图所示:

在这里插入图片描述

一般来说,当某处只有一个点时就应该取消聚合效果,这时候我们就需要在style: function (feature, resolution)这个回调函数里做文章了,代码如下:


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script class="lazy" data-src="libs/ol/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 随机创建1000个要素
        var source = new ol.source.Vector();
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }

        // 聚合
        var cluster = new ol.source.Cluster({
            source: source,
            distance: 100
        })

        // 创建图层
        var layer = new ol.layer.Vector({
            source: cluster,
            style: function (feature, resolution) {
                var size = feature.get('features').length;
                if (size == 1) {
                    return new ol.style.Style({
                        image: new ol.style.Icon({
                            class="lazy" data-src: 'img/location.png'
                        })
                    })
                }
                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'
                            })
                        })
                    })
                }
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 10,
                minZoom: 5,
                maxZoom: 14
            })
        });
    </script>
</body>
</html>

运行结果如下图所示:

在这里插入图片描述

其实这个效果实现起来很简单,核心代码就是:var size = feature.get('features').length;,如果size>1,则返回聚合样式,反之则返回图片样式。

4、聚合特殊处理二

在上面的代码中,我把地图的最大缩放层级设置为14,这也就导致了一个问题:当地图缩放到最大层级时,还有很多点保持着聚合效果。有时候用户可能会要求:当地图缩放到最大层级时,取消全部聚合效果。如果要实现这个功能,我们就需要对地图事件进行监听了,代码如下:


<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta charset="utf-8" />
    <title>OpenLayers</title>
    <style>
        html, body, #map {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <link href="libs/ol/ol.css" rel="stylesheet" />
    <script class="lazy" data-src="libs/ol/ol.js"></script>
</head>
<body>
    <div id="map"></div>

    <script>
        // 随机创建1000个要素
        var source = new ol.source.Vector();
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.00 + Math.random(), 30.00 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.01 + Math.random(), 30.01 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.02 + Math.random(), 30.02 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.03 + Math.random(), 30.03 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }
        for (var i = 1; i <= 200; i++) {
            var coordinates = [120.04 + Math.random(), 30.04 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            source.addFeature(feature);
        }

        // 聚合
        var cluster = new ol.source.Cluster({
            source: source,
            distance: 100
        })

        // 创建图层
        var layer = new ol.layer.Vector({
            source: cluster,
            style: function (feature, resolution) {
                var size = feature.get('features').length;
                if (size == 1) {
                    return new ol.style.Style({
                        image: new ol.style.Icon({
                            class="lazy" data-src: 'img/location.png'
                        })
                    })
                }
                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'
                            })
                        })
                    })
                }
            }
        });

        // 创建地图
        var map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                }),
                layer
            ],
            view: new ol.View({
                projection: 'EPSG:4326',
                center: [120, 30],
                zoom: 10,
                minZoom: 5,
                maxZoom: 14
            })
        });

        // 监听地图分辨率改变事件
        map.getView().on('change:resolution', function (event) {
            if (map.getView().getZoom() == map.getView().getMaxZoom()) {
                cluster.setDistance(0);
            }
            else {
                cluster.setDistance(100);
            }
        })
    </script>
</body>
</html>

运行结果如下图所示:

在这里插入图片描述

这个效果的实现也很简单,只需要监听当前地图的分辨率变化事件,如果当前缩放层级已经是最大层级,则将聚合的距离设置为0即可。

5.、结语

在要素数量很多的情况下,我们应该考虑对其进行聚合处理,这样不仅提升了用户的使用感受,而且也可以避免界面卡顿。其实在上面的代码中,我对change:resolution事件进行了监听,你也可以换成另一个事件——moveend,代码如下所示:


map.on('moveend', function (event) {
    if (map.getView().getZoom() == map.getView().getMaxZoom()) {
        cluster.setDistance(0);
    }
    else {
        cluster.setDistance(100);
    }
});

moveend事件进行监听也可以实现相同的效果,因为无论是地图的缩放、平移都会触发该事件。

到此这篇关于OpenLayers实现点要素图层的聚合显示的方法的文章就介绍到这了,更多相关OpenLayers 点要素图层的聚合显示内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

OpenLayers实现点要素图层的聚合显示的方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

JavaScript实现显示和隐藏图片的方法

这篇文章给大家分享的是有关JavaScript实现显示和隐藏图片的方法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。JavaScript是什么JavaScript是一种直译式的脚本语言,其解释器被称为JavaSc
2023-06-14

Android实现TextView显示HTML加图片的方法

本文实例讲述了Android实现TextView显示HTML加图片的方法。分享给大家供大家参考,具体如下: TextView显示网络图片,我用android2.3的系统,可以显示图片出来,并且如果图片比较大,应用会卡的现象,肯定是因为使用主
2022-06-06

Android中TextView显示插入的图片实现方法

本文实例讲述了Android中TextView显示插入的图片实现方法。分享给大家供大家参考,具体如下: Android系统默认给TextView插入图片提供了三种方式: 1、ImageSpan 2、Html.ImageGetter 3、Te
2022-06-06

iOS开发中实现显示gif图片的方法

我们知道Gif是由一阵阵画面组成的,而且每一帧画面播放的时常可能会不相等,观察上面两个例子,发现他们都没有对Gif中每一帧的显示时常做处理,这样的结果就是整个Gif中每一帧画面都是以固定的速度向前播放,很显然这并不总会符合需求。 于是自己
2022-05-19

Android编程实现大图滚动显示的方法

本文实例讲述了Android编程实现大图滚动显示的方法。分享给大家供大家参考,具体如下: 问题: 我有一张比较大的图片,比如长宽都是屏幕的两倍大小,我想实现的功能是首先将图片居中显示,由于图片太大显然只能显示一部分,然后可以通过拖动,实现图
2022-06-06

Android 网络图片查看显示的实现方法

我们的应用或多或少都会从网络获取图片数据然后进行显示,下面就将实现一个这样的例子,获取网络中的图片! 首先:我们来看一下效果图界面中有三个控件,一个EditText,一个Button,一个ImageView 1、下面是具体布局文件
2022-06-06

Win7显示桌面图标移动到左侧(边)显示的实现方法

得了干脆自己整一个算了。下面介绍如何将Win7里的显示桌面改到开始按钮旁。右下角的显示桌面依然存在。1、新建编程客栈一个本文文档,将以下内容复制进去: 复制代码代码如下:[Shell] Command=2 IconFile=explorer
2023-05-29

Android编程实现等比例显示图片的方法

本文实例讲述了Android编程实现等比例显示图片的方法。分享给大家供大家参考,具体如下: 在android中,由于密度的影响,如果想得到图片的宽高是不行的,具体为什么我就大概说一下,具体的请搜索度娘或者古哥吧。 原因是如果你把图片放在dr
2022-06-06

python实现读取并显示图片的两种方法

在 python 中除了用 opencv,也可以用 matplotlib 和 PIL 这两个库操作图片。本人偏爱 matpoltlib,因为它的语法更像 matlab。 一、matplotlib 1. 显示图片import matplotl
2022-06-04

Android编程实现只显示图片一部分的方法

本文实例讲述了Android编程实现只显示图片一部分的方法。分享给大家供大家参考,具体如下: 在Android应用程序中加载一张图片,然后把它显示出来这是一件非常容易的事情,那怎么才能显示一张图片的一小部分呢,一种做法是把图片ps一下,要显
2022-06-06

wordpress分类描述支持显示图片的功能实现方法

有的时候,我们希望在我们的分类页面打印分类描述,以此来介绍我们的分类。但在WordPress中,我们却无编程客栈法在分类描述中使用图片,即标签,那该怎么办呢?本文提供一段简短的代码编程客栈,即可让你的编程客栈分类描述框中的HTML
2022-06-12

phpcms实现列表页显示文字来源及点击数量的方法

复制代码代码如下: {pc:content action="listswww.cppcns.com" catid="$catid" num="25" order="id DESC" page="$page" moreinfo="1"}
2022-06-12

Android编程开发实现TextView显示表情图像和文字的方法

本文实例讲述了Android编程开发实现TextView显示表情图像和文字的方法。分享给大家供大家参考,具体如下: 从这个案例中我们可以学到当我们美化图片美化界面的时候可以在某一区域输入图片和文字混搭信息,第三张图片按比例缩小,第四张图像有
2022-06-06

Android实现从网络获取图片显示并保存到SD卡的方法

本文实例讲述了Android实现从网络获取图片显示并保存到SD卡的方法。分享给大家供大家参考,具体如下: 问题: 如何不断获取图片并显示出来,达到视频的效果? 代码:public class GetPictureFromInternetAc
2022-06-06

在Netdata中实现跨多个服务器和服务的聚合监控数据视图的方法是什么

在Netdata中实现跨多个服务器和服务的聚合监控数据视图的方法是通过使用Netdata的分布式架构和数据收集器。 Netdata提供了一个称为Netdata Cloud的中央管理平台,可用于集中管理和监控多个Netdata节点。要实现跨
在Netdata中实现跨多个服务器和服务的聚合监控数据视图的方法是什么
2024-06-03

编程热搜

目录