Vite + Vue3 + OpenLayers 彈窗

一、本文簡介

鼠標在地圖上點擊會出現一個彈窗,並且出現在鼠標指針上方。

如果在地圖邊緣點擊,會保證彈窗能完整顯示出來,所以會稍微移動底圖。



二、開發環境

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版)》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章