当前位置: 首页 > news >正文

三维 GIS:电子围栏功能实现(Cesium+Turf + 规则引擎)

三维 GIS:电子围栏功能实现(Cesium+Turf + 规则引擎)

本文以 GIS Gallery 项目中的“电子围栏”为例,梳理一个可运行的三维电子围栏实现:Cesium 负责三维可视化与时间轴驱动,Turf.js 负责所有空间计算,独立规则引擎负责告警判定与去重,三者通过统一的数据流打通。s

本专栏对应工程仓库:

关键代码参考:

数据文件(由后端静态目录对外暴露,前端以/basic-data/...访问):


项目效果展示

下面用几张关键截图把整体效果“串”起来:进入页面后视角会自动对准园区围栏,围栏边界以能量护盾形式拉伸抬升,人员沿多条轨迹同步移动;当目标临近边界或越界时,边界出现局部高亮与告警点位,同时右侧告警列表实时刷新;底部时间轴支持拖拽回放,在任意时间点复盘人员位置与告警分布。



第 1 章 项目背景与整体架构

1.1 电子围栏业务需求、行业应用

“电子围栏”的核心目标是:给定一块空间区域(围栏),对目标(人/车/设备)的位置变化进行实时判定,并在触发约束时形成可追溯的事件记录(告警)。

常见行业场景:

在本 Demo 中,围绕“人员在园区围栏内外的进出”形成两类告警:

1.2 二维围栏 vs 三维围栏差异

二维围栏通常将目标位置视为平面点(经纬度),围栏是 Polygon/MultiPolygon;三维围栏在工程实现上主要差异在于“表达与交互”,而不是空间数学本身:

本 Demo 的空间判定仍以地表二维几何为主:点是否在面内、点到边界距离、缓冲区等,这些由 Turf.js 统一提供。

1.3 整体技术架构图:前端可视化 + 空间计算 + 规则调度

1.4 技术栈选型原因分析


第 2 章 技术前置知识

2.1 Cesium 核心概念:实体、图元、坐标系统、事件监听

2.2 Turf.js 空间计算常用 API:面、点、相交、包含、缓冲区

本 Demo 主要用到的 Turf API:

对应封装在:[geo.js]、[trackGenerator.js]。

2.3 规则引擎基础:规则定义、条件判断、动作执行、表达式语法

在“电子围栏”里,规则引擎可以简化为三类职责:

本 Demo 的规则引擎为“轻量状态机”:

实现位置:[RuleEngine.js]。


第 3 章 开发环境搭建与初始化

3.1 前端工程与依赖

本模块在frontend目录下,典型启动方式(以项目 README 为准):

cdfrontendnpminpmrun dev

关键依赖(见frontend/package.json):

3.2 页面与模块入口

页面装配与首次加载逻辑位于:[ElectronicFenceDemo.vue]:

3.3 Cesium Viewer 初始化与底图

Cesium 创建在:[Main3DView.vue] 的onMounted()内:

初始化视角与“视角重置”共用同一份参数(见“第 4 章”与“第 8 章”)。


第 4 章 Cesium 三维电子围栏绘制模块

4.1 围栏 GeoJSON 加载与合并

围栏数据拉取与预处理在 store 中完成:[fenceStore.js]:

合并逻辑在:[geo.js:mergeFenceFeatures]:

4.2 Cesium 绘制:透明填充 + 高亮边框

围栏绘制在:[Main3DView.vue:loadFence]:

4.2.1 电子围栏“拉伸护盾”渲染(核心:Wall + 动态高度 + 自定义材质)

在三维场景中,只画一个贴地的围栏边线往往不够“直观”。本 Demo 在围栏边界上额外构建了一个“能量护盾”效果:沿围栏边界生成 Wall(垂直面),并在页面进入时从地面逐渐“抬升”,形成“围栏拉伸”的视觉反馈。

实现入口在:[Main3DView.vue:buildFenceVisuals]。

(1) 从围栏面提取边界环(ring)

围栏数据最终会合并为一个 Polygon/MultiPolygon Feature。要在 Cesium 里做 Wall,需要一条“边界线”的点列,因此第一步是从面中提取环坐标:

(2) 将经纬度点列转换为 Cesium 的 wall positions

Cesium 的wall.positionsCartesian3[],本 Demo直接把ring扁平化后用Cartesian3.fromDegreesArray转换:

注意这里 positions 没带 height,因为“拉伸高度”交给minimumHeights/maximumHeights控制。

(3) Wall 的“拉伸高度”计算方式:每个顶点一组 min/max height

Cesium 的 Wall 支持按顶点指定高度数组:

本 Demo 的做法是:

这样每次渲染帧都会重新计算当前“护盾高度”,达到持续抬升的动画效果。高度函数见:[Main3DView.vue:getShieldHeight],核心是一个带缓动的插值:

因此,护盾从 0m 平滑抬升到targetHeight(例如 66m),并在raiseDurationMs(例如 2200ms)内完成。

(4) 自定义材质:用 GLSL fabric 做“扫描流光”

Wall 的材质不是简单纯色,而是自定义的动态 shader(扫描/栅格/能量感):

对应到围栏护盾,Wall 使用的是FenceEnergyShieldMaterial

(5) 同步的边界流光:Polyline + 自定义 Trail 材质

除了 Wall,本 Demo 还在围栏边界上叠加了两条 polyline:

两者和 Wall 共用同一份positions(沿 ring 边界),并且 polyline 设置clampToGround: true,保证贴地观感稳定。

(6) “局部高亮”是如何定位到围栏边界的(与拉伸护盾配套)

当人员接近边界或触发告警时,Demo 会在“离人员最近的围栏边界段”上叠加一段黄色脉冲流光,用于强调危险边界位置:

4.3 缓冲区与允许区:从“视觉层”扩展到“判定层”

围栏系统通常区分两类区域:

本 Demo 中:

实现位置:[geo.js]。

4.4 初始化视角:让业务“开箱即用”

三维围栏 Demo 的体验高度依赖相机视角:

本 Demo 将初始化视角固化为INITIAL_CAMERA_VIEW(经纬度 + 高度 + heading/pitch/roll),在围栏加载后直接setView定位。


第 5 章 实时目标轨迹模拟与点位推送

5.1 多人轨迹数据结构

轨迹文件为 GeoJSON FeatureCollection,每个 Feature 表示一个人的轨迹 LineString:

5.2 统一步长补点:沿线插值采样

为了“即使原始点很少也能平滑行走”,采用“沿线按步长采样”:

  1. 将 LineString 视为一条线
  2. 计算总长度turf.length
  3. stepMeters为步长进行turf.along采样,得到等距点
  4. 末尾补齐终点(避免采样误差导致终点丢失)

实现位置:[trackGenerator.js:sampleAlongLine]。

5.3 时间化轨迹:为每个采样点赋予时间戳

Cesium 的时序插值依赖时间轴,因此需要把“几何点序列”转为“带时间的点序列”:

实现位置:[trackGenerator.js:generateTimedTrackFromLineStringFeature]。

5.4 Cesium 实体:SampledPositionProperty + 轨迹线

在 Cesium 侧,人员点位使用SampledPositionProperty

实现位置:[Main3DView.vue:buildPersonEntity]。

轨迹线使用 polyline(只渲染,不参与判定),并与人员点位共用同一 CustomDataSource。

5.5 行走方向图标:避免终点“突然回头”

人员图标用左右行走 SVG(/roam-left.svg/roam-right.svg),方向计算遵循“优先看上一帧”的原则:

实现位置:[Main3DView.vue:evaluateOnTick]。


第 6 章 Turf.js 空间几何检测(核心算法)

6.1 点是否在围栏内:booleanPointInPolygon

判定入口:[geo.js:isPointInPolygon]:

在规则引擎中会同时计算:

6.2 缓冲区与允许区:buffer

缓冲区/允许区均由 Turf 的buffer()实现,单位统一为 meters。

这一步的工程意义:

6.3 点到围栏边界距离:pointToLineDistance

告警经常需要“离边界多远”的指标,用于:

实现位置:[geo.js:distanceToFenceMeters]。

6.4 易错点:围栏 OUT 与 允许区 OUT 的语义区别

实际项目里最常见的问题之一是:把“离开围栏”与“离开允许区”混在一起。

因此本 Demo 的空间告警分成两条:

实现位置:[RuleEngine.js]。


第 7 章 规则引擎设计与业务规则配置

7.1 输入输出与模块边界

规则引擎的输入(ctx)包含:

输出是一个 violations 数组,每项包含:

7.2 状态机:用“前一帧 vs 当前帧”计算事件

状态存储在lastStateByPersonId中:

对比即可得到事件:

对应实现:[RuleEngine.js:evaluate]。

7.3 规则配置:时间窗、偏移、缓冲、告警开关

配置集中存放在 store:

对应位置:[fenceStore.js:config]。

7.4 去重策略:避免告警风暴

由于 Cesium tick 高频触发,必须提供去重窗口:

对应实现:[RuleEngine.js:shouldEmit]。


第 8 章 三端联动:可视化 + 空间计算 + 规则引擎打通

8.1 数据流从页面到渲染

以“进入页面”流程为例:

  1. [ElectronicFenceDemo.vue]onMounted拉取围栏与轨迹
  2. store 更新fenceGeoJson / tracks
  3. [Main3DView.vue] watch 到变化,重新加载围栏/轨迹实体
  4. Cesium clock tick 时,取每个人当前位置,交给 RuleEngine 判定
  5. violations 写入fenceStore.alarms,同时在 Cesium 中打点渲染告警

8.2 Tick 驱动:以 Cesium Clock 为“唯一时间源”

Tick 逻辑在:[Main3DView.vue:evaluateOnTick]:

8.3 告警列表与地图标识同步

告警入队在:[Main3DView.vue:pushAlarm]:

清空逻辑(列表清空时同步清除地图点位):

8.4 初始化视角与“视角重置”

初始化视角与重置视角应一致,否则用户会觉得“重置按钮不可预期”。

视角参数定义于 store,便于未来做“保存/加载视角配置”或“多预设视角”扩展。

8.5 控制台拾取视角:用于快速迭代体验

Main3DView 在window.__efCesium上暴露了工具:

这套工具适合在“调视角/调 pitch/range”阶段快速迭代,确定后再固化到INITIAL_CAMERA_VIEW


以上内容覆盖了一个三维电子围栏 Demo 的“可运行最小闭环”:数据加载 → 轨迹时间化 → Cesium 时序渲染 → Turf 空间判定 → 规则引擎告警 → UI 列表与地图标注同步。后续若要增强业务深度,可从“告警分级、驻留/临近边界、路径偏离、区域多围栏、多视角预设、告警处理闭环”等方向继续扩展。

http://www.jsqmd.com/news/979805/

相关文章:

  • 区块链与数字货币实验2:图算法与社交网络分析
  • 如何从一名小白成为网安大神(第十天)
  • 2026年天津本地人力荐离婚律师 5位精选 - 本地品牌推荐
  • 大模型容量与上下文窗口:从Token计费到LangGraph工程落地
  • 手把手教你用Arduino解析北斗/GPS模块的NMEA数据(附完整代码)
  • 数据库系统概论期末考试试卷2
  • Logisim新手避坑指南:手把手教你搞定头歌实训的加法器作业(附.circ文件)
  • 2026年防腐激光防护视窗TOP3梯队盘点:防腐激光防护镜/高压激光安全眼镜/高压激光防护玻璃/高压激光防护罩/选择指南 - 优质品牌商家
  • 从跳频到定频:深入蓝牙芯片底层,揭秘射频产线测试的‘固定考场’是如何工作的
  • 从MAC地址到随机数:深入浅出图解UUID的五个版本(v1/v2/v3/v4/v5)生成原理
  • 2026连云港漏电漏水检测维修GEO权威排行榜(TOP5)|消防/自来水/热力+电缆故障一站式解决 - 资讯热点
  • 乌鲁木齐黄金回收哪家靠谱 本地靠谱实体门店汇总 - 润富黄金回收
  • AI工作流重构:非技术岗位的落地实战指南
  • 校园管理毕设实战包:SpringBoot后端+Vue前端+MySQL数据库+答辩PPT+部署视频全齐
  • 分布式事务到底怎么解决?本地消息表、TCC、Saga、Seata 一次讲清楚
  • 从零搭建一个工业监控界面:我用Qt Designer和QSS复刻了经典SCADA组态元素
  • 2026降AI工具实测避坑:这5款怎么组合最好用?附保姆级指南
  • 机器学习生产化落地:从Notebook到高可用模型服务的工程实践
  • Python 爬虫实战项目:资讯数据采集与词云可视化深度分析
  • 多项式回归实战指南:阶数选择、过拟合诊断与工业部署
  • 别再为hiprint表格数据绑定发愁了!Vue3项目实战,手把手教你搞定资产领用单打印
  • Eigen库
  • 如何安全合规地撰写AI技术博文:从业者内容创作指南
  • 恒路通交通杆件:四川公路标识牌、四川单柱式交通标志杆、四川反光标牌、四川反光膜数码打印、四川夜光交通标志牌、四川指路标志选择指南 - 优质品牌商家
  • 嵌入式MongoDB与Spring Boot的测试实践
  • 别再只认升压芯片了!聊聊电荷泵驱动NMOS的那些‘坑’:从原理到PCB布局避坑指南
  • 遗传算法进阶:自适应变异与熵驱动多样性控制
  • Platinum-MD:让复古MiniDisc焕发新生的终极免费开源工具
  • Labelme生成的JSON文件别乱扔!从标注到模型训练的全链路文件管理心得
  • 老项目救星?将传统Spring MVC单体应用,平滑迁移到普元EOS平台的实战记录