Vite + Vue3 + OpenLayers 弹窗

作者: 德育处主任 | 来源:发表于2021-09-16 11:50 被阅读0次
    Vite + Vue3 + OpenLayers 弹窗

    一、本文简介

    tanchuan

    鼠标在地图上点击会出现一个弹窗,并且出现在鼠标指针上方。

    如果在地图边缘点击,会保证弹窗能完整显示出来,所以会稍微移动底图。

    二、开发环境

    Vite + Vue3 + ol6

    # 1、使用 Vite 创建项目;取个好听的项目名;拉取 vue 的代码模板
    npm init vite@latest
    
    # 2、初始化项目
    cd you-project
    npm install
    
    # 3、安装 ol
    npm i ol -S
    
    # 4、启动项目
    npm run dev
    

    使用 Vite 初始化项目并安装 ol ,更详细做法可以查看 『Vite + Vue3 + OpenLayers 起步』

    三、思路与编码

    思路

    1. 初始化地图
    2. 地图点击事件,并获取当前点击的坐标位置
    3. 弹出窗口

    初始化地图

    初始化地图详细操作可以查看 『Vite + Vue3 + OpenLayers 起步』

    • 要初始化地图,首先需要引入 ol 提供的基础服务
    • 还需要一个地图容器(我使用的是一个 div 标签)
    • 然后通过 ol 提供的方法绑定这个容器
    • 配置基础参数,渲染地图

    地图点击事件

    • ol 提供了一系列的交互事件,其中就有 鼠标点击底图 事件

    • 利用这个事件获取到当前点击的坐标位置

    弹出窗口

    • 弹窗需要一个容器来展示信息(我使用了一个 div 标签)

    • 通过"地图点击事件“获取到的坐标位置来定位弹窗出现的位置

    本例使用了 ol 提供的方法,把 弹窗容器 放入 ol的“覆盖物”’ 中管理。

    弹窗展示了现在所点击的坐标轴信息,还有一个关闭按钮。


    编码

    <template>
        <!-- 地图容器 -->
        <div id="map" class="map__x" ref="mapCom"></div>
        
        <!-- 弹窗容器 -->
        <div ref="popupCom" class="popup">
           <!-- 关闭按钮 -->
          <span class="icon-close" @click="closePopup">✖</span>
          <!-- 弹窗内容(展示坐标信息) -->
          <div class="content">{{currentCoordinate}}</div>
        </div>
    </template>
    
    <script setup>
    import { ref, onMounted } from 'vue'
    import { Map, View } from 'ol' // 引入容器绑定模块和视图模块
    import Tile from 'ol/layer/Tile' // 瓦片加载器
    import XYZ from 'ol/source/XYZ' // 引入XYZ地图格式
    import Overlay from 'ol/Overlay'// 引入覆盖物模块
    import 'ol/ol.css' // ol提供的css样式(必须引入)
    
    const mapCom = ref(null) // 地图容器
    
    const popupCom = ref(null) // 弹窗容器
    
    const map = ref(null) // 地图实例
    
    const overlay = ref(null) // 覆盖物实例
    const currentCoordinate = ref('') // 弹窗信息
    
    // 初始化地图
    function initMap() {
      // 注册一个覆盖物
      overlay.value = new Overlay({
        element: popupCom.value, // 弹窗标签,在html里
        autoPan: true, // 如果弹窗在底图边缘时,底图会移动
        autoPanAnimation: { // 底图移动动画
          duration: 250
        }
      })
      map.value = new Map({
        target: mapCom.value,
        layers: [
          new Tile({ // 加载瓦片
            name: 'defaultLayer',
            source: new XYZ({ // 瓦片底图地址
              url: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
            })
          })
        ],
        view: new View({
          projection: 'EPSG:4326', // 投影坐标系
          center: [113.1206, 23.034996], // 地图中心点
          zoom: 12 // 地图缩放级别(打开页面时默认级别)
        }),
        overlays: [overlay.value] // 绑定一个覆盖物
      })
    
      mapClick() // 在地图初始化完成后再绑定点击事件
    }
    
    // 点击地图事件
    function mapClick() {
      map.value.on('singleclick', evt => { // 绑定一个点击事件
        const coordinate = evt.coordinate // 获取坐标
        currentCoordinate.value = coordinate // 保存坐标点
        overlay.value.setPosition(coordinate) // 设置覆盖物出现的位置
      })
    }
    
    // 关闭弹窗
    function closePopup () {
      overlay.value.setPosition(undefined) // setPosition 传入undefined会隐藏弹窗元素
      currentCoordinate.value = '' // 把弹窗内容清空
    }
    
    onMounted(() => {
      // 在元素加载完之后再执行地图初始化
      initMap()
    })
    </script>
    
    <style lang="scss" scoped>
    .map__x {
      width: 600px;
      height: 600px;
      border: 1px solid #eee;
    }
    
    .popup {
      width: 300px;
      height: 100px;
      background: #fff;
      position: absolute;
      top: -115px;
      left: -150px;
      box-sizing: border-box;
      padding: 10px;
    
      &::after {
        content: '';
        display: block;
        position: absolute;
        width: 20px;
        height: 20px;
        background: #fff;
        bottom: -10px;
        left: 50%;
        transform: translateX(-50%) rotate(45deg);
      }
    
      .icon-close {
        position: absolute;
        top: 0px;
        right: 8px;
        cursor: pointer;
      }
    
      .content {
        margin-top: 14px;
      }
    }
    </style>
    

    四、推荐

    本例展示地址(vite+vue3+ol)

    本例展示地址(备份链接)

    本例仓库(vite+vue3+ol)

    ol在vue2中使用(预览)

    ol在vue2中使用(仓库)

    OpenLayers 官网

    《WebGIS之OpenLayers全面解析(第2版)》

    相关文章

      网友评论

        本文标题:Vite + Vue3 + OpenLayers 弹窗

        本文链接:https://www.haomeiwen.com/subject/yxsrgltx.html