引言
OpenLayers 是一个开源的 JavaScript 库,用于在网页上展示地图。随着 Vue 3.0 的发布,我们可以利用 Vue 的响应式系统和组件化特性来封装 OpenLayers,以便在 Vue 项目中更方便地使用地图功能。本文将介绍如何在 Vue 3.0 项目中封装 OpenLayers 地图组件。
仓库地址: gitee.com/Mr-ZhouCB/v…
准备工作
首先,确保你的项目中已经安装了 Vue 3.0。然后,通过 npm 安装 OpenLayers:
npm install ol
封装 OpenLayers 地图组件
接下来,我们将创建一个 Vue 组件来封装 OpenLayers 地图。这个组件将负责地图的初始化、图层的管理以及地图的基本交互。
1. 项目中使用结构
<Openlayers id="maps">
<OlView :defaultOptions="mapStore['ol'].view">
// 图层选择组件
<OlSelectLayers v-model:value="mapStore['ol'].map.layer"></OlSelectLayers>
//比例尺组件
<OlScaleLine></OlScaleLine>
//右键菜单组件
<OlContextmenu @change:center="onChangeCenter" @change:zoom="onChangeZoom"></OlContextmenu>
// 测面积, 测距组件
<OlMeasure>
<OlDistance></OlDistance>
<OlArea></OlArea>
</OlMeasure>
//地图缩放控件
<OlZoom></OlZoom>
// 指南针
<OlCompass></OlCompass>
// 切换cesium控件
<OlSelectMap v-model:value="mapStore.source"></OlSelectMap>
// 省市区控件
<SelectArea></SelectArea>
</OlView>
</Openlayers>
2. 创建地图组件 Openlayers.vue
<template>
<div class="map" ref="mapRef">
<slot></slot>
</div>
</template>
<script setup>
import Map from "ol/Map"
import MousePosition from "ol/control/MousePosition"
import {format as formatAxirs} from "ol/coordinate"
import "ol/ol.css"
defineOptions({
name: "Openlayers"
})
let mapRef = ref()
var map = new Map({
// 设置天地图底图
layers: new LayerGroup({
layers: [
new TileLayer({
source: new XYZ({
url: `http://t2.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${tk}`
})
}),
new TileLayer({
source: new XYZ({
url: `http://t2.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=${tk}`
})
})
]
}),
controls: [
new MousePosition({
coordinateFormat: function (coordinate) {
return formatAxirs(coordinate, "经度:{x} 纬度:{y}", 6)
},
projection: "EPSG:4326",
className: "custom-mouse-position"
})
]
})
onMounted(() => {
//dom加载完毕才设置目标节点,方便子组件获取map实例
map.setTarget(mapRef.value)
})
onUnmounted(() => {
// 销毁map
map.setTarget(null)
map = null
})
// 子组件通过inject获取
provide("openlayers", {
map
})
</script>
<style lang="scss" scoped>
.map {
width: 100%;
height: 100%;
position: relative;
}
</style>
3. 创建视图组件 OlView.vue
<template>
<slot></slot>
</template>
<script setup>
import View from "ol/View"
import {fromLonLat} from "ol/proj"
defineOptions({
name: "OlView"
})
let props = defineProps({
// 设置初始化new View() 参数
defaultOptions: {
type: Object,
default: () => ({})
}
})
let {map} = inject("openlayers")
let view = new View({
zoom: 10,
minZoom: 0,
maxZoom: 14,
constrainResolution: true,
projection: "EPSG:4326", // 默认经纬度坐标
...props.defaultOptions
})
map.setView(view)
provide("view", {
view
})
</script>
<style lang="scss" scoped></style>