zoukankan      html  css  js  c++  java
  • 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;
                     0;
                    position: absolute;
                    pointer-events: none;
                }
    
                .ol-popup:after
                {
                    border-top-color: white;
                    border- 10px;
                    left: 48px;
                    margin-left: -10px;
                }
    
                .ol-popup:before
                {
                    border-top-color: #cccccc;
                    border- 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: "微软雅黑";
                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真困难,这个东西没少浪费时间

  • 相关阅读:
    NMON记录服务器各项性能数据
    性能测试基础知识
    Jmeter——小性能用例
    POSTMAN——环境变量
    Jmeter——分布式并发
    Linux-Ps命令使用
    Linux目录结构和常用命令
    Linux复制和移动文件
    Linux目录结构
    Linux-获得命令帮助man
  • 原文地址:https://www.cnblogs.com/tuboshu/p/10752357.html
Copyright © 2011-2022 走看看