OpenLayers之 OverLay问题汇总

一、Overlay

1、简介

主要是放置一些和地图位置相关的元素,如:infowindow、点标记、图片等,而这些覆盖物都是和html中的element等价的,通过overlay的属性element和html元素绑定同时设定坐标参数——达到将html元素放到地图上的位置,在平移缩放的时候html元素也会随着地图的移动而移动。

2、属性

letoverLay = new ol.Overlay(options),此处的 options 便是参数键值对构成的对象字面量。可配置的键值对,定义如下:

  • id,为对应的 overlay 设置一个 id,便于使用 ol.Map 的 getOverlayById 方法取得相应的 overlay;
  • element,overlay 包含的 DOM element;
  • offset,偏移量,像素为单位,overlay 相对于放置位置(position)的偏移量,默认值是 [0, 0],正值分别向右和向下偏移;
  • position,在地图所在的坐标系框架下,overlay 放置的位置;
  • positioning,overlay 对于 position 的相对位置,可能的值包括 bottom-left、bottom-center、bottom-right 、center-left、center-center、center-right、top-left、top-center、top-right,默认是 top-left,也就是 element 左上角与 position 重合;
  • stopEvent,地图的事件传播是否停止,默认是 true,即阻止传播,可能不太好理解,举个例子,当鼠标滚轮在地图上滚动时,会触发地图缩放事件,如果在 overlay 之上滚动滚轮,并不会触发缩放事件,如果想鼠标在 overlay 之上也支持缩放,那么将该属性设置为 false 即可;
  • insertFirst,overlay 是否应该先添加到其所在的容器(container),当 stopEvent 设置为 true 时,overlay 和 openlayers 的控件(controls)是放于一个容器的,此时将 insertFirst 设置为 true ,overlay 会首先添加到容器,这样,overlay 默认在控件的下一层(CSS z-index),所以,当 stopEvent 和insertFirst 都采用默认值时,overlay 默认在 控件的下一层
  • autoPan,当触发 overlay setPosition 方法时触发,当 overlay 超出地图边界时,地图自动移动,以保证 overlay 全部可见;
  • autoPanAnimation,设置 autoPan 的效果动画,参数类型是 olx.animation.panOptions
  • autoPanMargin,地图自动平移时,地图边缘与 overlay 的留白(空隙),单位是像素,默认是 20像素

3、overlay常用方法

  • getElement,取得包含 overlay 的 DOM 元素;
  • getId,取得 overlay 的 id;
  • getMap,获取与 overlay 关联的 map对象;
  • getOffset,获取 offset 属性;
  • getPosition,获取 position 属性;
  • getPositioning,获取 positioning 属性;
  • setElement;设置 overlay 的 element;
  • setMap,设置与 overlay 的 map 对象;
  • setOffset,设置 offset;
  • setPosition,设置 position 属性;
  • setPositioning,设置 positioning 属性。

4、问题以及解决方案

一、

问题描述:创建一个overlay以后,该dom默认是 display:none

原因: openlays6的版本的 id写成默认值时,会出现这个问题

解决方案:将id设置成变量

二、

问题描述:创建多个overlay以后,修改展示顺序,比如:在一个图标上展示一个弹框

解决方案:创建Overlay事,属性保持一致,防止openlayers内部将这些overlay按属性分组放,这样所有的overlay在同一个dom里边。根据图标还是文字框设置不通的classname,然后设置z-index值

let popup = new Overlay({

        id: id,

        element: el,

        positioning: 'top-center',

        // stopEvent: true,

        // insertFirst: true,

        autoPan: autoPan || false,

        offset: [textX || 0, textY || 0],

        className: className ? `ol-overlay-container ol-selectable ${className}` : 'ol-overlay-container ol-selectable'

      })

三、

问题描述:封装overlay模糊查询删除方法时,直接在forEach循环中进行删除,会有删除不尽的问题

解决方案:将模糊查询出来的overlay放在一个数组,再集中删除

5. 方法封装

/**
     * 创建图层的tip框
     * @param {*} tipId overlayId
     * @param {*} eleClassName 创建的元素的class
     * @param {*} text tip框展示的内容
     * @param {*} component 引用的组件
     * @param {*} offset overlay的偏移
     */
    addIconTips({ tipId, eleClassName = 'tips-wrap', text = '', component = '', infoObj = {}, offset = [0, 0], position = undefined }) {
      let el
      if (text) {
        el = document.createElement('div')
        el.style.cssText = `min-width:30px;width:${text.length * 12 + 10}px;`
        el.className = `${eleClassName}`

        let nameEle = document.createElement('div')
        nameEle.className = 'tip-name'
        el.innerText = `${text}`
      }

      if (component) {
        const Marker = Vue.extend(component)
        el = new Marker({
          propsData: {
            item: infoObj
          }
        }).$mount(document.createElement('div')).$el
      }
      let popup = this.CURRENT_MAP.getOverlayById(tipId)
      if (popup) {
        this.CURRENT_MAP.removeOverlay(popup)
      }

      popup = new Overlay({
        id: tipId,
        element: el,
        positioning: 'bottom-center',
        stopEvent: false,
        autoPan: false,
        position,
        offset // 正值分别向右和向下偏移
      })
      this.CURRENT_MAP.addOverlay(popup)
    },
/**
     * 设置overlay显示与隐藏
     * @param {*} title: 根据title模糊查询   overlayId可具体查询  二者选其一
     */
    setOverlayVisible({ title = '', overlayId, state }) {
      if (overlayId) {
        let overlay = this.CURRENT_MAP.getOverlayById(overlayId)
        if (overlay?.get('element')) {
          overlay.get('element').parentElement.style.display = state ? 'flex' : 'none'
        }
        return
      }

      if (title) {
        let overlays = this.CURRENT_MAP.getOverlays()
        overlays.forEach(overlay => {
          const id = overlay?.getId() || ''
          if (id?.includes(title)) {
            if (overlay?.get('element')) {
              overlay.get('element').parentElement.style.display = state ? 'flex' : 'none'
            }
          }
        })
      }
    },
    /**
     * 移除overlay
     * @param {*} title === '' 时,移除全部overlay 根据title模糊查询   overlayId可具体查询  二者选其一
     */
    removeOverLayInMap({ title = '', overlayId }) {
      if (overlayId) {
        let overlay = this.CURRENT_MAP.getOverlayById(overlayId)
        this.CURRENT_MAP.removeOverlay(overlay)
        return
      }
      let overlays = this.CURRENT_MAP.getOverlays()
      if (title) {
        let matches = []
    
        overlays.forEach(overlay => {
          const id = overlay?.getId() || ''
          if (id?.includes(title)) {
            
            // 直接删除会有删不干净的问题,解决办法:先放到一个数组中在进行删除
            //  this.CURRENT_MAP.removeOverlay(overlay)
            matches.push(overlay)
          }
        })
         matches.forEach(m => {
          map.removeOverlay(m)
        })
      } else {
        overlays.clear()
      }
    },

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 OpenLayers Overlay 与 Vue 组件结合的案例: 1. 在 Vue 组件中定义一个 div 元素,并设置其样式和位置,作为 OpenLayers Overlay 的容器。 ```html <template> <div class="map-overlay" ref="overlay"></div> </template> <style> .map-overlay { position: absolute; top: 10px; right: 10px; z-index: 100; } </style> ``` 2. 在 Vue 组件中引入 OpenLayers 库,并在 mounted 钩子函数中创建一个 Overlay 对象,并将其添加到地图上。 ```javascript import ol from 'openlayers'; export default { mounted() { const map = new ol.Map({ target: 'map', // ... }); const overlay = new ol.Overlay({ element: this.$refs.overlay, positioning: 'top-right' }); map.addOverlay(overlay); } } ``` 3. 在 Vue 组件中定义一个方法,用于更新 Overlay 中的内容。这个方法可以根据需要接受一个参数,并将其渲染到 Overlay 容器中。 ```javascript export default { // ... methods: { updateOverlay(content) { this.$refs.overlay.innerHTML = content; } } } ``` 4. 在 Vue 组件中使用 updateOverlay 方法,更新 Overlay 中的内容。 ```javascript export default { // ... mounted() { // ... const overlay = new ol.Overlay({ element: this.$refs.overlay, positioning: 'top-right' }); map.addOverlay(overlay); // 更新 Overlay 内容 this.updateOverlay('Hello, World!'); } } ``` 这个案例中,我们使用了 OpenLayersOverlay 对象来创建一个浮动面板,然后将其与 Vue 组件结合,通过 updateOverlay 方法来更新 Overlay 中的内容。这种方式可以方便地将 OpenLayers 的地图功能与 Vue 组件结合起来,实现更加灵活和丰富的交互效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值