一、前言

大家好,这里分享一个 Vue3 + OpenLayers 的小案例
模仿共享单车的电子围栏功能,用户在地图上绘制停泊点时,系统会自动判断该点是否在规划好的电子围栏内(多边形或圆形)。

这个功能在实际项目中有很大应用场景,比如:

  • 共享单车/电动车:判断用户还车是否在规定区域;

  • 物流调度:判断车辆停靠是否在任务范围内;

  • 园区/景区管理:判断人员是否进入限制区域。

下面我们通过一个完整的 Vue3 + OpenLayers 示例来实现。


三、功能效果


二、环境依赖

  • Vue3 + Vite + TypeScript

  • OpenLayers (ol)

  • Element Plus(消息提示用)

安装依赖:

npm install ol element-plus

四、核心实现思路

  1. 初始化地图:加载 OSM 底图,添加一个点图层和一个围栏图层。

  2. 绘制电子围栏:提前设置一个多边形区域和一个圆形区域。

  3. 交互绘制点:通过 Draw 交互让用户选择停泊点。

  4. 判断点是否在围栏内:利用 geometry.intersectsCoordinate(coord) 方法判断坐标是否落在围栏内。

  5. 消息提示:使用 ElMessage 提示用户结果。


五、完整代码示例

<!--* @Author: 彭麒* @Date: 2025/9/4* @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: 模仿共享单车,判断点是否放在规划的电子围栏内</div></div><h4><el-button type="primary" size="small" @click="drawImage">绘制停泊点</el-button></h4><div id="vue-openlayers"></div></div>
</template><script setup lang="ts">
import "ol/ol.css";
import { onMounted, ref } from "vue";
import { Map, View } from "ol";
import Tile from "ol/layer/Tile";
import OSM from "ol/source/OSM";
import LayerVector from "ol/layer/Vector";
import SourceVector from "ol/source/Vector";
import Fill from "ol/style/Fill";
import Feature from "ol/Feature";
import { Point, Circle as OLCircle, Polygon } from "ol/geom";
import Stroke from "ol/style/Stroke";
import Style from "ol/style/Style";
import CircleStyle from "ol/style/Circle";
import Draw from "ol/interaction/Draw";
import { ElMessage } from "element-plus";// 地图对象
const map = ref<Map | null>(null);
const draw = ref<Draw | null>(null);// 点数据源
const source = new SourceVector({wrapX: false,
});// 围栏数据源
const dataSource = new SourceVector({wrapX: false,
});// 多边形数据
const polygonData = [[[116.005, 39.005],[115.006, 40.008],[112.008, 39.008],[116.005, 39.005],],
];// 圆形数据
const circleData = {circleCenter: [115.992, 38.5],circleRadius: 0.5,
};// 显示多边形
const showPolygon = () => {const polygonFeature = new Feature({geometry: new Polygon(polygonData),});dataSource.addFeature(polygonFeature);
};// 显示圆形
const showCircle = () => {const circleFeature = new Feature({geometry: new OLCircle(circleData.circleCenter, circleData.circleRadius),});dataSource.addFeature(circleFeature);
};// 初始化地图
const initMap = () => {const mapLayer = new Tile({source: new OSM(),});const pointLayer = new LayerVector({source: source,style: new Style({image: new CircleStyle({radius: 5,fill: new Fill({color: "#f0f",}),}),}),});const weilan = new LayerVector({source: dataSource,style: new Style({fill: new Fill({color: "transparent",}),stroke: new Stroke({width: 2,color: "red",}),}),});map.value = new Map({target: "vue-openlayers",layers: [mapLayer, weilan, pointLayer],view: new View({projection: "EPSG:4326",center: [115.006, 39.508],zoom: 8,}),});
};// 绘制停泊点
const drawImage = () => {if (!map.value) return;source.clear();// 停止上一次绘制if (draw.value !== null) {map.value.removeInteraction(draw.value);}draw.value = new Draw({source: source,type: "Point",});map.value.addInteraction(draw.value);draw.value.on("drawend", (e) => {if (!map.value) return;map.value.removeInteraction(draw.value as Draw);const coord = (e.feature.getGeometry() as Point).getCoordinates();const arr = dataSource.getFeatures();let flag = 0;for (let i = 0; i < arr.length; i++) {const polygonGeometry = arr[i].getGeometry();if (polygonGeometry?.intersectsCoordinate(coord)) {flag++;}}if (flag) {ElMessage.success({message: "在电子围栏内",duration: 1000,});} else {ElMessage.error({message: "在电子围栏外",duration: 1000,});}});
};onMounted(() => {initMap();showPolygon();showCircle();
});
</script><style scoped>
.container {width: 840px;height: 600px;margin: 50px auto;border: 1px solid #42b983;
}#vue-openlayers {width: 800px;height: 430px;margin: 0 auto;border: 1px solid #42b983;position: relative;
}
</style>


七、总结与扩展

本文实现了一个 基础电子围栏判断功能,在真实业务中可以扩展为:

  • 支持多围栏:一个城市多个禁停区/允许停放区;

  • 围栏编辑:后台管理系统可视化绘制/修改电子围栏;

  • 轨迹回放:判断车辆行驶轨迹是否进入围栏;

  • 性能优化:大规模电子围栏渲染(可用 GeoJSON 数据源)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/921602.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/921602.shtml
英文地址,请注明出处:http://en.pswp.cn/news/921602.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

键盘上面有F3,四,R,F,V,按下没有反应,维修记录

打开游戏&#xff0c;按了好几遍F&#xff0c;结果都没反应&#xff0c;但是左右上下行走是没问题的。一脸懵逼&#xff1f;&#xff1f;&#xff1f;打开键盘测试网页&#xff0c;发现有一列没反应&#xff0c;F1不是&#xff0c;F1我定义了一个快捷键&#xff0c;跟测试冲突了…

8051单片机-成为点灯大师

第三章 成为点灯大师 1. 硬件设计 上一章说到&#xff0c;怎么点亮LED灯&#xff0c;很简单啊&#xff0c;就是把P2口设置成低电平就行了。接下来让我们更进一步&#xff0c;完成LED闪烁、流水灯实验2. 软件设计 2.1 LED闪烁实验 为了使LED闪烁&#xff0c;我们自然而然的想到要…

Rust 日志库完全指南:从入门到精通

GitHub 仓库: https://github.com/zhouByte-hub/rust-study ⭐ 如果这个项目对您有帮助&#xff0c;请给我一个 star&#xff01; 在 Rust 生态系统中&#xff0c;日志处理是一个至关重要的环节。无论是开发小型应用还是大型系统&#xff0c;良好的日志记录都能帮助我们追踪问题…

【科研绘图系列】R语言绘制论文合集图

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 数据准备与过滤 统计分析 可视化绘图 抗药性分析 系统发育分析 加载R包 数据下载 Supp figure 1 Fig 1a Fig 1c Fig 1d Fig 1e Fig 1f Supp figure 3 Supp figure 4 Supp figure 5…

【c++】从三个类的设计看软件架构的哲学思考

从三个类的设计看软件架构的哲学思考 文章目录从三个类的设计看软件架构的哲学思考前言一、OP类&#xff1a;系统工程的安全守护者设计特点设计哲学适用场景现实类比二、VarReviser类&#xff1a;版本控制的严谨管理者设计特点设计哲学适用场景现实类比三、Model类&#xff1a;…

人工智能优化SEO关键词的实战策略

本文聚焦智能技术如何革新关键词优化实践&#xff0c;系统解析提升网站排名的核心路径。重点探讨语义分析如何精准匹配用户意图、长尾词智能挖掘怎样解锁高潜力流量&#xff0c;并详解工具筛选高转化关键词的五大实用策略。通过实战案例说明技术如何突破流量增长瓶颈&#xff0…

【c++】c++第一课:命名空间

文章目录1.C的第⼀个程序2.命名空间2.1 namespace的价值2.2 namespace的定义2.3 命名空间使⽤最新的c标准&#xff08;建议收藏&#xff09; 1.C的第⼀个程序 C兼容C语⾔绝⼤多数的语法&#xff0c;所以C语⾔实现的helloworld依旧可以运⾏&#xff0c;C中需要把定义⽂件代码后…

版本发布流程手册:Release分支规范与Bug分级标准全解析

在软件交付日益高频、用户需求快速迭代的今天&#xff0c;版本发布流程的规范性直接决定了团队的交付效率、产品质量和用户满意度。然而&#xff0c;许多团队仍面临以下痛点&#xff1a; 发布混乱&#xff1a;分支管理随意&#xff0c;代码冲突频发&#xff1b;质量失控&#…

什么是CA根证书

CA 根证书&#xff08;Certificate Authority Root Certificate&#xff09;是 数字证书体系&#xff08;PKI&#xff0c;Public Key Infrastructure&#xff09; 中的核心证书。它有几个关键点&#xff1a;1. 定义 CA&#xff08;Certificate Authority&#xff09;&#xff1…

git push -u origin main 这个-u起什么作用

git push -u origin main 里的 -u 等价于 --set-upstream&#xff0c;它的作用是&#xff1a;&#x1f449; 把本地分支 main 和远程分支 origin/main 绑定&#xff08;建立追踪关系&#xff09;。&#x1f539; 具体效果第一次推送分支时&#xff0c;如果加了 -u&#xff1a;本…

【Unity基础】两个关于UGUI中Text对非英文字体支持的问题

问题1&#xff1a;Unity中为什么UGUI中的Text(Textmeshpro&#xff09;默认不支持非英文字体&#xff0c;而legacy中的text却可以呢&#xff1f; 在Unity中&#xff0c;TextMeshPro&#xff08;TMP&#xff09;默认不支持非英文字体&#xff0c;而Legacy Text支持&#xff0c;主…

碎片时间干活的好手(requestIdleCallback)

&#x1f7e2; What —— 它是什么&#xff1f; requestIdleCallback(callback[, options]) 是浏览器提供的一个 API&#xff0c;用来在主线程空闲时执行一些优先级不高的任务。 它的特点&#xff1a; 异步执行&#xff1a;不会打断关键的渲染、交互、动画。节省性能&#xff1…

第三方网站测评:【WEB应用文件包含漏洞(LFI/RFI)的测试步骤】

文件包含漏洞分为本地文件包含(LFI)和远程文件包含(RFI)两类。LFI允许读取服务器本地文件,RFI可执行远程服务器上的恶意代码。PHP应用中include()、require()等函数未正确过滤用户输入时易产生此类漏洞。 检测URL中可能包含文件的参数,常见特征如下: 参数名包含file、pa…

网络爬虫(web crawler)

文章目录一、什么是网络爬虫二、爬虫工作流程详解第1步&#xff1a;起始点 - URL种子库&#xff08;Seed URLs&#xff09;第2步&#xff1a;大脑 - 调度器&#xff08;Scheduler&#xff09;第3步&#xff1a;双手 - 网页下载器&#xff08;Downloader&#xff09;第4步&#…

redis的高可用(哨兵)

Redis 的主从复制模式下&#xff0c;一旦主节点由于故障不能提供服务&#xff0c;需要人工进行主从切换&#xff0c;同时大量的客户端需要被通知切换到新的主节点上&#xff0c;对于上了一定规模的应用来说&#xff0c;这种方案是无法接受的&#xff0c;于是Redis从2.8开始提供…

安徽某能源企业积极推进运维智能化转型,引入高压配电房机器人巡检系统

在工业自动化与智能化深度融合的当下&#xff0c;机器人技术已成为能源行业提质增效的关键支撑。特别是在配电房这类高压电力核心区域的运维工作中&#xff0c;传统人工巡检不仅面临效率低下、巡检周期长的困境&#xff0c;更因人员直接接触高压设备而存在极高的安全风险。此&a…

数据结构_二叉平衡树

#include <stdio.h> #include <stdlib.h> #define max(a,b) ((a > b)? (a):(b))//平衡二叉树的节点结构 typedef struct AVL_TreeNode{int data; //数据域struct AVL_TreeNode* l;struct AVL_TreeNode* r;int h;//记录树的高度&#xff0c;用于计算平衡因子 }…

扫描件、PDF、图片都能比对!让文档差异无所遁形

智能文档比对系统可精准识别文档差异&#xff0c;解决金融、法律等多方协作场景下的版本混乱、审核低效和合规风险问题&#xff0c;将一份百页文档的人工核对从数小时缩短至3分钟以内。 文档差异比对常见场景有哪些&#xff1f; 每一次文档的修改都可能带来潜在风险&#xff0c…

excel里面店铺这一列的数据结构是2C【uniteasone17】这种,我想只保留前面的2C部分,后面的【uniteasone17】不要

这个结构是&#xff1a; 2C【uniteasone17】只要取前面的 2C 部分&#xff0c;可以用 Excel 的 公式 或者 文本函数 来实现。 方法 1&#xff1a;使用公式提取 假设店铺数据在 A2 单元格&#xff1a; LEFT(A2,FIND("【",A2)-1)&#x1f449; 解释&#xff1a; FIND(“…

四、神经网络的学习(中)

4.3 数值微分梯度法使用梯度的信息决定前进的方向。本节将介绍梯度是什么、有什么性质等内容。4.3.1 导数假如你是全程马拉松选手&#xff0c;在开始的10分钟内跑了2千米。如果要计算此时的奔跑速度&#xff0c;则为2/10 0.2&#xff3b;千米/分&#xff3d;。也就是说&#x…