🧭 效果演示图
页面加载后,展示地图并提供按钮操作,点击按钮即可在地图上绘制一个椭圆形,并支持清除图层。
🧱 一、项目背景
在 WebGIS 地图可视化场景中,我们经常需要在地图上绘制规则图形(如圆形、椭圆、多边形等),而这些图形往往具备地理意义。
本示例基于:
-
🌐 OpenLayers:用于地图容器与图层渲染
-
🧮 Turf.js:地理空间分析库,用于生成地理椭圆图形
-
🧩 Vue3 + Composition API:现代化前端组件开发范式
📦 二、安装依赖
使用 npm
安装相关依赖:
npm install ol @turf/turf
✨ 三、功能说明
-
使用
turf.ellipse(center, xSemiAxis, ySemiAxis)
创建符合 GeoJSON 标准的椭圆形数据 -
使用
ol.format.GeoJSON
解析数据并在地图上渲染 -
提供按钮点击交互功能:绘制、清除图层
💻 四、完整代码实现
🔧 1. EllipticMap.vue
<!--
* @Author: 彭麒
* @Date: 2025/7/15
* @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+Turf 绘制椭圆形
</div>
</div>
<h4>
<el-button type="primary" size="small" @click="ellipse">绘制椭圆形</el-button>
<el-button type="danger" size="small" @click="clearSource">清除图层</el-button>
</h4>
<div id="vue-openlayers"></div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } 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 VectorSource from 'ol/source/Vector'
import XYZ from 'ol/source/XYZ'
import { fromLonLat } from 'ol/proj'
import { Style, Fill, Stroke } from 'ol/style'
import GeoJSON from 'ol/format/GeoJSON'
import * as turf from '@turf/turf'
// 地图实例
const map = ref<Map | null>(null)
// 矢量数据源
const turfSource = new VectorSource({
wrapX: false
})
// 显示 GeoJSON 数据
const show = (geojsonData: GeoJSON.FeatureCollection) => {
const features = new GeoJSON().readFeatures(geojsonData, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
})
turfSource.addFeatures(features)
}
// 清除图层
const clearSource = () => {
turfSource.clear()
}
// 绘制椭圆
const ellipse = () => {
const center = [-75, 40]
const xSemiAxis = 15
const ySemiAxis = 10
const ellipseFeature = turf.ellipse(center, xSemiAxis, ySemiAxis)
show(ellipseFeature as turf.FeatureCollection)
}
// 初始化地图
const initMap = () => {
const gaodeLayer = new TileLayer({
source: new XYZ({
url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=en&size=1&scl=1&style=7'
})
})
const turfLayer = new VectorLayer({
source: turfSource,
style: new Style({
fill: new Fill({
color: 'rgba(255, 0, 0, 0.2)'
}),
stroke: new Stroke({
width: 2,
color: 'blue'
})
})
})
map.value = new Map({
target: 'vue-openlayers',
layers: [gaodeLayer, turfLayer],
view: new View({
projection: 'EPSG:3857',
center: fromLonLat([-75, 40]),
zoom: 8
})
})
}
// 组件挂载时初始化地图
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;
position: relative;
}
</style>
🧠 五、进阶建议
-
✅ 支持用户交互选择椭圆中心点绘制
-
✅ 支持设置旋转角度、单位(米、千米、英里)
-
✅ 支持导出为 GeoJSON 文件供后端或 GIS 软件使用
-
✅ 多图层管理、多种样式配置
🔚 六、总结
本示例完整展示了如何在 Vue3 项目中,结合 Turf.js 与 OpenLayers 实现一个地理意义下的椭圆图形绘制功能。
你可以以此为基础,继续构建更复杂的图形绘制分析工具,服务于地块管理、资源调度、应急预案等系统开发场景。
如你有任何问题或想进一步优化,欢迎在评论区交流!
如果觉得有帮助,记得 👍点赞 + ❤️收藏 + 💬留言支持我持续更新~