Openlayers V9.2.4 Overlay 详解
#openlayers #overlay #覆盖物
Overlay 是与一个地图位置相关联的地图覆盖元素。Overlay 固定在一个几何坐标上,移动地图时,Overlay 会跟着移动。
Overlay 用于显示需要自定义的 DOM 元素(HTML+CSS),例如弹窗、标注、文本信息、加载 icon 样式不支持的 gif 等格式图片等功能。
基础使用
Overlay 使用时一般分为三个部分,也即 HTML、CSS 和 JavaScript 部分。参考案例为官网案例 1。
HTML 及 CSS 部分
HTML 部分
HTML 部分为
- 一个弹出框
- 右上角有一个 ✖ 用于关闭 overlay
- 中间部分为内容区域
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
CSS 部分
/* popup 总体样式 */
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0,0,0,0.2);
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 280px;
}
.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: "✖";
}
JavaScript 部分
代码使用 Overlay 步骤:
- 导入模块
- 获取 DOM 元素
- 创建 Overlay 实例
- 将 Overlay 添加/移除地图
- 为地图添加唤醒事件,如点击后弹出
// 1. 导入 Overlay 模块
import Overlay from 'ol/Overlay.js';
// 2. 获取 DOM 元素 HTMLElement
const element = document.getElementById('popup'),
// 3. 创建 Overlay 实例
const popup = new Overlay({
element,
});
// 4. 添加到地图中( map 是 Map 类实例,需事先创建)
map.addOverlay(popup);
// 5. 添加点击唤出事件
map.on('click', function (evt) {
const coordinate = evt.coordinate;
popup.setPosition(coordinate);
});
效果如下
创建 Overlay 实例 - Overlay 构造选项
在实例化 Overlay 对象时,一般只需要指定它的 element 选项即可(或增加 id 用于区分不同的 overlay)。
Id
id
: overlay 的唯一标识 ,初始化的时候传入。便于地图实例使用 getOverlayById
方法取得相应的 overlay
,从而进行修改、删除等操作。
element(主要使用选项)
传入从 DOM 获取的 HTMLElement,用于展示自定义的 HTML 元素。
实际使用中,一般使用 DOM 的方法获取。例如
const element = document.getElementById("overlay")
地图添加/移除 Overlay
Overlay 在地图实例中是以一个数组形式添加的。因此,以地图实例入手,控制地图实例的 Overlay 数组进行增加、删除数组内元素,即可控制地图中 Overlay 增删。
添加 Overlay
地图添加 Overlay 有两种方式:
- 地图实例使用 addOverlay 方法添加 Overlay
- Overlay 实例使用 setMap 方法设置地图实例
代码如下
// 地图实例添加Overlay
map.addOverlay(overlay);
// Overlay实例设置地图
overlay.setMap(map);
移除 Overlay
移除 Overlay2 有几种方法:
- 地图实例方法删除单个 Overlay,删除 DOM;
- 直接控制地图实例的 Overlay 数组删除全部 Overlay,删除 DOM;
- Overlay 使用 setPosition 方法将 position 设置为 undefined
- Overlay 使用 setmap 方法,将 map 设置为 null
代码如下:
// 1. Map 方法删除单个 overlay
map.removeOverlay(overlay);
// 2. 直接操作 Map 的 Overlay 数组删除全部 Overlay
map.getOverlays().clear();
// 3. 单个 Overlay 使用 setPosition 方法隐藏
overlay.setPosition(undefined);
// 4. 单个 Overlay 使用 setmap 方法
overlay.setMap(unll);
API 分析
因为 Overlay 的方法主要是属性的 get 和 set 方法以及事件的绑定和解绑。因此本节主要分析构造选项中的参数 34。
位置参数
position
:在地图坐标系下,overlay 放置的位置。
offset
:偏移量,单位为像素。overlay
相对于放置位置(position
)的偏移量,默认值是 [0, 0]
,正值分别向右和向下偏移。
positioning
: overlay
对于 position
的相对位置,默认为 top-left
。
可以的值为 9 个位置,上中下和左中右。
'top-left'
'top-center'
'top-right'
'center-left'
'center-center'
'center-right'
'bottom-left'
'bottom-center'
'bottom-right'
上述三个参数有 get 和 set 方法。
==TODO::positioning 9 种参数的相对位置==
样式参数
-
autoPan
:相当于就是给 overlay 增加了个外边距,一般不用管它,或者当你需要对此覆盖物四周进行逻辑处理时,再去研究也不迟 -
autoPanAnimation
,用于将叠加层平移到视图中的动画选项。此动画仅在autoPan
启用时使用。可以提供 Aduration
和easing
来自定义动画。如果autoPan
作为对象提供,则弃用并忽略。 -
className
:overlay 实例化后的总的 dom 的 CSS 类名,一般都用默认的,不在此加入新的样式,当然这还是根据你的需求来变
insertFirst
官网定义 5
此属性控制是先将 overlay 插入(insert) 到叠加层容器中,还是 追加(append) 。如果 overlay 与 controls 的覆盖层放置在同一个容器(container)中(请参阅 stopEvent
选项),则可能会将 insertFirst=true
,以便 overlay 显示在 controls 下方。
参数理解 2
insertFirst
是一个 boolean
值,默认为 true
,可以用于部分控制多个 Overlay 的重叠覆盖问题(类似于 z-index)。
当 insertFirst=true
时, overlay 会按照添加顺序依次添加到地图中,此时 overlay 的覆盖关系由添加顺序决定,后添加的 overlay 会覆盖先添加的 overlay。
当 insertFirst=false
时,当使用方法显示 overlay 后,此时才将 overlay 插入(insert),从而可以实现动态的覆盖效果,也即先出现的在下面,后出现的在上面。
事件参数
stopEvent
,是否应停止事件传播到地图视口。这个就跟原生 js 里的 stopPropagation 一样,阻止事件冒泡到父元素上,一般就使用默认的 true
涉及 Overlay 的事件冒泡机制。例如在 overlay 弹窗存在滚动条的情况下,鼠标滚轮滚动,地图缩放和 overlay 弹窗会一起触发。
这时候 stopEvent=true
即可阻止冒泡
参考
Footnotes
转载自:https://juejin.cn/post/7375083022612037666