在车辆管理系统中,电子围栏(GeoFence) 是一个非常常见的功能:
当车辆进入或离开指定区域时触发告警。
应用场景包括车队管理、共享出行、物流监控等。
本文将基于 Vue3 + 高德地图 (AMap),实现一个支持 圆形、矩形、多边形围栏 的车辆进出检测,并触发报警。
📌 功能需求
支持 多种围栏类型:圆形、矩形、多边形。
判断车辆是否进入/离开围栏。
记录车辆上一次状态,避免重复报警。
支持 进入报警 / 离开报警 / 双向报警 三种模式。
🛠 实现思路
从
store
获取全局的AMap
实例。遍历车辆绑定的围栏,判断当前车辆位置是否在围栏内。
结合 上一次缓存的状态,判断是否发生“进入”或“离开”事件。
调用
triggerAlarm
方法,执行告警逻辑(比如消息提醒、声音提示、后台记录)。
💻 核心代码实现
import { useGlobalStore } from '../stores/globalInfo'
import { triggerAlarm } from './notify'
// 缓存车辆上一次是否在围栏内
const vehicleFenceState = new Map<string, boolean>()
export function checkVehicleFence(
vehicle: any,
fences: any[],
store: ReturnType<typeof useGlobalStore>
) {
const AMap = store.AMap
if (!AMap) return // AMap 还没准备好
if (!vehicle.latitude || !vehicle.longitude) return
const point = [vehicle.longitude, vehicle.latitude]
// 只筛选绑定了当前车辆的围栏
const relatedFences = fences.filter(fence =>
fence.monitorVehicles?.includes(vehicle.cdtId)
)
relatedFences.forEach(fence => {
if (!fence.enabled) return;//该围栏是否处于暂停状态
let inside = false
// 判断车辆是否在围栏内
if (fence.fenceType === 'circle' && fence.center && fence.fenceRadius) {
const distance = AMap.GeometryUtil.distance(point, fence.center)
inside = distance <= fence.fenceRadius
} else if (fence.fenceType === 'polygon' && fence.coordinates) {
// 多边形围栏
inside = AMap.GeometryUtil.isPointInRing(point, fence.coordinates)
} else if (fence.fenceType === 'rectangle' && fence.coordinates?.length === 2) {
// 矩形围栏:coordinates = [左上角坐标, 右下角坐标]
const [sw, ne] = fence.coordinates
const bounds = new AMap.Bounds(sw, ne)
inside = bounds.contains(point)
}
// 取上一次缓存的状态
const lastInside = vehicleFenceState.get(`${vehicle.cdtId}-${fence.fenceId}`) ?? false
// 进入围栏触发
if (!lastInside && inside && (fence.alarmMode === 'enter' || fence.alarmMode === 'both')) {
triggerAlarm(vehicle, fence, 'enter', store)
}
// 离开围栏触发
if (lastInside && !inside && (fence.alarmMode === 'leave' || fence.alarmMode === 'both')) {
triggerAlarm(vehicle, fence, 'leave', store)
}
// 更新缓存
vehicleFenceState.set(`${vehicle.cdtId}-${fence.fenceId}`, inside)
})
}
📚 关键点解析
缓存机制
使用
Map
记录车辆在某个围栏中的上一次状态,避免重复触发告警。
多种围栏类型支持
圆形:通过
AMap.GeometryUtil.distance
判断距离是否小于半径。多边形:通过
AMap.GeometryUtil.isPointInRing
判断是否在多边形范围内。矩形:利用
AMap.Bounds.contains
判断坐标是否在矩形范围。
报警模式
enter
→ 仅进入触发leave
→ 仅离开触发both
→ 进出均触发
灵活扩展
triggerAlarm
可根据业务需求扩展,比如发送 WebSocket 消息、推送通知、写入数据库。
🎨 效果展示
当车辆进入某个围栏时,立即触发 进入报警。
当车辆离开围栏时,立即触发 离开报警。
围栏被禁用(
enabled = false
)时不会触发任何报警。
✅ 总结
通过本文的实现,我们完成了一个通用的 车辆电子围栏监控 功能:
支持多种围栏类型。
支持进入/离开/双向报警。
使用缓存机制避免重复告警。
可与 Vue3 + 高德地图 无缝集成。
在实际项目中,可以结合 WebSocket 实时定位,实现车辆的 实时监控 + 围栏告警系统 🚀。