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

场景

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

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/118631046

上面实现加载显示离线地图并显示图标元素的效果后。

实现当多个元素堆积在一起时实现聚合显示效果。

并且伴随着地图的缩放实现自动聚合显示和取消聚合。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

1、随机创建一些要素

        // 随机创建要素
        var clusterSource = new ol.source.Vector();
        debugger
        for (var i = 1; i <= 10; i++) {
            var coordinates = [-11551949.709486058 + Math.random(), 5533080.7247905275 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            clusterSource.addFeature(feature);
        }
        for (var i = 1; i <= 20; i++) {
            var coordinates = [-11553949.709486058 + Math.random(), 5527080.7247905275 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            clusterSource.addFeature(feature);
        }

这里的坐标值是从地图上获取的一些坐标值,然后通过对x和y随机增加随机数,构造一组10和一组20个的要素。

2、新建聚合图层数据源

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

这里的distance就是设置的聚合的距离。

3、新建聚合图层

        // 聚合图层
        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: function (feature, resolution) {
                var size = feature.get('features').length;
                if (size == 1) {
 }else{
 }

如果size大于1则返回聚合样式,反之则返回图片样式。

4、将聚合图层添加进地图

        //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, clusterLayer],
            target: 'map',
            view: view
        });

5、除此之外的代码就是离线加载瓦片地图的代码,完整代码

<!doctype html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>OpenLayers example</title>
    <link rel="stylesheet" href="lib/ol65/ol.css" type="text/css">
    <style>
        html,
        body,
        #map {
            padding: 0;
            margin: 0;
             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 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();
        debugger
        for (var i = 1; i <= 10; i++) {
            var coordinates = [-11551949.709486058 + Math.random(), 5533080.7247905275 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            clusterSource.addFeature(feature);
        }
        for (var i = 1; i <= 20; i++) {
            var coordinates = [-11553949.709486058 + Math.random(), 5527080.7247905275 + Math.random()];
            var feature = new ol.Feature(new ol.geom.Point(coordinates));
            clusterSource.addFeature(feature);
        }

        // 聚合图层数据源
        var clusterSourceForLayer = new ol.source.Cluster({
            source: clusterSource,
            distance: 100
        })
        // 聚合图层
        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, clusterLayer],
            target: 'map',
            view: view
        });

        //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>
博客园: https://www.cnblogs.com/badaoliumangqizhi/ 关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。
原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/15730484.html