OpenLayer学习之聚合标注和信息框弹出

首先感觉我做的这个Demo是真的烂,查资料都没有多少,自己摸索着做出来,虽然比较烂,但是毕竟是一种思路

一、聚合图层的组成

1、Vector的source,这里面主要放feature,这个source不是直接加载到Vector图层中的source

        for (var i = 0; i < dataSource.length; i++) {
            var coordinate = ol.proj.transform([dataSource[i].x, dataSource[i].y], 'EPSG:4326', 'EPSG:3857');

            var attr = {
                attribute: dataSource[i].attribute
            };
            features[i] = new ol.Feature({
                geometry: new ol.geom.Point(coordinate),
                attribute: attr
            });
        }
        console.log(features);
        var source = new ol.source.Vector({
            features: features,
        });

2、声明ol.source.Cluster

        var clusterSource = new ol.source.Cluster({
            distance: 40,
            source: source
        });

注意这里source是上面ol.source.Vector

二、初始化聚合图层

        //加载聚合标注的矢量图层
        var styleCache = {};
        var layerVetor = new ol.layer.Vector({
            source: clusterSource,//注意一定不要搞错了
            style: function (feature, resolution) {
                var size = feature.get('features').length;
                var style = styleCache[size];
                if (!style) {
                    style = [new ol.style.Style({
                        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */({
                            anchor: [0.5, 60],
                            anchorOrigin: 'top-right',
                            anchorXUnits: 'fraction',
                            anchorYUnits: 'pixels',
                            offsetOrigin: 'top-right',
                            offset: [0, 1],//偏移量设置
                            scale: 0.2,  //图标缩放比例
                            opacity: 0.75,  //透明度
                            src: 'Script/Marker.png'//图标的url
                        })),
                        text: new ol.style.Text({
                            text: size.toString(),
                            fill: new ol.style.Fill({
                                color: 'blue'
                            })
                        })
                    })];
                    styleCache[size] = style;
                }
                return style;
            }
        });
        var map = new ol.Map({
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                })
            ],
            view: new ol.View({
                center: ol.proj.transform([104.06, 30.67], 'EPSG:4326', 'EPSG:3857'),
                zoom: 10
            }),
            target: 'map',
            controls: ol.control.defaults().extend([
                new ol.control.FullScreen(),
                new ol.control.OverviewMap(),
                new ol.control.Zoom(),
                new ol.control.MousePosition()
            ]),
        });
        map.addLayer(layerVetor);

三、弹出框的设置

        /**
        * 实现popup的html元素
        */
        var container = document.getElementById('popup');
        var content = document.getElementById('popup-content');
        var closer = document.getElementById('popup-closer');

        /**
        * 在地图容器中创建一个Overlay
        */
        var popup = new ol.Overlay(/** @type {olx.OverlayOptions} */({
            element: container,
            autoPan: true,
            positioning: 'bottom-center',
            stopEvent: false,
            autoPanAnimation: {
                duration: 250
            }
        }));
        map.addOverlay(popup);

        /**
        * 添加关闭按钮的单击事件(隐藏popup)
        * @return {boolean} Don't follow the href.
        */
        closer.onclick = function () {
            popup.setPosition(undefined);  //未定义popup位置
            closer.blur(); //失去焦点
            return false;
        };
        /**
* 动态创建popup的具体内容
* @param {string} title 
*/
        function addFeatrueInfo(info) {
            //新增a元素
            var elementA = document.createElement('a');
            content.appendChild(elementA); // 新建的div元素添加a子节点
            var elementDiv1 = document.createElement('div');
            elementDiv1.className = "markerText";
            //elementDiv.innerText = info.att.text;
            setInnerText(elementDiv1, "所属省份:"+info.proname);
            content.appendChild(elementDiv1); // 为content添加div子节点  
            //新增div元素
            var elementDiv = document.createElement('div');
            elementDiv.className = "markerText";
            //elementDiv.innerText = info.att.text;
            setInnerText(elementDiv,"地名:"+ info.name);
            content.appendChild(elementDiv); // 为content添加div子节点 

        }
        /**
        * 动态设置元素文本内容(兼容)
        */
        function setInnerText(element, text) {
            if (typeof element.textContent == "string") {
                element.textContent = text;
            } else {
                element.innerText = text;
            }
        }
        layerVetor.on('click', function (evt) {
            var geometry = evt.Feature;
            console.log(geometry);
        });
        /**
        * 为map添加点击事件监听,渲染弹出popup
        */
        map.on('click', function (evt) {
            var coordinate = evt.coordinate;
            //判断当前单击处是否有要素,捕获到要素时弹出popup
            var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layerVetor) { return feature; });
            var featuerInfo = feature.getProperties().features[0].N.attribute.attribute;
            if (feature) {
                content.innerHTML = ''; //清空popup的内容容器
                addFeatrueInfo(featuerInfo); //在popup中加载当前要素的具体信息
                if (popup.getPosition() == undefined) {
                    popup.setPosition(coordinate); //设置popup的位置
                }
            }
        });
        /**
        * 为map添加鼠标移动事件监听,当指向标注时改变鼠标光标状态
        */
        map.on('pointermove', function (e) {
            var pixel = map.getEventPixel(e.originalEvent);
            var hit = map.hasFeatureAtPixel(pixel);
            map.getTargetElement().style.cursor = hit ? 'pointer' : '';
        })

四、全部源码

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>聚合和弹出</title>
    <link href="Script/ol.css" rel="stylesheet" />
    <style type="text/css">
        .ol-popup
        {
            position: absolute;
            background-color: white;
            -webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
            filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
            padding: 15px;
            border-radius: 10px;
            border: 1px solid #cccccc;
            bottom: 12px;
            left: -50px;
        }

            .ol-popup:after, .ol-popup:before
            {
                top: 100%;
                border: solid transparent;
                content: " ";
                height: 0;
                width: 0;
                position: absolute;
                pointer-events: none;
            }

            .ol-popup:after
            {
                border-top-color: white;
                border-width: 10px;
                left: 48px;
                margin-left: -10px;
            }

            .ol-popup:before
            {
                border-top-color: #cccccc;
                border-width: 11px;
                left: 48px;
                margin-left: -11px;
            }

        .ol-popup-closer
        {
            text-decoration: none;
            position: absolute;
            top: 2px;
            right: 8px;
        }

            .ol-popup-closer:after
            {
                content: "✖";
                height:30px;
                padding:12px;
            }

        #popup-content
        {
            font-size: 14px;
            font-family: "微软雅黑";
            width:100px;
        }

            #popup-content .markerInfo
            {
                font-weight: bold;
            }
    </style>
    <script src="Script/ol.js"></script>
    <script src="Script/data.js"></script>
</head>

<body>

    <div id="map">
        <!-- Popup -->
        <div id="popup" class="ol-popup">
            <a href="#" id="popup-closer" class="ol-popup-closer"></a>
            <div id="popup-content">
            </div>
        </div>
    </div>
    <script>
        var dataSource = county.items;
        var features = new Array(dataSource.length);
        for (var i = 0; i < dataSource.length; i++) {
            var coordinate = ol.proj.transform([dataSource[i].x, dataSource[i].y], 'EPSG:4326', 'EPSG:3857');

            var attr = {
                attribute: dataSource[i].attribute
            };
            features[i] = new ol.Feature({
                geometry: new ol.geom.Point(coordinate),
                attribute: attr
            });
        }
        console.log(features);
        var source = new ol.source.Vector({
            features: features,
        });
        var clusterSource = new ol.source.Cluster({
            distance: 40,
            source: source
        });
        //加载聚合标注的矢量图层
        var styleCache = {};
        var layerVetor = new ol.layer.Vector({
            source: clusterSource,
            style: function (feature, resolution) {
                var size = feature.get('features').length;
                var style = styleCache[size];
                if (!style) {
                    style = [new ol.style.Style({
                        image: new ol.style.Icon(/** @type {olx.style.IconOptions} */({
                            anchor: [0.5, 60],
                            anchorOrigin: 'top-right',
                            anchorXUnits: 'fraction',
                            anchorYUnits: 'pixels',
                            offsetOrigin: 'top-right',
                            offset: [0, 1],//偏移量设置
                            scale: 0.2,  //图标缩放比例
                            opacity: 0.75,  //透明度
                            src: 'Script/Marker.png'//图标的url
                        })),
                        text: new ol.style.Text({
                            text: size.toString(),
                            fill: new ol.style.Fill({
                                color: 'blue'
                            })
                        })
                    })];
                    styleCache[size] = style;
                }
                return style;
            }
        });
        var map = new ol.Map({
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.OSM()
                })
            ],
            view: new ol.View({
                center: ol.proj.transform([104.06, 30.67], 'EPSG:4326', 'EPSG:3857'),
                zoom: 10
            }),
            target: 'map',
            controls: ol.control.defaults().extend([
                new ol.control.FullScreen(),
                new ol.control.OverviewMap(),
                new ol.control.Zoom(),
                new ol.control.MousePosition()
            ]),
        });
        map.addLayer(layerVetor);


        /**
        * 实现popup的html元素
        */
        var container = document.getElementById('popup');
        var content = document.getElementById('popup-content');
        var closer = document.getElementById('popup-closer');

        /**
        * 在地图容器中创建一个Overlay
        */
        var popup = new ol.Overlay(/** @type {olx.OverlayOptions} */({
            element: container,
            autoPan: true,
            positioning: 'bottom-center',
            stopEvent: false,
            autoPanAnimation: {
                duration: 250
            }
        }));
        map.addOverlay(popup);

        /**
        * 添加关闭按钮的单击事件(隐藏popup)
        * @return {boolean} Don't follow the href.
        */
        closer.onclick = function () {
            popup.setPosition(undefined);  //未定义popup位置
            closer.blur(); //失去焦点
            return false;
        };
        /**
* 动态创建popup的具体内容
* @param {string} title 
*/
        function addFeatrueInfo(info) {
            //新增a元素
            var elementA = document.createElement('a');
            content.appendChild(elementA); // 新建的div元素添加a子节点
            var elementDiv1 = document.createElement('div');
            elementDiv1.className = "markerText";
            //elementDiv.innerText = info.att.text;
            setInnerText(elementDiv1, "所属省份:"+info.proname);
            content.appendChild(elementDiv1); // 为content添加div子节点  
            //新增div元素
            var elementDiv = document.createElement('div');
            elementDiv.className = "markerText";
            //elementDiv.innerText = info.att.text;
            setInnerText(elementDiv,"地名:"+ info.name);
            content.appendChild(elementDiv); // 为content添加div子节点 

        }
        /**
        * 动态设置元素文本内容(兼容)
        */
        function setInnerText(element, text) {
            if (typeof element.textContent == "string") {
                element.textContent = text;
            } else {
                element.innerText = text;
            }
        }
        layerVetor.on('click', function (evt) {
            var geometry = evt.Feature;
            console.log(geometry);
        });
        /**
        * 为map添加点击事件监听,渲染弹出popup
        */
        map.on('click', function (evt) {
            var coordinate = evt.coordinate;
            //判断当前单击处是否有要素,捕获到要素时弹出popup
            var feature = map.forEachFeatureAtPixel(evt.pixel, function (feature, layerVetor) { return feature; });
            var featuerInfo = feature.getProperties().features[0].N.attribute.attribute;
            if (feature) {
                content.innerHTML = ''; //清空popup的内容容器
                addFeatrueInfo(featuerInfo); //在popup中加载当前要素的具体信息
                if (popup.getPosition() == undefined) {
                    popup.setPosition(coordinate); //设置popup的位置
                }
            }
        });
        /**
        * 为map添加鼠标移动事件监听,当指向标注时改变鼠标光标状态
        */
        map.on('pointermove', function (e) {
            var pixel = map.getEventPixel(e.originalEvent);
            var hit = map.hasFeatureAtPixel(pixel);
            map.getTargetElement().style.cursor = hit ? 'pointer' : '';
        })
    </script>
</body>
</html>

五、效果图

六、总结

这里我用的是一个data数据,这里的坐标主要针对天地图比较准点,OSM好像看着不太准,就当看看效果图把,这里有Bug就是这个点击查询元素不太灵敏,我想应该有个缓冲区,但是始终没有找到,还有就是那个我把Attribute与放在要素里面,点击选择的时候这个获取atrrbute真困难,这个东西没少浪费时间

 

转载于:https://www.cnblogs.com/tuboshu/p/10752357.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在OpenLayers地图上点击位置后弹提示框,可以使用Overlay和Popup来实现。以下是一个简单的例子: ```javascript // 创建地图 var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([116.3975, 39.9086]), zoom: 10 }) }); // 创建一个VectorLayer用于添加点 var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); // 创建一个Overlay用于显示提示框 var popupOverlay = new ol.Overlay({ element: document.getElementById('popup'), autoPan: true, autoPanAnimation: { duration: 250 } }); // 创建一个点击事件处理函数 function handleMapClick(event) { // 获取点击位置的坐标 var coordinate = event.coordinate; // 创建一个点Feature并添加到VectorLayer上 var feature = new ol.Feature({ geometry: new ol.geom.Point(coordinate) }); vectorLayer.getSource().addFeature(feature); // 设置提示框内容为坐标 var content = '<p>坐标:' + coordinate + '</p>'; document.getElementById('popup-content').innerHTML = content; // 将提示框显示在点击位置上 popupOverlay.setPosition(coordinate); map.addOverlay(popupOverlay); } // 监听Map对象的"click"事件,并在回调函数中处理点击事件 map.on('click', handleMapClick); // 将VectorLayer添加到地图上 map.addLayer(vectorLayer); ``` 在HTML中还需要添加一个Popup的容器,如下所示: ```html <div id="map"></div> <div id="popup" class="ol-popup"> <a href="#" id="popup-closer" class="ol-popup-closer"></a> <div id="popup-content"></div> </div> ``` 这样就可以在地图上点击位置后弹提示框了,提示框会显示点击位置的坐标。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值