Vue3 + 高德地图实现车辆电子围栏监控与报警

发布于:2025-08-31 ⋅ 阅读:(20) ⋅ 点赞:(0)

在车辆管理系统中,电子围栏(GeoFence) 是一个非常常见的功能:

  • 当车辆进入或离开指定区域时触发告警。

  • 应用场景包括车队管理、共享出行、物流监控等。

本文将基于 Vue3 + 高德地图 (AMap),实现一个支持 圆形、矩形、多边形围栏 的车辆进出检测,并触发报警。


📌 功能需求

  1. 支持 多种围栏类型:圆形、矩形、多边形。

  2. 判断车辆是否进入/离开围栏。

  3. 记录车辆上一次状态,避免重复报警。

  4. 支持 进入报警 / 离开报警 / 双向报警 三种模式。


🛠 实现思路

  1. store 获取全局的 AMap 实例。

  2. 遍历车辆绑定的围栏,判断当前车辆位置是否在围栏内。

  3. 结合 上一次缓存的状态,判断是否发生“进入”或“离开”事件。

  4. 调用 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)
    })
}

📚 关键点解析

  1. 缓存机制

    • 使用 Map 记录车辆在某个围栏中的上一次状态,避免重复触发告警。

  2. 多种围栏类型支持

    • 圆形:通过 AMap.GeometryUtil.distance 判断距离是否小于半径。

    • 多边形:通过 AMap.GeometryUtil.isPointInRing 判断是否在多边形范围内。

    • 矩形:利用 AMap.Bounds.contains 判断坐标是否在矩形范围。

  3. 报警模式

    • enter → 仅进入触发

    • leave → 仅离开触发

    • both → 进出均触发

  4. 灵活扩展

    • triggerAlarm 可根据业务需求扩展,比如发送 WebSocket 消息、推送通知、写入数据库。


🎨 效果展示

  • 当车辆进入某个围栏时,立即触发 进入报警

  • 当车辆离开围栏时,立即触发 离开报警

  • 围栏被禁用(enabled = false)时不会触发任何报警。


✅ 总结

通过本文的实现,我们完成了一个通用的 车辆电子围栏监控 功能:

  • 支持多种围栏类型。

  • 支持进入/离开/双向报警。

  • 使用缓存机制避免重复告警。

  • 可与 Vue3 + 高德地图 无缝集成。

在实际项目中,可以结合 WebSocket 实时定位,实现车辆的 实时监控 + 围栏告警系统 🚀。


网站公告

今日签到

点亮在社区的每一天
去签到