openlayers-18-聚合显示补充(切换聚合与非聚合状态)

最近有一些网友问我,聚合显示怎么实现聚合与不聚合之间的切换,有很多方法能够实现,下面是一个示例作为参考。

openlayers-18-聚合显示补充(切换聚合与非聚合状态)_第1张图片
openlayers-18-聚合显示补充(切换聚合与非聚合状态)_第2张图片

DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>加载天地图title>
    <link href="ol/ol.css" rel="stylesheet" type="text/css" />
    <script src="ol/ol.js" type="text/javascript">script>
    <style type="text/css">
       html,body{
        margin:0px;
        padding:0px;
       }
       #mapCon {
            width: 100%;
            height: 98%;
        }
    style>
head>
<body>
    
    <div id="mapCon">div>
    <div style="position: absolute;top:10px;left:50px;">
        <button onclick="toggleCluster()">切换聚合button>
    div>
    <script type="text/javascript">
        var key = "4689fc6b9bc0fdc8c48298f751ebfb41";//天地图密钥
        var center = [116.3913,39.9071];
        var pointArr = [[116.3913,39.9071],[116.3813,39.9071],[116.3713,39.9071],[116.3613,39.9071],[115.3913,38.9071],[115.3813,38.9071],[115.3613,38.9071],[115.3313,38.9071]];//北京经纬度
        //ol.layer.Tile:是一个瓦片图层类,用于显示瓦片资源。
        //source是必填项,用于为图层设置来源。

        //ol.source.XYZ: 
        //创建天地图矢量图层
        var TiandiMap_vec = new ol.layer.Tile({
            title: "天地图矢量图层",
            source: new ol.source.XYZ({
                url: "http://t{0-7}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=" + key,
                wrapX: false
            })
        });
        //创建天地图矢量注记图层
        var TiandiMap_cva = new ol.layer.Tile({
            title: "天地图矢量注记图层",
            source: new ol.source.XYZ({
                url: "http://t{0-7}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=" + key,
            })
        });
        //1. 实例化Map对象加载地图
        var map = new ol.Map({
            //地图容器div的ID
            target: 'mapCon',
            //地图容器中加载的图层
            layers: [TiandiMap_vec, TiandiMap_cva],
            //地图视图设置
            view: new ol.View({
                //地图初始中心点(经纬度)
                center: center,
                //地图初始显示级别
                zoom: 8,
                projection: "EPSG:4326"
            })
        });
        //2.创建用于放置标注的矢量图层以及图层源
        //矢量标注的数据源-非聚合
        var vectorSource = new ol.source.Vector();
        //3.聚合标注数据源
        var clusterSource = new ol.source.Cluster({
            distance: 40,
            source: vectorSource
        });
        var styleCache = {};
        //矢量标注图层
        var vectorLayer = new ol.layer.Vector({
            source: clusterSource,//初始设置源为聚合源
            zIndex:1000,
            style: function (feature, resolution) {
                
                var size = feature.get('features').length;
                var style;
                //当前的标注仅包含一个feature时,采用该feature的样式显示,而不是统一聚合样式,这个很有用
                if (size == 1) {
                    style = styleCache[feature.get('features')[0].get("name")];
                } else {
                    style = styleCache[size];
                }
                if (!style) {
                    style = [
                        new ol.style.Style({
                            image: new ol.style.Circle({
                                radius: 10,
                                stroke: new ol.style.Stroke({
                                    color: '#fff'
                                }),
                                fill: new ol.style.Fill({
                                    color: '#cc4700'
                                })
                            }),
                            text: new ol.style.Text({
                                text: size.toString(),
                                fill: new ol.style.Fill({
                                    color: '#fff'
                                })
                            })
                        })
                    ];
                    if (size == 1) {
                        //这里采用那么作为styleCache对象key的值,name是唯一的,
                        //这样就可以为为每一个feature设置不同的样式,因为起初feature未聚合前,
                        //可能会使用不同的图标来表示不同的目标
                        let pkiaa = feature.get('features')[0].get("name");
                        style = feature.get('features')[0].getStyle();
                        styleCache[pkiaa] = style;
                    } else {
                        styleCache[size] = style;
                    }
                }
                return style;
            }
        });
        map.addLayer(vectorLayer);

        //4.实例化矢量标注对象并添加到矢量图层源
        for (let index = 0; index < pointArr.length; index++) {
            const element = pointArr[index];
            var markerFeature = new ol.Feature({
                geometry: new ol.geom.Point(element),
                name:'point_'+index,//保证唯一性,在聚合显示时用于区分独立的 style
            });
            markerFeature.setStyle(createMarkerStyle(markerFeature));
            //将新要素添加到数据源中
            vectorSource.addFeature(markerFeature);
        }
        //切换聚合状态
        function toggleCluster(){
            //获取当前矢量图层的源
            let vecSource = vectorLayer.getSource();
            //判断矢量图层的 源 是否 有 distance属性,该属性是聚合矢量源特有,可以根据此来判断当前 矢量图层的源是 聚合源还是非聚合源
            //如果有distance属性,则设置矢量图层的源 为  非聚合源
            if (vecSource.distance !=undefined){
                vectorLayer.setSource(vectorSource);
            }
            //如果没有distance属性,则设置矢量图层的源 为 聚合源
            else{
                vectorLayer.setSource(clusterSource);
            }
        }
        //创建矢量标注样式
        function createMarkerStyle(feature) {
            //获取name,根据不同的name,配置不同的图标
            let name = feature.get("name");
            let index = name.split('_')[1];
            console.log(index);
            let imageUrl = 'static/img/hq.png';
            if (index%2 == 0) {//与2求余为0的,设置为勋章 标记
                imageUrl = "static/img/xz.png";
            }
            return new ol.style.Style({
                /**{olx.style.IconOptions}类型*/
                image: new ol.style.Icon(
                    ({
                        // anchor: [0.5, 0.5],//图标的锚点,经纬度点所对应的图标的位置,默认是[0.5, 0.5],即为标注图标的中心点位置
                        anchorOrigin: 'top-right',//锚点的偏移位置,默认是top-left,
                        anchorXUnits: 'fraction',//锚点X的单位,默认为百分比,也可以使用px
                        anchorYUnits: 'pixels',//锚点Y的单位,默认为百分比,也可以使用px
                        offsetOrigin: 'top-right',//原点偏移bottom-left, bottom-right, top-left, top-right,默认 top-left
                        // offset:[0,10],
                        //图标缩放比例
                        // scale:0.5,//可以设置该比例实现,图标跟随地图层级缩放
                        //透明度
                        opacity: 0.75,//如果想隐藏某个图标,可以单独设置该值,透明度为0时,即可隐藏,此为隐藏元素的方法之一。
                        //图标的url
                        src: imageUrl
                    })
                ),
                text: new ol.style.Text({
                    //位置
                    textAlign: 'center',
                    //基准线
                    textBaseline: 'middle',
                    //文字样式
                    font: '20px 宋体',
                    //文本内容
                    text: feature.get('name'),//通过设置的fature的name属性获取,也可以通过参数获取设置,此处接收 字符串 对象
                    //文本填充样式(即文字颜色),红色
                    fill: new ol.style.Fill({ color: '#ff002f' }),
                    //描边颜色,蓝色
                    stroke: new ol.style.Stroke({ color: '#0022ff', width: 1 })
                })
            });
        }
    script>
body>
html>

你可能感兴趣的:(OpenLayers入门与实践,前端,openlayer,webgis,ol)