🔧 本文将演示如何在 Vue3 项目中使用 OpenLayers 显示多个多边形,并将其导出为
.kml
文件,同时为每个图形自定义颜色样式与名称,适用于地图可视化与地理数据导出场景。
🎯 效果演示
💡 点击按钮可渲染多个多边形,并通过导出按钮将图形保存为
.kml
文件。
🧰 技术栈
技术 | 用途 |
---|---|
Vue 3 + Composition API | 前端框架 |
OpenLayers | 地图渲染与交互 |
Element Plus | UI组件库(按钮) |
file-saver | 文件导出(保存为 KML) |
📦 核心依赖安装
npm install ol file-saver
# 或者使用 pnpm / yarn 安装
🔨 代码实现
✅ 地图初始化
const initMap = () => {
map.value = new Map({
target: 'vue-openlayers',
layers: [new TileLayer({ source: new OSM() }), vectorLayer],
view: new View({
center: [-72.60, 41.4134],
zoom: 9,
projection: 'EPSG:4326'
})
})
}
✅ 显示多边形图层
const showPolygon = () => {
clearDraw()
const features = polygonsData.value.map(({ coord, color, name }) => {
const feature = new Feature({
geometry: new Polygon([coord])
})
feature.setStyle(featureStyle(color[0], color[1]))
feature.setProperties({ name })
return feature
})
source.addFeatures(features)
}
🔍 每个多边形都来自
polygonsData
,支持自定义名称与颜色。
✅ 导出 KML 文件
const exportKML = () => {
const features = source.getFeatures()
const kmlData = new KML().writeFeaturesNode(features)
const kmlString = new XMLSerializer().serializeToString(kmlData)
saveAs(new Blob([kmlString], { type: 'text/plain;charset=utf-8' }), 'polygons.kml')
}
✅ 完整示例代码
<!--
* @Author: 彭麒
* @Date: 2025/7/10
* @Email: 1062470959@qq.com
* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。
-->
<template>
<div class="container">
<div class="w-full flex justify-center flex-wrap">
<div class="font-bold text-[24px]">
在 Vue3 中使用 OpenLayers 显示多个多边形,导出 KML,自定义 name 和 style
</div>
</div>
<h4>
<el-button type="primary" size="small" @click="showPolygon">根据坐标点显示多边形</el-button>
<el-button type="danger" size="small" @click="clearDraw">清除图形</el-button>
<el-button type="info" size="small" @click="exportKML">导出KML</el-button>
</h4>
<div id="vue-openlayers"></div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import VectorLayer from 'ol/layer/Vector'
import OSM from 'ol/source/OSM'
import VectorSource from 'ol/source/Vector'
import Feature from 'ol/Feature'
import { Polygon } from 'ol/geom'
import Fill from 'ol/style/Fill'
import Stroke from 'ol/style/Stroke'
import Style from 'ol/style/Style'
import KML from 'ol/format/KML'
import { saveAs } from 'file-saver'
// 地图对象和数据源
const map = ref(null)
const source = new VectorSource({
wrapX: false,
features: []
})
// 多边形数据(坐标、颜色、名称)
const polygonsData = ref([
{
coord: [
[-72.16, 41.4134],
[-72.0176, 41.3896],
[-72.0643, 41.23],
[-72.2064, 41.2537],
[-72.16, 41.4134]
],
name: 'polygon1',
color: ['red', 'blue']
},
{
coord: [
[-73.16, 41.4134],
[-73.0176, 41.3896],
[-73.0643, 41.23],
[-73.2064, 41.2537],
[-73.16, 41.4134]
],
name: 'polygon2',
color: ['yellow', 'brown']
}
])
// 初始化地图
const initMap = () => {
const osmLayer = new TileLayer({
source: new OSM()
})
const vectorLayer = new VectorLayer({
source: source,
style: new Style({
fill: new Fill({
color: 'transparent'
}),
stroke: new Stroke({
width: 2,
color: 'blue'
})
})
})
map.value = new Map({
target: 'vue-openlayers',
layers: [osmLayer, vectorLayer],
view: new View({
center: [-72.60, 41.4134],
zoom: 9,
projection: 'EPSG:4326'
})
})
}
// 清除图形
const clearDraw = () => {
source.clear()
}
// 自定义样式封装
const featureStyle = (fillColor, strokeColor) => {
return new Style({
fill: new Fill({ color: fillColor }),
stroke: new Stroke({ width: 2, color: strokeColor })
})
}
// 根据坐标数据渲染多边形
const showPolygon = () => {
clearDraw()
const features = polygonsData.value.map(({ coord, color, name }) => {
const feature = new Feature({
geometry: new Polygon([coord])
})
feature.setStyle(featureStyle(color[0], color[1]))
feature.setProperties({ name })
return feature
})
source.addFeatures(features)
}
// 导出为 KML
const exportKML = () => {
const features = source.getFeatures()
const kmlData = new KML().writeFeaturesNode(features)
const kmlString = new XMLSerializer().serializeToString(kmlData)
console.log(kmlString) // 控制台查看
saveAs(new Blob([kmlString], { type: 'text/plain;charset=utf-8' }), 'polygons.kml')
}
// 初始化
onMounted(() => {
initMap()
})
</script>
<style scoped>
.container {
width: 840px;
height: 570px;
margin: 50px auto;
border: 1px solid #42B983;
}
#vue-openlayers {
width: 800px;
height: 400px;
margin: 0 auto;
border: 1px solid #42B983;
}
</style>
📁 自定义多边形数据结构说明
{
coord: [ [...坐标...], [...], ... ], // 坐标点数组(闭合)
name: 'polygon1', // 自定义名称
color: ['fillColor', 'strokeColor'] // 填充色、边框色
}
你可以根据业务需求动态生成 polygonsData,比如从接口返回、GeoJSON 转换、用户绘制等。
🌍 拓展方向建议
-
✅ 增加绘制功能(Draw Polygon)
-
🔁 支持 GeoJSON 与 KML 互相转换
-
🖍 支持颜色选择器配置图层样式
-
🗂 与 Cesium 联动,实现 2D/3D 同步地图
✅ 小结
本文实现了以下功能:
-
✅ 使用 Vue3 + OpenLayers 初始化地图
-
✅ 显示多个多边形,支持不同样式与名称
-
✅ 一键导出为 KML 文件
❤️ 如果对你有帮助
📌 点赞 + 收藏 + 留言支持作者,持续更新高质量地图开发内容!