OpenLayers之信息窗体

看过之前的文章,对于OpenLayers会有一个大致的了解。下面我们继续讲解 OpenLayer如何创建信息窗口。

下面示例是以 OpenLayersV8.2.0版本 作为依赖包

信息窗体

在Openlayer中,信息窗体属于覆盖物(Overlay),和高德地图的信息窗体类似。Web端,信息窗体与点标记的区别是:前者是通过DOM节点构成,后者是矢量图形。

我们也可以通过覆盖物(Overlay)来创建点标记,不过这个要看开发场景,如果数据量巨大,推荐使用矢量点标记,反之覆盖物点标记也可以。

Overlay

ol.Overlay是覆盖物API,主要用途就是在地图之上覆盖DOM元素,作为弹窗、提示窗、标注信息等,通过给定的经纬度,它会固定在对应的点位上,移动地图或拖动地图,覆盖物(Overlay)与地图的相对位置不变。

  • ol.Overlay:显示在地图上并附加到单个地图位置的元素。与Control一样,套印格式也是可见的小部件。与"控件"不同,它们不在屏幕上的固定位置,而是与地理坐标绑定,因此平移地图将移动"覆盖"。
yaml 复制代码
const popup = new Overlay({
  element: document.getElementById('popup'),
  autoPan: true,
  positioning: 'bottom-center',
  stopEvent: false,
  offset: [0, 0],
  autoPanAnimation: { duration: 250 }
  // ...更多属性
});
popup.setPosition(coordinate);
map.addOverlay(popup);

关于ol.OverlayAPI更多属性配置,可以查看官方文档:ol.Overlay

示例

xml 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>点聚合 Map</title>
    <link rel="stylesheet" href="./8.2.0/theme/ol.css">
    <script src="./8.2.0/en/latest/ol/dist/ol.js"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/ol@v8.2.0/dist/ol.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v8.2.0/ol.css"> -->
    <style>
        #infowindow {
            background: rgba(0, 0, 0, 0.66);
            border-radius: 5px;
            padding: 5px;
            color: #fff;
        }
    </style>
</head>

<body>
    <div id="map" style="height: 95vh; border: 6px solid;"></div>
    <div id="infowindow"></div>

    <script>
        const url = 'https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}'
        let map = new ol.Map({
            target: 'map',
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.XYZ({
                        url: url
                    })
                })
            ],
            view: new ol.View({
                center: [116.39, 39.91],
                zoom: 11,
                projection: 'EPSG:4326'
            })
        });
        // 地图点击事件
        map.on('click', (e) => {
            console.log(e);
        })


        const element = document.getElementById('infowindow');
        let infowindow = null;
        const coordinate = [
            [
                116.28288330078125,
                39.91595224314723
            ],
            [
                116.49848999023439,
                39.881633003379434
            ]
        ]

        // 以下是点标记代码
        // 创建Style样式
        const iconStyle = new ol.style.Style({
            image: new ol.style.Icon({
                anchor: [0.5, 0.5],
                color: 'blue',
                src: './img/point.png',
                width: 30
            }),
            text: new ol.style.Text({
                text: '点标记',
                offsetY: -25,
                fill: new ol.style.Fill({ color: 'blue' })
            })
        })
        // 创建Feature要素
        const features = coordinate.map((item) => {
            const Feature = new ol.Feature({
                // 创建geometry
                geometry: new ol.geom.Point(item),
                name: 'Marker'
            })
            Feature.positon = item;
            return Feature;
        })
        // 创建Vector图层
        const vectorLayer = new ol.layer.Vector({
            source: new ol.source.Vector(),
            style: iconStyle
        })
        features.forEach((item) => vectorLayer.getSource().addFeature(item))
        map.addLayer(vectorLayer);
        // 点标注点击
        map.on('click', (evt) => {
            const Feature = map.forEachFeatureAtPixel(evt.pixel, (feature) => {
                return feature
            })
            if (Feature && Feature.get('name') === 'Marker') {
                console.log('Marker点标注', Feature);
                const positon = Feature.positon;
                if (!infowindow) {
                    addInfoWindow(positon);
                } else {
                    element.innerHTML = positon.toString();
                    infowindow.setPosition(positon);
                }

            }
        })
        // 以上是点标记代码

        // 创建覆盖物
        function addInfoWindow(positon) {
            infowindow = new ol.Overlay({
                element: element,
                autoPan: true,
                positioning: 'bottom-center',
                stopEvent: false,
                offset: [0, -32],
                autoPanAnimation: { duration: 250 }
            })
            map.addOverlay(infowindow);
            element.innerHTML = positon.toString();
            infowindow.setPosition(positon);
        }
    </script>
</body>

</html>

当点击点标记,信息窗体即会展示。来预览下覆盖物(Overlay)上图的效果吧!

总结

  • 在openlayer中,信息窗体属于覆盖物(Overlay);
  • 覆盖物(Overlay)的主体是DOM元素节点,移动地图或拖动地图,主体会伴随相对位置不变;
  • ol.Overlay覆盖物(Overlay)也可用来创建点标记、文本等;

掘金2023年度人气创作者打榜中,快来帮我打榜吧~activity.juejin.cn/rank/2023/w...

相关推荐
少云清17 分钟前
【UI自动化测试】12_web自动化测试 _验证码处理和cookie
前端·python·web自动化测试
linux_cfan1 小时前
2026版 WordPress 视频插件终极选型:知识付费创作者如何低成本打造专业在线课堂?
前端·javascript·音视频·html5
pas1361 小时前
46-mini-vue 实现编译 template 为 render 函数
前端·javascript·vue.js
木斯佳1 小时前
前端八股文面经大全:京东零售前端实习一面(2026-1-20)·面经深度解析
前端·状态模式·零售
YuMiao2 小时前
把 WebSocket 服务迁移到 Cloudflare Durable Objects —— 以一次协同编辑实战为例
javascript·node.js
zheshiyangyang2 小时前
前端面试基础知识整理【Day-8】
前端·面试·职场和发展
a1117762 小时前
优雅简历(html开源)
前端·开源·html
Cache技术分享2 小时前
330. Java Stream API - 处理 Optional 对象:像流一样优雅地使用 Optional
前端·后端
感性的程序员小王2 小时前
别再手撸架构图了!我写了个 AI 工具,把 Spring Boot 代码一键变成 Draw.io 流程图
前端·后端
猪头男2 小时前
【从零开始学习Vue|第七篇】深入组件——Props
前端