diff --git a/doc/deploy/environment.md b/doc/deploy/environment.md new file mode 100644 index 0000000..5b6bdc1 --- /dev/null +++ b/doc/deploy/environment.md @@ -0,0 +1,40 @@ +# 机场部署环境 + +## 测试平台 + +### 硬件环境 + +- 服务器 + - 后台 + - IP: 10.100.23.10 + - 用户名: root + - 密码: Huawei@1234567890 + - 前端 + - IP: + - 用户名: + - 密码: + - 前置机(地图代理) + - IP: 10.98.23.81 + - 端口: 8090 + - 用户名: root + - 密码: Huawei@123 + - 前置机(红绿灯代理) + - IP: 10.98.23.111 + - 端口: 8082 + - 用户名: administrator + - 密码: Huawei@123 +- 外部服务 + - 机场车辆位置服务 + - IP: 10.32.38.3 + - 端口: 8090 + - 地图服务 + - URL: http://221.215.103.144:8090/iserver/services/map-QDJC_DT-GX3/rest/maps +- 安全设备 + - VPN + - IP: 222.173.72.76 + - 端口: 19443 + - 用户名: DXYK + - 密码: admin@1234 + - 堡垒机 + - 用户名: dxyk + - 密码: ADMIN@1234 diff --git a/doc/design/后端空间分析与数据存储.md b/doc/design/后端空间分析与数据存储.md new file mode 100644 index 0000000..cab0e15 --- /dev/null +++ b/doc/design/后端空间分析与数据存储.md @@ -0,0 +1,321 @@ +# **机场地面运营实时空间分析与数据管理后端架构方案** + +**执行摘要** + +本报告提出了一套为机场地面运营系统设计的后端架构方案,旨在应对现有SuperMap iServer部署仅提供地图显示服务,且其空间分析和数据存储能力不开放的限制。核心方案围绕构建一个高性能、定制化的后端系统,该系统将独立处理所有关键的实时空间分析任务,包括碰撞检测、超速检测和地理围栏功能,并负责所有地理空间数据的存储与管理。 + +该架构将采用PostgreSQL结合PostGIS作为强大的地理空间数据库,并利用Java Spring Boot框架集成JTS(Java拓扑套件)和GeoTools等专业空间分析库。为了确保检测的准确性,方案还详细阐述了获取道路地理信息并与机场权威GIS地图服务保持持续同步的机制。 + +通过这种明确职责分离的后端中心化方法,系统将实现以下关键优势:显著提升地面运营的安全性,通过实时、精确的检测能力降低事故风险;提高运营效率,优化车辆调度和资源利用;以及构建一个可扩展、易于维护且具备高度控制力的安全关键型系统。 + +**1\. 引言:项目背景与架构挑战** + +**1.1 当前SuperMap iServer的局限性与项目需求** + +用户提出的项目背景明确指出,当前的SuperMap iServer部署仅限于通过Web接口提供地图显示服务,其内置的空间分析和数据存储功能均不开放。这意味着,尽管SuperMap iClient(客户端组件)集成了Turf.js以支持客户端空间分析 1,并且SuperMap iServer本身也支持通过DataFlow服务进行实时数据可视化 3,但核心的服务器端分析和数据存储能力对本项目而言是不可用的。 + +这种“封闭式”的iServer部署模式,虽然在表面上构成了项目实施的限制,但实际上也提供了一个独特的机会。由于无法依赖iServer的内部空间能力,项目被要求开发一个高度专业化、优化且可控的后端系统,专门用于处理安全关键型功能。这种强制性的独立开发,使得核心检测逻辑能够获得更大的自主权,并可能实现比通用GIS服务器组件更优越的性能和安全性。这种架构决策将主要的GIS智能从商业现成产品(COTS)转移到内部开发的、领域特定的解决方案,从而在长期来看,通过利用开源技术,可能实现更强的控制力、更紧密的系统集成以及更具成本效益的效益,尽管初期开发投入会增加。 + +因此,本项目的核心要求是:必须在定制后端独立实现实时碰撞检测、超速检测以及强大的地理空间数据管理功能,以支持机场地面车辆和道路网络。此外,该定制后端还必须能够获取并维护道路地理信息与机场权威GIS地图服务的同步,这对于上述检测功能的准确性至关重要。 + +**1.2 拟议的后端中心化GIS架构概述** + +本方案的架构愿景围绕一个分布式、实时处理的系统。一个专门定制的后端系统将执行所有关键的空间分析并管理地理空间数据,而现有的SuperMap iServer将继续承担其主要的可视化层角色。这种方法明确了职责分离,将后端定位为地面运营的“智能中心”。 + +该架构的关键组成部分包括: + +* **实时数据摄取层:** 负责接收来自地面车辆的连续遥测数据,如位置、速度、航向等。 +* **后端空间分析引擎:** 核心应用逻辑,实现碰撞、超速和地理围栏检测算法。 +* **地理空间数据库:** 用于持久存储静态地理空间数据(如详细的道路网络、机场基础设施)和动态数据(如历史车辆轨迹、生成的警报)。 +* **数据同步模块:** 确保后端道路网络数据与机场权威GIS源保持一致的关键组件,该权威GIS源也同时为SuperMap iServer提供显示数据。 +* **实时通知/推送服务:** 将警报、更新的车辆状态和分析结果推送回SuperMap iServer进行实时可视化,并发送给其他相关的机场运营系统。 + +在实时GIS架构模式中,将客户端可视化与强大的服务器端处理和空间数据库分离是一种普遍且被广泛认可的最佳实践 7。例如,Esri的系统模式明确将“实时数据流和分析”作为核心能力 7,这与我们拟议的后端架构高度契合。Mapsted在机场运营中应用实时位置数据 11的案例也进一步强调了后端强大实时处理和分析能力的重要性。 + +将关键空间分析和数据存储组件与可视化层(SuperMap iServer)解耦,显著增强了整个系统的弹性。即使iServer出现性能问题或停机,核心安全检测功能也能独立运行,确保持续监控。这种分离还允许根据计算需求(例如,车辆数量、分析复杂性)独立扩展分析后端,与iServer上的可视化负载区分开来。iServer的固有局限性促成了这种架构解耦,而这种解耦反过来又实现了独立扩展、更高的容错能力以及对关键安全组件的更大灵活性。这种架构方法与微服务和事件驱动架构等现代企业模式相符,促进了模块化,使得单个组件的开发、部署和维护更加容易,而不会影响整个系统。这对于机场等复杂、安全关键型环境至关重要。 + +**2\. 后端空间分析实现实时检测** + +本节将详细阐述在定制后端实现核心实时检测功能所需的算法、空间库和处理逻辑。重点将放在实现安全关键操作所需的高性能和准确性上。 + +**2.1 实时碰撞检测** + +核心原理在于系统持续监控所有地面车辆的精确位置、速度和航向,并将其当前和预测路径相互比较,同时与预定义的静态障碍物(例如,建筑物、限制区域、停放的飞机)进行比较。目标是识别潜在的空间冲突并及时生成警报。 + +**2.1.1 核心算法与空间库(例如JTS、GeoTools)** + +为实现实时碰撞检测,采用结合快速初步检查和精确几何交叉测试的多阶段方法至关重要。 + +* **粗略阶段检测:** + * **轴对齐包围盒(AABB):** 这是一种简单且计算成本低廉的方法,可快速排除非碰撞情况。如果两个对象的矩形包围盒不重叠,则它们不可能发生碰撞 1。这可作为快速的初始过滤器。 + * **圆形碰撞:** 对于车辆的简化表示或初步的接近度检查,比较两个圆心之间的距离与它们半径之和,可提供快速的碰撞测试 1。 +* **精确阶段检测:** + * **分离轴定理(SAT):** 这是一种更复杂、更强大的算法,用于检测任意两个凸多边形之间的碰撞 1。它适用于更精确的车辆形状表示(例如,矩形足迹)或复杂的、不规则的静态障碍物。后端将使用基于Java的空间库来实现这一点。 + +**Java空间库选择:** + +* **JTS(Java拓扑套件):** 这是一个基础的、开源的Java 2D平面几何库。JTS提供了一套全面的空间谓词(例如,intersects、touches、contains、disjoint)和几何操作(例如,buffer、intersection、union、difference) 15。其健壮性以及对OGC SQL简单要素规范的遵循,使其成为核心几何计算的可靠选择。值得注意的是,PostGIS本身就是基于GEOS构建的,而GEOS是JTS的C++移植版本 15。 +* **GeoTools:** 一个开源的Java GIS工具包,它在JTS的基础上构建,为地理空间数据处理和分析提供了更高层次的框架。它提供了一种符合标准的地理空间数据可视化和处理方法,包括坐标参考系统(CRS)和转换支持,以及高级过滤功能 19。GeoTools集成了JTS作为其底层几何支持 19,并提供了一个灵活的插件系统,可以与Spring Boot应用程序集成 20。 +* **Spatial4j:** 一个通用的空间/地理空间Java库,提供常见的形状、距离计算(包括余弦定律、半正矢、文森特公式用于大地测量距离),并支持从WKT和GeoJSON等格式读写形状。它可以包装JTS几何体以添加日期线环绕支持。该库对于初步的基于距离的过滤或特定的大地测量计算可能很有用,如果机场的坐标系统需要的话。 +* **Esri Geometry API for Java:** 该API使开发人员能够编写用于空间数据分析的自定义应用程序,提供直接通过API创建简单几何体、执行空间操作(联合、差异、相交、裁剪、切割和缓冲区)以及拓扑关系测试的方法。虽然这是一个强大的选择,但其效用取决于机场更广泛的GIS基础设施中现有的Esri生态系统联系。 + +**实施策略:** 对于每辆车辆,将根据其当前位置、速度和航向动态生成一个“受保护区域”(例如,一个围绕其当前位置和预测路径的缓冲区多边形)。碰撞检测将涉及对两个车辆的受保护区域之间,或车辆与静态障碍物之间的交叉测试。 + +**2.1.2 碰撞逻辑与事件处理** + +* **实时数据流:** 车辆位置(纬度、经度、时间戳、速度、航向、车辆ID、车辆类型)将持续流式传输到后端。这需要一个高吞吐量、低延迟的数据摄取机制。 +* **事件驱动处理:** 事件驱动架构是处理连续车辆数据流的理想选择。每个传入的车辆位置更新都将在后端触发一个空间分析事件。 +* **接近度与交叉检查:** + * 收到新的车辆位置后,系统将使用空间索引(例如,PostGIS支持的R树或四叉树,并可被JTS/GeoTools利用)高效识别附近的车辆和静态障碍物(例如,建筑物、限制区域、维护区域、停放的飞机),以缩小详细碰撞检查的候选数量。 + * 然后,将对车辆动态生成的“碰撞盒”(例如,表示车辆物理足迹的多边形或其周围的缓冲区)与识别出的附近实体的碰撞盒之间执行精确的交叉测试(使用JTS/GeoTools几何操作)。 +* **威胁评估:** 除了简单的几何交叉,系统还需要结合其他因素进行更智能的威胁评估: + * **碰撞时间(TTC):** 根据当前速度和航向计算预计的碰撞发生时间。这一概念是空中防撞系统(TCAS)的核心 3。 + * **严重性:** 评估潜在碰撞的严重性(例如,迎头相撞与擦碰,与静止物体碰撞与与另一辆移动车辆碰撞)。 + * **受保护区域调整:** 车辆周围“受保护区域”的大小和形状可以是动态的,根据车辆速度(速度越高,区域越大)、车辆类型(例如,大型车辆需要更大的缓冲区)和环境条件(例如,因雾或雨导致能见度降低)等因素进行调整。 +* **警报生成:** 如果检测到潜在碰撞或危险接近,系统将生成实时警报。这些警报可以是地图显示上的视觉警报(通过SuperMap iServer)、车辆驾驶室内的声光警告,或发送给地面控制人员的通知。 + +对于安全关键型系统,如机场地面运营,对实时性能的严格要求,使得采用优化算法和多阶段检测流程变得必要。单纯地对每个传入的车辆更新执行所有空间分析,可能会导致计算瓶颈,尤其是在处理大量车辆时。因此,必须采用多阶段方法:首先,利用简单、快速的检查(例如,基于距离的过滤、AABB重叠测试)来迅速排除绝大多数非碰撞对。这大大减少了需要进行更昂贵计算的候选数量。随后,将更精确(且计算成本更高)的算法(例如,SAT、JTS交叉测试)仅应用于粗略阶段识别出的少数潜在碰撞候选。这种优化策略对于确保系统的可扩展性至关重要。如果没有这种方法,随着跟踪车辆数量的增加,后端将很快不堪重负,导致警报延迟或遗漏,从而直接危及安全。 + +**2.2 超速检测** + +**2.2.1 空间-时间分析用于速度监控** + +原理是系统将持续比较地面车辆的实时速度与它当前正在行驶的特定道路段的动态限速。这需要将实时车辆数据与地理空间道路网络相结合。 + +* **数据要求:** + * 实时车辆速度,通常来自GPS/GNSS遥测数据。 + * 包含相关限速(包括静态默认值和动态临时值)的全面道路网络数据集。 +* **检测逻辑:** + 1. **车辆在道路网络上的位置:** 对于每个传入的车辆位置,执行空间查询以确定车辆当前所在的道路段,或在定义的容差范围内最近的道路段。这可能涉及点在多边形内测试(如果道路段已缓冲)或使用PostGIS函数(如ST\_Contains或ST\_DWithin结合小缓冲区)进行高效的最近邻搜索 23。 + 2. **限速检索:** 查询后端的地理空间数据库(PostGIS)以检索识别出的道路段适用的限速属性。如果该路段有动态限速,则优先使用动态限速。 + 3. **速度比较:** 比较车辆当前报告的速度与检索到的限速。 + 4. **阈值与持久性:** 实施一个小的容差(例如,允许略微超速几公里/小时)以减少误报。此外,超速警报理想情况下应仅在车辆保持超速状态达到预定义持续时间(例如,3-5秒)后触发,以过滤掉瞬时速度峰值。 +* **时间维度:** 系统需要考虑车辆移动的时间维度。在短时间内跟踪速度有助于识别持续超速,而不是瞬时波动。 + +**2.2.2 与动态限速数据的集成** + +机场环境的动态特性,如滑行道、跑道或服务道路上的限速可能因运营需求(例如,活跃航班、维护、恶劣天气或特殊操作)而频繁变化。如果仅存储静态限速,将导致超速检测不准确,并使系统迅速过时。因此,这些动态信息必须实时或近实时地摄取到我们的后端,并更新到airport\_road\_segments数据模型中。道路网络数据模型(详见第3.2节)必须设计为能够适应限速的动态属性,可能包括有效期(开始/结束时间)或活动限制的标志。这种对道路网络属性(如限速)的实时更新能力,能够确保超速检测与当前运营条件和安全协议完全一致。这强调了拥有不仅仅是空间数据,而是拥有最新且与上下文相关的空间数据的重要性,这对于安全和效率至关重要。 + +**2.3 地理围栏用于运营区域和警报** + +**2.3.1 定义与管理地理围栏** + +地理围栏的目的是在机场内的各种运营区域(例如,跑道、滑行道、停机坪区域、限制进入区、维护区、飞机停机位、加油站)周围定义虚拟地理边界(多边形)。当车辆进入或离开这些区域时,这些地理围栏将作为特定警报或行动的触发器。 + +这些地理围栏的几何形状及其相关规则(例如,允许的车辆类型、区域内的特定限速、指定的警报接收者、基于时间的限制)将持久存储在PostGIS数据库中。一个专用的管理界面(可以是后端管理工具的一部分,也可以是独立的Web应用程序)将允许授权的机场人员根据运营需求的变化轻松创建、修改、激活和停用地理围栏。 + +**2.3.2 实时地理围栏进入/退出检测** + +原理是对于每个传入的实时车辆位置,系统将对所有相关的活动地理围栏几何体执行点在多边形内测试。 + +* **空间查询:** 利用高效的PostGIS空间函数,如ST\_Contains或ST\_Intersects 24,来确定车辆当前位置是否落在任何已定义的地理围栏内。对地理围栏几何体进行空间索引将确保快速的查询性能。 +* **事件触发:** 根据空间查询的结果和车辆先前已知的位置,系统将触发特定事件: + * **进入事件:** 当车辆从地理围栏外部移动到内部时。 + * **退出事件:** 当车辆从地理围栏内部移动到外部时。 + * **停留/驻留事件:** 如果车辆在特定地理围栏内停留时间过长或未经授权(例如,检测未经授权的怠速或在限制区域内长时间停留)。 +* **警报生成:** 一旦触发事件,系统将根据地理围栏的配置规则生成特定警报或启动预定义操作。这可能包括立即通知地面控制人员、记录事件以供审计,或触发与该区域相关的特定限速执行检查。 + +当地理围栏与强大的后端集成时,它将转变为一个强大的、多功能的运营智能工具 26。它能够实现超越简单边界警报的多种关键功能。例如,可以根据车辆当前所在的地理围栏区域动态应用或修改安全规则,如特定的限速或碰撞避免参数(例如,跑道与停机坪区域有不同的规则)。它还能自动监控合规性,例如自动记录车辆在限制区域的存在,对未经授权的进入触发警告,或对某些区域强制执行特定的操作协议。此外,地理围栏可以监控运营效率,例如跟踪车辆在特定运营区域(如装载区、维护区)的停留时间,以识别瓶颈、优化工作流程并改进资源分配。这些能力,通过服务器端空间分析实现,能够更精细、更具上下文感知能力地自动化应用安全和运营规则,从而全面提升机场地面运营管理和态势感知能力。地理围栏从静态地图数据演变为生成动态、可操作的运营智能,使系统从单纯的可视化转变为主动、自动化的决策支持和执行,显著提升了安全性和效率。 + +**3\. 强大的地理空间数据存储用于机场运营** + +本节将详细阐述所选的数据库技术和地理空间数据模型的设计,它们是支持实时空间分析需求的基础。 + +**3.1 数据库选择:PostgreSQL与PostGIS** + +PostgreSQL结合PostGIS扩展,是领先的开源关系型数据库管理系统,专为强大且高性能的地理空间数据管理而设计。其能力非常适合实时机场地面运营的需求。 + +* **主要优势:** + * **全面的空间数据类型:** PostGIS扩展了PostgreSQL,使其能够原生支持各种开放地理空间联盟(OGC)几何类型,包括点、线、多边形和多几何体,支持2D和3D 24。这使得能够精确建模车辆、道路网络和运营区域。 + * **高级空间索引:** PostGIS提供了高效的空间索引机制,如GiST(通用搜索树)索引 23。这些索引对于在复杂空间查询中快速缩小搜索范围至关重要(例如,查找特定区域内的所有车辆,或识别相交的几何体),这对于碰撞和超速检测的实时性能至关重要。 + * **丰富的空间函数:** PostGIS提供了庞大的空间函数库,用于分析、测量和处理。这包括ST\_DWithin(用于索引距离搜索)、ST\_Intersects(用于检查几何重叠)、ST\_Buffer(用于创建受保护区域)、ST\_Length(用于计算距离)和ST\_Area(用于计算面积) 16。后端应用程序直接调用这些函数来执行其空间分析逻辑。 + * **可扩展性与可靠性:** PostgreSQL是一个成熟、高度可扩展且可靠的数据库系统,在高事务环境中得到了验证。它能够处理大量的实时数据摄取和并发查询,使其适用于连续的车辆遥测流 25。 + * **开源与社区支持:** 作为开源项目,PostGIS受益于庞大活跃的开发者社区、广泛的文档,并且没有许可费用,这降低了总拥有成本并提供了定制的灵活性 24。 + * **无缝Spring Boot集成:** PostgreSQL和PostGIS通过Spring Data JPA和Hibernate Spatial与Java Spring Boot应用程序集成得非常好。Hibernate Spatial提供了Java实体与PostGIS几何类型之间必要的映射,允许开发人员使用熟悉的JPA范式与空间数据交互。 + +对于机场地面运营这类安全关键型应用,仅仅具备“基本”空间能力是远远不够的。PostGIS作为一个成熟、高性能且功能丰富的开源解决方案,能够专门满足复杂的系统需求。它处理复杂几何体、提供高级空间索引(对实时查询性能至关重要)以及通过Hibernate Spatial与Java后端无缝集成的能力,使其成为构建定制化安全关键型系统的最佳选择。它提供了精确检测所需的精度和速度。选择PostGIS符合后端采用开源技术战略,这可以显著减少供应商锁定,并利用庞大活跃的开发者社区进行持续支持和创新。这为系统提供了可持续且灵活的基础。 + +**3.2 机场运营地理空间数据模型设计** + +目标是在PostgreSQL/PostGIS中设计一个全面且高效的数据模型,能够存储所有必要的静态(道路网络、运营区域)和动态(实时车辆遥测、警报)地理空间数据。该模型必须有助于快速查询和分析,以支持碰撞、超速和地理围栏检测。 + +**拟议的表和关键属性:** + +* **airport\_road\_segments 表:** + * **目的:** 存储所有机场道路段的几何表示、其属性以及用于网络分析(例如,路径规划、寻路)的拓扑链接。 + * **关键列:** + * id (主键, UUID/BIGINT):每个道路段的唯一标识符。 + * geom (GEOMETRY(LINESTRING, 4326/SRID)):表示道路段的实际几何线串。SRID 4326 (WGS84) 是全球坐标的常用选择。 + * name (TEXT):道路段的描述性名称或标识符(例如,“Alpha滑行道”,“3号服务道”)。 + * segment\_type (TEXT):道路分类(例如,'跑道'、'滑行道'、'停机坪道路'、'服务道'、'维护路径')。 + * max\_speed\_static (NUMERIC):该路段的默认或常规限速(例如,单位为公里/小时)。 + * max\_speed\_dynamic (NUMERIC):一个可为空的字段,用于存储该路段*当前、临时*的动态限速,当其激活时覆盖max\_speed\_static。 + * is\_one\_way (BOOLEAN):指示路段是否为单向的标志,对准确的路径规划和方向检查至关重要。 + * surface\_type (TEXT):例如,'沥青'、'混凝土'、'碎石'。 + * from\_node\_id, to\_node\_id (BIGINT):外键,链接到单独的network\_nodes表(此处未明确详细说明,但暗示用于网络拓扑和路由算法,如pgRouting 29)。 + * updated\_at (TIMESTAMP):上次修改的时间戳,对于动态属性尤其重要。 + * **与检测的相关性:** 为超速检测(限速)、碰撞检测(如果道路靠近建筑物,则为静态障碍物)以及地理围栏提供基础道路网络和上下文信息。 +* **operational\_zones 表:** + * **目的:** 存储机场内所有地理围栏运营区域的几何边界及其相关规则。 + * **关键列:** + * id (主键, UUID/BIGINT):每个区域的唯一标识符。 + * geom (GEOMETRY(POLYGON, 4326/SRID)):地理围栏的多边形边界。 + * zone\_name (TEXT):描述性名称(例如,“09R-27L跑道”,“A区限制区域”,“1号加油区”)。 + * zone\_type (TEXT):区域分类(例如,'跑道'、'滑行道'、'限制区'、'维护区'、'停车区')。 + * allowed\_vehicle\_types (TEXT):允许进入此区域的车辆类型数组。 + * min\_speed\_limit (NUMERIC):该区域内的最低限速(如果适用)。 + * max\_speed\_limit (NUMERIC):该区域内的最高限速。 + * is\_restricted\_access (BOOLEAN):指示是否为限制进入区域的标志。 + * active\_period\_start, active\_period\_end (TIMESTAMP):区域规则的激活和失效时间。 + * alert\_level (ENUM):当触发事件时应生成的警报级别(例如,'信息'、'警告'、'关键')。 + * contact\_groups (TEXT):当触发警报时应通知的联系组列表。 + * **与检测的相关性:** 地理围栏的核心,支持基于上下文的规则应用。 +* **vehicle\_tracks 表:** + * **目的:** 存储历史实时车辆位置,用于回放、分析和审计。 + * **关键列:** + * id (主键, UUID/BIGINT)。 + * vehicle\_id (外键)。 + * timestamp (TIMESTAMP):记录时间。 + * geom (GEOMETRY(POINT, 4326/SRID)):车辆位置点。 + * speed\_kmh (NUMERIC):记录时的速度。 + * heading\_deg (NUMERIC):记录时的航向。 + * status (TEXT):车辆状态(例如,'移动中'、'停车'、'怠速')。 + * **与检测的相关性:** 用于历史分析和轨迹重建。 +* **realtime\_vehicle\_status 表(或内存缓存):** + * **目的:** 存储所有跟踪车辆的最新状态,用于实时分析。 + * **关键列:** + * vehicle\_id (主键)。 + * last\_seen\_timestamp (TIMESTAMP):最后一次接收到位置更新的时间。 + * current\_geom (GEOMETRY(POINT, 4326/SRID)):车辆当前位置。 + * current\_speed\_kmh (NUMERIC)。 + * current\_heading\_deg (NUMERIC)。 + * current\_zone\_id (外键,链接到operational\_zones):车辆当前所在的运营区域ID。 + * is\_overspeeding (BOOLEAN):是否超速的标志。 + * is\_collision\_risk (BOOLEAN):是否存在碰撞风险的标志。 + * last\_alert\_type (TEXT):上次生成的警报类型。 + * **与检测的相关性:** 实时检测的主要数据源,持续更新。 +* **alerts\_log 表:** + * **目的:** 记录所有生成的警报,用于审计、报告和事后分析。 + * **关键列:** + * id (主键, UUID/BIGINT)。 + * alert\_timestamp (TIMESTAMP):警报生成时间。 + * vehicle\_id (外键)。 + * alert\_type (ENUM: 'OVERSPEED', 'COLLISION\_RISK', 'ZONE\_ENTRY', 'ZONE\_EXIT'):警报类型。 + * location\_geom (GEOMETRY(POINT, 4326/SRID)):警报发生时的位置。 + * details (JSONB):警报的详细信息(例如,涉及的另一辆车ID,超速数值,进入/退出区域的名称)。 + * resolved\_status (BOOLEAN):警报是否已解决。 + * resolved\_by (TEXT):解决警报的人员或系统。 + * **与检测的相关性:** 审计跟踪,安全系统性能监控。 + +**索引策略:** 为所有几何列创建空间索引(例如,CREATE INDEX geom\_idx ON table USING GIST(geom);)以确保最佳查询性能。同时,对用于外键和频繁查询的属性创建非空间索引。 + +**4\. 道路地理信息获取与同步** + +**4.1 数据获取策略** + +* **初始数据摄取:** 获取初始道路网络数据的方法包括: + * 现有机场GIS数据导出(例如,Shapefile、GeoJSON、WKT)。 + * 如果权威数据源提供WFS(Web要素服务),则通过WFS获取(WMS提供的是图像,而非矢量数据)。 + * 商业机场地图数据库(AMDB)提供商 30。 + * ICAO GIS数据产品 31。 +* **数据质量与预处理:** 强调数据清洗、拓扑验证以及属性丰富(例如,添加限速、单向标志,如果原始数据中没有)。 + +**4.2 与GIS地图服务的同步机制** + +核心挑战在于保持后端权威道路数据与SuperMap iServer用于显示的数据之间的一致性。由于iServer的存储是封闭的,这意味着权威数据存在于其他地方(例如,机场中央GIS)。因此,同步的目标是确保后端的数据与iServer所消费的权威GIS源保持一致。 + +**拟议的解决方案:事件驱动同步** + +1. **权威数据源识别:** 明确机场道路网络数据的主要来源(例如,由机场管理部门维护的企业级GIS)。 +2. **变更数据捕获(CDC):** 实施一种机制来检测权威GIS道路网络数据中的变更(新增、修改、删除)。这可以通过以下方式实现: + * **数据库触发器/日志:** 如果权威GIS使用PostgreSQL等数据库,可利用数据库触发器或逻辑复制来捕获变更。 + * **GIS系统API/Webhooks:** 如果权威GIS提供用于数据更新的API或Webhooks(例如,Esri ArcGIS Enterprise),则订阅这些事件。 + * **定时导出/比较:** 虽然实时性较差,但可作为备用方案:定期从权威数据源导出数据,并与后端数据集进行比较以识别差异。 +3. **后端更新流程:** + * 一旦检测到变更,后端中专门的同步服务将摄取更新的地理空间数据。 + * 该服务将把变更应用到PostGIS中的airport\_road\_segments表,确保数据完整性并更新相关属性(例如,max\_speed\_dynamic、is\_one\_way)。 + * 此过程应具有事务性,以防止数据损坏。 +4. **SuperMap iServer更新(可视化层):** + * 由于iServer仅提供地图服务,假定它从相同的权威GIS源或同步副本消费数据。 + * 同步过程确保后端的数据与iServer正在消费的源保持一致。如果iServer直接从权威源消费WMS/WFS,那么我们的后端同步确保了内部一致性。 + * 如果iServer需要直接推送更新以显示其地图图层(例如,用于临时限速等动态元素),后端可以利用SuperMap iServer的DataFlow服务(WebSocket)进行实时可视化更新 3。这将仅推送变更的*视觉表示*,而非用于分析的底层数据。 + +**数据一致性与延迟:** 目标是实现关键道路网络属性(例如,动态限速、临时封闭)的近实时同步,以确保后端的分析基于最新的运营实际情况。这种同步的延迟直接影响检测系统的准确性和安全性。 + +数据同步并非一次性导入,而是一个持续且至关重要的过程。实时检测的准确性,直接取决于道路网络数据的实时性。这要求建立强大的变更数据捕获机制和自动化更新管道,以确保后端对“世界”的认知与运营实际情况保持一致,从而直接影响安全性和效率。 + +**5\. 实时数据推送与可视化** + +**5.1 后端到SuperMap iServer的数据推送** + +后端系统需要将实时分析结果(例如,车辆位置、碰撞警报、超速警告、地理围栏闯入)推送到SuperMap iServer,以便在地图界面上进行可视化。 + +* **机制:** SuperMap iServer提供了基于WebSocket协议的DataFlow服务,可实现客户端与服务器之间的低延迟、全双工、双向通信,并广播分析结果给客户端 3。这是后端将动态数据推送到iServer进行显示的理想机制。 +* **数据格式:** 推送的数据可能采用SuperMap iClient易于消费的格式,例如GeoJSON,SuperMap iClient JavaScript支持GeoJSON用于高效点图层和数据流图层 1。 +* **负载内容:** 推送的数据将包括车辆ID、最新位置、速度、航向以及指示碰撞风险、超速状态或地理围栏交互的标志/属性。 + +**5.2 客户端可视化与警报** + +前端应用程序将利用SuperMap iClient JavaScript,通过DataFlow服务消费从后端推送的实时数据。 + +* **动态图层渲染:** iClient支持实时数据可视化,包括动态监控和大量点数据的高效渲染(例如,10,000+辆汽车的实时位置,1秒内可渲染多达100万个点) 1。这使得能够流畅地显示移动车辆和动态警报。 +* **警报视觉提示:** 客户端地图将动态更新车辆符号(例如,颜色变化、闪烁图标)以指示警报状态(例如,碰撞风险为红色,超速为黄色)。当发生闯入时,地理围栏边界可以高亮显示。 +* **用户界面集成:** 警报还可以触发弹出通知、声音警报,或与其他机场运营仪表盘集成。 +* **有限的客户端分析(Turf.js):** 虽然主要的空间分析由后端驱动,但SuperMap iClient与Turf.js的集成提供了一些客户端空间分析能力(例如,基本的空间、拓扑、测量操作) 1。这可用于显示地图上非常轻量级、非安全关键的视觉计算或用户发起的查询,但不能用于核心检测逻辑。 + +尽管后端执行“思考”任务,但可视化层是运营人员获取态势感知的关键界面。实时数据和警报的有效可视化对于人工决策至关重要。这要求低延迟的数据推送、清晰的符号系统和直观的用户界面,以便将复杂的空间分析转化为可操作的信息,供操作员使用。安全系统的成功不仅取决于检测能力,还在于有效传达威胁。 + +**6\. 结论与建议** + +本报告提出的后端架构方案,通过构建一个独立且功能强大的后端系统,有效地解决了SuperMap iServer在机场地面运营中空间分析和数据存储能力不开放的挑战。这种职责明确分离的架构,利用PostgreSQL与PostGIS的强大地理空间数据管理能力,以及Java Spring Boot与JTS/GeoTools在实时空间分析方面的优势,为机场地面运营提供了安全、高效且可扩展的解决方案。 + +**主要结论:** + +* **定制化后端至关重要:** 面对iServer的限制,构建一个专门的后端系统是实现实时碰撞检测、超速检测和地理围栏功能的唯一可行路径。这种定制化方法允许对安全关键逻辑进行精细控制和优化。 +* **PostGIS是理想的地理空间骨干:** PostGIS凭借其丰富的数据类型、高效的空间索引和强大的空间函数,成为处理机场复杂地理空间数据的最佳选择,能够满足实时分析对精度和速度的严格要求。 +* **数据同步是持续的运营要求:** 确保后端道路网络数据与权威GIS源的持续同步是系统准确性和安全性的基石。任何数据滞后都可能导致检测结果的失效。 +* **可视化层是态势感知的关键:** 尽管分析在后端进行,但通过SuperMap iServer进行清晰、实时的可视化是操作员理解并响应威胁的关键。 + +**建议:** + +1. **优先后端空间分析引擎的详细设计与实现:** 集中资源,使用JTS和GeoTools库,设计并实现高效的碰撞和超速检测算法,包括粗略阶段和精确阶段的优化。 +2. **建立健壮的道路网络数据治理与同步管道:** 明确权威道路数据源,并实施可靠的变更数据捕获(CDC)机制,确保后端数据与权威源的近实时一致性。 +3. **开发全面的测试协议:** 针对各种碰撞、超速和地理围栏场景进行严格的模拟和实地测试,验证系统在不同运营条件下的保护能力和误报率。 +4. **考虑分阶段部署:** 从一个试点区域或特定车辆类型开始,逐步扩展系统的覆盖范围和功能,以降低风险并验证系统性能。 +5. **探索与更多机场系统的集成:** 除了车辆跟踪硬件,还可以考虑与航空交通管制(ATC)系统、机场运营数据库等进行数据集成,以获取更丰富的数据输入,实现更全面的态势感知。 +6. **评估引入机器学习模型的潜力:** 长期来看,可以研究利用机器学习模型进行预测性分析,例如预测潜在的交通拥堵、高风险区域或车辆行为异常,从而实现更主动的安全管理。 + +#### **Works cited** + +1. SuperMap iClient JavaScript 10i, accessed June 4, 2025, [https://iclient.supermap.io/10.0.1/web/index.html](https://iclient.supermap.io/10.0.1/web/index.html) +2. SuperMap iClient JavaScript 11i(2023), accessed June 4, 2025, [https://iclient.supermap.io/11.1.0/web/index.html](https://iclient.supermap.io/11.1.0/web/index.html) +3. SuperMap iServer Streaming Data Technology \- SuperMap, accessed June 4, 2025, [https://www.supermap.com/en-us/news/?82\_670.html](https://www.supermap.com/en-us/news/?82_670.html) +4. accessed January 1, 1970, [https://www.supermap.com/zh-cn/a/product/gis-iserver-2024.html\#nav-list](https://www.supermap.com/zh-cn/a/product/gis-iserver-2024.html#nav-list) +5. Data flow service \- SuperMap iClient, accessed June 4, 2025, [https://iclientdev.supermap.io/iserver/help/html/en/iS/use\_iserver/usedataflow/dataflow.htm](https://iclientdev.supermap.io/iserver/help/html/en/iS/use_iserver/usedataflow/dataflow.htm) +6. Terminal GIS for Mobile Overview and Features \- SuperMap, accessed June 4, 2025, [https://www.supermap.com/en-us/list/?157\_1.html](https://www.supermap.com/en-us/list/?157_1.html) +7. Empowering IT Professionals with Architecture Patterns, Practices ..., accessed June 4, 2025, [https://www.esri.com/about/newsroom/arcnews/empowering-it-professionals-with-architecture-patterns-practices-for-arcgis](https://www.esri.com/about/newsroom/arcnews/empowering-it-professionals-with-architecture-patterns-practices-for-arcgis) +8. Real-Time Visualization & Analytics | Gain Insights from Big Data & IoT, accessed June 4, 2025, [https://www.esri.com/en-us/capabilities/real-time/overview](https://www.esri.com/en-us/capabilities/real-time/overview) +9. Web GIS: Revolutionizing RealTime Spatial Data Access \- Satpalda, accessed June 4, 2025, [https://satpalda.com/web-gis-revolutionizing-realtime-spatial-data-access/](https://satpalda.com/web-gis-revolutionizing-realtime-spatial-data-access/) +10. GIS Platform | On‑Premise | 2GIS Documentation, accessed June 4, 2025, [https://docs.2gis.com/en/on-premise/architecture/services/gisplatform](https://docs.2gis.com/en/on-premise/architecture/services/gisplatform) +11. How Location Data Improves Airport Operations in 2025? \- Mapsted, accessed June 4, 2025, [https://mapsted.com/blog/how-location-data-improves-airport-operations](https://mapsted.com/blog/how-location-data-improves-airport-operations) +12. 2D collision detection \- Game development \- MDN Web Docs, accessed June 4, 2025, [https://developer.mozilla.org/en-US/docs/Games/Techniques/2D\_collision\_detection](https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection) +13. jriecken/sat-js: A simple JavaScript library for performing 2D collision detection \- GitHub, accessed June 4, 2025, [https://github.com/jriecken/sat-js](https://github.com/jriecken/sat-js) +14. Real-Time Collision Detection (The Morgan Kaufmann Series in Interactive 3-D Technology), accessed June 4, 2025, [https://www.amazon.com/Real-Time-Collision-Detection-Interactive-Technology/dp/1558607323](https://www.amazon.com/Real-Time-Collision-Detection-Interactive-Technology/dp/1558607323) +15. JTS Topology Suite \- OSGeo, accessed June 4, 2025, [https://www.osgeo.org/projects/jts/](https://www.osgeo.org/projects/jts/) +16. JTS | Features, accessed June 4, 2025, [https://locationtech.github.io/jts/jts-features.html](https://locationtech.github.io/jts/jts-features.html) +17. Geometry (org.locationtech.jts:jts-core 1.20.0 API), accessed June 4, 2025, [https://locationtech.github.io/jts/javadoc/org/locationtech/jts/geom/Geometry.html](https://locationtech.github.io/jts/javadoc/org/locationtech/jts/geom/Geometry.html) +18. Libraries \- OSGeo, accessed June 4, 2025, [https://www.osgeo.org/choose-a-project/development/libraries/](https://www.osgeo.org/choose-a-project/development/libraries/) +19. GeoTools \- OSGeo, accessed June 4, 2025, [https://www.osgeo.org/projects/geotools/](https://www.osgeo.org/projects/geotools/) +20. Application Integration — GeoTools 33-SNAPSHOT User Guide, accessed June 4, 2025, [https://docs.geotools.org/stable/userguide/welcome/application.html](https://docs.geotools.org/stable/userguide/welcome/application.html) +21. How to Use GeoTools — GeoTools 34-SNAPSHOT User Guide, accessed June 4, 2025, [https://docs.geotools.org/latest/userguide/welcome/use.html](https://docs.geotools.org/latest/userguide/welcome/use.html) +22. Traffic collision avoidance system \- Wikipedia, accessed June 4, 2025, [https://en.wikipedia.org/wiki/Traffic\_collision\_avoidance\_system](https://en.wikipedia.org/wiki/Traffic_collision_avoidance_system) +23. Return all results within a 30km radius of a specific lat/long point? \- GIS StackExchange, accessed June 4, 2025, [https://gis.stackexchange.com/questions/77072/return-all-results-within-a-30km-radius-of-a-specific-lat-long-point](https://gis.stackexchange.com/questions/77072/return-all-results-within-a-30km-radius-of-a-specific-lat-long-point) +24. PostGIS, accessed June 4, 2025, [https://postgis.net/](https://postgis.net/) +25. Applications of PostGIS and PostgreSQL in Modern Geospatial Analysis \- VE3, accessed June 4, 2025, [https://www.ve3.global/applications-of-postgis-and-postgresql-in-modern-geospatial-analysis/](https://www.ve3.global/applications-of-postgis-and-postgresql-in-modern-geospatial-analysis/) +26. Geofencing in Retail: Implementation Guide for Tech SaaS Product \- MobiDev, accessed June 4, 2025, [https://mobidev.biz/blog/geofencing-in-retail-implementation-guide-for-tech-saas-products](https://mobidev.biz/blog/geofencing-in-retail-implementation-guide-for-tech-saas-products) +27. Geofencing Time and Attendance \- TimeTrex, accessed June 4, 2025, [https://www.timetrex.com/blog/geofencing-time-and-attendance](https://www.timetrex.com/blog/geofencing-time-and-attendance) +28. Chapter 5\. Spatial Queries \- PostGIS, accessed June 4, 2025, [https://postgis.net/docs/using\_postgis\_query.html](https://postgis.net/docs/using_postgis_query.html) +29. Vehicle Routing with PostGIS and Overture Data | Crunchy Data Blog, accessed June 4, 2025, [https://www.crunchydata.com/blog/vehicle-routing-with-postgis-and-overture-data](https://www.crunchydata.com/blog/vehicle-routing-with-postgis-and-overture-data) +30. Geospatial Data & Imagery \- L3Harris, accessed June 4, 2025, [https://www.l3harris.com/all-capabilities/geospatial-data-imagery](https://www.l3harris.com/all-capabilities/geospatial-data-imagery) +31. ICAO GIS Aviation Data, accessed June 4, 2025, [https://www.icao.int/Aviation-GIS-Navigation-Data/Pages/default.aspx](https://www.icao.int/Aviation-GIS-Navigation-Data/Pages/default.aspx) +32. SuperMap iClient JavaScript 10i(2020) \-a cloud GIS web client development platform, accessed June 4, 2025, [https://iclient.supermap.io/10.1.1/en/web/index.html](https://iclient.supermap.io/10.1.1/en/web/index.html) \ No newline at end of file diff --git a/doc/design/机场预警系统架构设计方案.md b/doc/design/机场预警系统架构设计方案.md new file mode 100644 index 0000000..eb0c059 --- /dev/null +++ b/doc/design/机场预警系统架构设计方案.md @@ -0,0 +1,232 @@ +# **机场车辆碰撞预警系统:实时空间分析的架构设计** + +## **1\. 概述** + +本报告旨在为机场车辆碰撞预警系统提供一个优化的架构设计方案,核心在于解决实时碰撞预警、超速预警和电子围栏预警等计算与处理逻辑应置于前端(Web)还是后端(Java Spring Boot)的关键决策。鉴于该系统固有的安全关键性,对高可靠性、一致性和可扩展性的要求至关重要。经过深入分析,本报告强烈建议采用以后端为中心的架构,充分利用超图iServer强大的实时流数据处理和空间分析能力。 + +这种架构方案将带来多重显著优势:首先,它确保了预警生成过程的精确性和一致性,最大限度地减少了误报和漏报;其次,它能够高效处理海量的实时地理空间数据,并支持未来车辆数量和数据复杂度的增长;最后,通过将复杂的计算逻辑集中在后端,可以显著简化前端开发,从而实现更低的开发难度和更短的开发周期,最终交付一个高性能、高可靠且易于维护的机场车辆碰撞预警系统。 + +## **2\. 项目背景与架构困境** + +机场车辆碰撞预警系统旨在通过实时监测与分析,为机场地面车辆提供即时、准确的碰撞、超速及电子围栏越界警告,以避免事故发生。该系统在机场运营环境中扮演着至关重要的角色,任何故障都可能导致严重的安全隐患、运营中断和经济损失。 + +该系统的前端将采用Web技术开发,主页利用超图GIS服务器产品iServer提供的在线地图服务,并通过iClient for OpenLayers进行地图展示和交互。后端则基于Spring Boot框架进行Java开发,负责数据处理和业务逻辑。 + +当前面临的核心架构选择问题是:将碰撞预警、超速预警、电子围栏预警等核心计算和处理逻辑置于前端Web应用(SuperMap iClient)还是后端Java Spring Boot服务?用户提出,前端可能因直接访问GIS服务实时地图数据而具备更好的实时性,但这与将主要业务逻辑置于后端处理的传统架构设计原则相悖,前端通常仅负责显示和交互。本报告旨在深入剖析这一困境,并提供一个合理且高效的解决方案。 + +对于一个碰撞预警系统而言,其安全关键性是首要考量。这意味着系统必须具备极高的可靠性、确定性以及可验证性。例如,美国国家航空航天局(NASA)对地面防撞系统(GCAS)的评估研究,其核心在于最大化“保护”(系统探测和防止地面碰撞的能力)并最小化“干扰”(不必要的干预或对飞行员的抑制)1。这项研究采用了蒙特卡洛技术,模拟了超过60,000种独特条件,并利用了超过3,000小时的ADS-B飞行数据进行评估,以确保系统在各种复杂场景下的性能和可靠性1。这种严谨的测试和验证流程,以及对复杂算法(如轨迹预测算法TPA)的精细调优,都强调了核心安全逻辑必须在一个受控、稳定且可预测的环境中执行。 + +浏览器前端环境固有的特性,如性能波动、对客户端网络状况的依赖、以及用户可能关闭标签页等行为,都会引入不确定性。这使得在前端执行安全关键的、需要高确定性的计算变得极具挑战性。相比之下,集中化的后端环境能够提供必要的受控执行上下文,从而更容易应用复杂的算法、管理大规模数据集,并确保系统行为的一致性和可验证性。因此,架构决策不仅仅是关于“实时”显示,更深层次地关乎安全逻辑的可靠性、准确性和可验证性,这些因素强烈倾向于将核心处理置于一个健壮的后端。 + +## **3\. 实时GIS架构模式与最佳实践** + +实时GIS是一个专注于连续摄取、处理、分析和可视化动态地理空间数据的专业领域,这些数据通常来源于传感器、物联网设备和移动资产。其主要目标是提供即时态势感知,从不断变化的地理现象中获取洞察,并触发及时响应。 + +### **3.1 实时GIS的关键架构支柱** + +领先的GIS平台,如Esri的ArcGIS,已将“实时数据流和分析”视为其核心系统模式之一4。这种模式涵盖了全面的能力集,包括从各种来源(固定传感器、移动物体、事件)摄取数据、利用高级空间分析识别模式和关系、高效存储数据、动态可视化、智能数据分发(例如,警报)以及触发外部系统动作5。 + +构建健壮的实时GIS应用程序需要遵循多项架构最佳实践。Esri的架构实践强调了六个关键支柱:自动化、集成、可观察性、性能和可扩展性、可靠性以及安全性4。对于碰撞预警系统而言,性能、可扩展性、可靠性和安全性尤为重要。实时系统,特别是那些处理大量传感器数据的系统,通常涉及“大数据分析”,并需要“分布式计算”来进行高效的时空分析5。这暗示了需要一个强大的服务器端基础设施来处理高数据吞吐量和复杂的计算。 + +### **3.2 实时Web应用中处理逻辑的通用考量** + +传统的Web GIS架构清晰地划分了职责:客户端应用程序(Web浏览器、移动应用)作为前端界面,主要负责地图显示、用户交互和数据可视化6。相反,服务器端组件则负责管理后端任务,执行复杂的空间分析、地理处理操作,并将处理后的地理空间数据传回客户端进行展示6。例如,2GIS平台架构就体现了这种分离,其后端服务(SPCore)负责实现“所有必要的地理空间逻辑”,并通过RESTful API与前端通信7。 + +在比较客户端和服务器端数据处理时,客户端跟踪易于实现,并可直接访问浏览器特定的上下文信息(如IP地址、用户代理、Cookie),这对于简单的实时显示更新可能有利8。然而,对于关键应用程序,它存在显著缺点:易受广告拦截器和浏览器隐私设置(ITP/ETP)的影响、潜在的网络问题、对数据流的控制有限,以及对持续、重度计算的固有性能限制8。 + +相比之下,服务器端处理能够提升数据质量和准确性,改善整体应用程序性能(通过减轻客户端负担),对数据流拥有更大的控制权(包括为隐私合规性进行过滤和匿名化),并有效缓解客户端干扰(如广告拦截器)9。这些优势凸显了服务器端在可靠性、安全性和可扩展性方面的适用性。 + +对主流GIS厂商(如Esri)和通用Web GIS架构的深入分析显示,复杂的地理空间数据处理、实时分析和稳健的数据管理主要在服务器端进行4。客户端的主要职责是可视化和用户交互。Esri的“实时数据流和分析”模式明确将“分析”列为服务器端能力,通常需要企业级解决方案,例如ArcGIS GeoEvent Server5。这不仅仅是一种“传统做法”,而是一种经过充分验证的架构模式,旨在构建可扩展、可靠和安全的地理空间系统。 + +对于机场碰撞预警系统这样的安全关键型应用,遵循这一既定模式至关重要。将核心逻辑置于前端将引入不必要的风险,包括可靠性、数据一致性、可扩展性以及长期可维护性方面的问题,从长远来看,这可能会增加开发复杂度和时间,与用户追求的简洁高效目标相悖。 + +## **4\. 超图生态系统实时空间处理能力** + +超图(SuperMap)GIS生态系统为构建实时空间预警系统提供了强大的能力,其产品设计清晰地划分了服务器端和客户端的职责,以优化整体性能和可靠性。 + +### **4.1 SuperMap iServer 的核心作用** + +SuperMap iServer 提供了一套强大的能力,是构建实时空间预警系统后端的基石: + +* **流数据技术:** SuperMap iServer 的流数据技术是实时应用的核心。它基于Spark Streaming处理技术框架构建,天然适用于高效处理连续流数据和历史数据集,并能保证处理过程中的容错性1。这项能力与连续摄取和处理实时车辆位置数据的需求完美契合。 +* **DataFlow 服务实现低延迟推送:** iServer 的 DataFlow 服务专为“客户端与服务器之间低延迟、实时数据传输”而设计,采用 WebSocket 协议1。这使得服务器能够“向客户端广播实时数据分析结果”,为将生成的警报和更新后的车辆位置高效、直接地推送到前端提供了机制,无需客户端持续轮询。 +* **Datastore 实现高效实时数据存储和查询:** iServer 的 Datastore 功能主要依赖于 Elasticsearch 分布式流数据库,能够高效存储流数据1。这对于实时搜索、稳定数据保留和快速检索至关重要,支持诸如历史轨迹回放和时间轴回放等功能,以进行事后分析和系统审计。 +* **服务器端空间分析能力支持复杂计算:** SuperMap iServer 支持“分布式分析服务”,包括“叠加分析”和“聚合分析”等基本操作12。此外,它还能“动态跟踪相关目标”并“对目标位置变化行为进行警报或通知”1。这些能力正是核心预警逻辑所需的:碰撞检测(例如,使用缓冲区分析进行邻近检查,叠加分析进行交叉判断)、超速检测(根据位置更新计算速度)以及电子围栏(对预定义机场区域执行实时点在多边形内测试)。 + +### **4.2 SuperMap iClient 的核心作用** + +SuperMap iClient JavaScript 定位为一个强大的Web客户端开发平台,主要侧重于可视化和用户交互: + +* **基于 Turf.js 的客户端空间分析:能力与局限性:** SuperMap iClient JavaScript 10i 和 11i 集成了 Turf.js,一个开源的 JavaScript 空间分析库,提供了“客户端计算能力,如空间分析、拓扑分析、等值线分析、测量分析”13。这使得“各种常见的空间操作可以在客户端快速完成,无需连接GIS服务”13。然而,对于高频率、高并发、安全关键型的连续多目标碰撞检测场景,其“常见空间操作”的上下文以及浏览器环境固有的局限性,表明它不适合承担此类核心计算任务。浏览器资源可能会在持续、复杂的计算中不堪重负,并引入可靠性问题。3D GIS分析在客户端的普遍困难也支持了这一观点15。尽管Turf.js提供了算法16,但挑战在于如何在浏览器受限的环境中持续、可靠且大规模地应用它们,尤其是在延迟和数据一致性至关重要的场景下17。 +* **高性能实时数据可视化:** iClient 在可视化方面表现出色,能够“高性能可视化”和“流畅显示”大规模数据集13。它拥有针对点图层升级的渲染性能,支持在1秒内渲染多达100万个点,并改进了数据流图层的性能,支持多达10万个矢量点13。它明确支持“SuperMap iServer 的实时数据服务可视化”,并有“10,000+ 辆汽车实时位置可视化”的示例13。这使其成为显示车辆运动和警报的理想选择。 + +超图iServer的文档明确指出其“流数据技术”和“DataFlow服务”是用于实时数据的“分析处理”、“存储”和“输出”,包括“对目标位置变化行为进行警报或通知”的核心组件1。这直接契合了用户对碰撞、超速和电子围栏“计算”和“警报”的需求。相反,SuperMap iClient的功能则持续强调“可视化”、“显示”和实现“常见空间操作”13。尽管Turf.js提供了客户端空间分析能力,但对于安全关键型碰撞预警系统而言,其规模和连续性(涉及大量动态对象和复杂空间几何)可能会超出浏览器性能和可靠性的实际限制,尤其是在低延迟和数据一致性要求极高的情况下17。 + +这种在超图生态系统内部清晰的职责划分意味着,利用iServer处理核心、高负荷的空间分析逻辑符合其设计初衷,即提供健壮且可扩展的实时处理能力。而iClient则非常适合高效地向用户呈现这些关键结果。这种战略性的职责分配能够优化计算性能和系统可靠性,从而有助于实现更易于维护和更高效的开发过程。 + +下表详细说明了SuperMap产品在碰撞预警系统中的能力分工: + +**表2:超图产品在碰撞预警系统中的能力分工** + +| 超图组件 | 关键实时能力 | 与碰撞系统功能的相关性 | +| :---- | :---- | :---- | +| SuperMap iServer 流数据技术 | 实时数据摄取与处理 (Spark Streaming) | 摄取连续的车辆位置流数据。 | +| SuperMap iServer DataFlow 服务 | 低延迟实时数据推送 (WebSocket) | 将碰撞、超速、电子围栏警报推送到前端。 | +| SuperMap iServer Datastore | 高效实时与历史数据存储 (Elasticsearch) | 存储车辆轨迹、电子围栏定义和警报日志,用于分析和回放。 | +| SuperMap iServer 分布式分析服务 | 服务器端空间分析 (叠加、聚合) | 执行连续的碰撞检测、超速检查和电子围栏逻辑。 | +| SuperMap iClient 客户端分析 (Turf.js) | 常见空间操作 (测量、拓扑) | 支持用户发起的非关键空间查询(例如,地图上的距离测量)。 | +| SuperMap iClient 实时数据可视化 | 高性能动态地图显示 (10万+点) | 可视化实时车辆位置,并在地图上显示警报,确保流畅响应。 | + +## **5\. 实时碰撞预警系统案例研究与经验教训** + +深入分析现有实时碰撞预警系统和机场运营管理方案,可以为本次架构设计提供宝贵的经验和借鉴。 + +### **5.1 地面防撞系统(GCAS)的分析** + +美国国家航空航天局(NASA)对通用航空飞机地面防撞系统(GCAS)的广泛研究1为用户的项目提供了直接的参考。这项研究的核心在于最大化“保护”(系统探测和防止地面碰撞的能力)同时最小化“干扰”(不必要或不恰当的干预)。 + +评估方法包括利用“蒙特卡洛技术模拟超过60,000种独特条件”的“系统级分析”1。这种测试和验证的严谨性凸显了对高度确定性和可靠性处理环境的需求。为测试GCAS的保护能力而开发的“恢复自动驾驶仪”2,以及对“轨迹预测算法(TPA)”的调优2,都强调了核心防撞逻辑的复杂性和计算密集性。这类复杂、安全关键的算法,本质上更适合在受控、集中且健壮的服务器端或嵌入式系统中进行管理和执行,而非分布式的、较不可预测的客户端环境。 + +从NASA GCAS案例研究中得到的详细经验,直接指导了架构决策。对实现98.5%“保护率”的强调,以及通过数千小时飞行数据和蒙特卡洛模拟对“干扰”激活的细致评估,表明碰撞检测逻辑必须具有卓越的可靠性、可预测性和可验证性。浏览器环境的特点是性能可变、依赖客户端网络条件以及可能的用户中断(例如,关闭标签页),这些都会引入不确定性,而这对于安全关键功能是不可接受的。集中式后端处理环境提供了执行一致性所需的控制,更易于应用复杂算法,并实现全面、可重复的测试,这对于确保安全和符合法规至关重要。因此,对于用户的系统而言,架构选择不仅仅是实现“实时”显示,更根本地关乎安全逻辑的可靠性、一致性和可验证性,这强烈要求采用以后端为中心的方法。 + +### **5.2 机场实时追踪与运营系统的经验** + +现代机场运营正经历一场由“实时位置数据和物联网(IoT)”驱动的变革19。这些技术在简化旅客流程、优化行李追踪以及提升飞机周转时间等方面发挥着关键作用。 + +这些“智慧机场解决方案”高度依赖“大数据分析和人工智能,不仅能响应,还能预测”运营问题19。例如,多伦多皮尔逊国际机场利用AI驱动的视频分析监控海关排队情况,德里机场T3航站楼部署了500多个天花板传感器追踪人流和等待时间,阿姆斯特丹史基浦机场则采用预测模型来预判人流瓶颈19。Veoci等平台20进一步印证了这一趋势,提供“GIS地图”、“实时报告(仪表板)”和“外部集成”功能,实现全面的机场运营管理。尽管这些解决方案为工作人员提供了移动应用程序以数字化表单和工作流程,但其底层的数据处理、分析和报告功能是集中化的。 + +对现有智慧机场解决方案的分析19清晰地表明,尽管实时“数据”在前端收集和“可视化”(例如,仪表板、移动应用程序),但繁重的计算任务——如“大数据分析”、“AI驱动的视频分析”、“预测建模”和“实时报告”——均在后端执行。这是因为这些操作涉及集成多样的数据源、应用复杂算法、管理海量数据集,并通常执行计算密集型任务(如机器学习),这些都是强大服务器端基础设施固有的能力。前端作为交互式显示层,呈现由这些强大后端流程生成的洞察和警报。用户的碰撞预警系统涉及类似的复杂空间分析,用于预测潜在事件和管理电子围栏,这与这种以后端为中心的行业模型天然契合。 + +### **5.3 无人地面车辆(UGV)防撞系统的架构启示** + +无人地面车辆(UGV)防撞系统提供了进一步的架构启示,尤其是在“实时感知、决策和控制机制”的集成方面21。 + +这些系统利用多种先进传感器,包括激光雷达(LiDAR)、雷达、超声波传感器和视觉摄像头来感知环境21。这些传感器的数据随后被输入到复杂的“导航算法”(例如,人工势场法)和“预测建模”技术中,以预测物体运动并确定安全路径21。UGV中“基于深度学习的感知”在增强障碍物检测和人类识别方面的日益重要性21,突显了此类实时空间智能的巨大计算需求。 + +UGV防撞系统21是另一个强有力的类比。对其架构的描述,强调“实时感知、决策和控制”,以及使用激光雷达和雷达等先进传感器,特别是“预测建模”和“基于深度学习的感知”,都指向了对强大计算能力和专业处理的需求。基于浏览器的客户端从根本上不适合连续处理高保真传感器数据流,或对多个动态实体执行复杂的AI/ML模型进行预测分析。这些任务总是由专用的车载处理器(对于自动驾驶车辆)或配备处理此类计算负载的强大后端服务器来处理。用户的系统涉及预测潜在碰撞和持续监控移动车辆与机场静态基础设施之间的复杂空间关系,这与UGV模型完美契合,支持将核心安全关键逻辑放在后端或专用处理器上。 + +## **6\. 建议的架构设计与原理** + +基于上述分析,为机场地面车辆碰撞预警系统推荐的架构设计是:以后端为中心处理核心逻辑,前端专注于可视化和即时警报。这种设计方案在性能、可靠性、可扩展性和开发效率之间实现了最佳平衡,并战略性地利用了SuperMap iServer在后端空间处理方面的强大能力和SuperMap iClient在前端可视化方面的高性能。 + +### **6.1 后端职责(Spring Boot \+ SuperMap iServer)** + +Spring Boot应用程序作为中央处理枢纽,将与SuperMap iServer紧密集成,处理所有关键的实时空间分析和数据管理任务: + +* **实时车辆数据摄取与流处理:** Spring Boot后端将负责接收来自所有机场车辆的连续实时位置数据(例如,通过物联网网关、专用追踪设备或Kafka等消息队列)。这些原始数据流将被送入SuperMap iServer的流数据技术,该技术基于Spark Streaming,天生为高吞吐量、容错的连续数据流处理而设计1。 +* **执行所有关键空间分析:碰撞检测、超速、电子围栏:** + * **碰撞检测:** 后端将持续执行复杂的空间分析操作。这包括邻近检查(例如,围绕车辆的缓冲区分析)、车辆轨迹与静态/动态障碍物(飞机、建筑物、其他车辆)之间的交叉测试,以及最小距离计算。这些操作将利用SuperMap iServer的分布式分析能力12,并可结合高效的空间算法,如用于粗略碰撞检测的轴对齐包围盒(AABB)和用于精确碰撞判断的分离轴定理(SAT)等更精确的方法,针对潜在碰撞对进行细致检查16。 + * **超速预警:** 后端将根据车辆的位置更新计算其实时速度,并与机场特定区域(例如,跑道、滑行道、停机坪)动态定义的速度限制进行比较。 + * **电子围栏预警:** 预定义的电子围栏,代表限制区域、操作区域或禁区,将存储在iServer的Datastore中进行管理。后端将持续执行实时点在多边形内测试,以检测车辆何时进入或离开这些指定的虚拟边界24。 +* **集中警报生成并推送至客户端:** 一旦检测到任何碰撞风险、超速违规或电子围栏越界,后端将立即生成一份详细的警报。随后,SuperMap iServer的DataFlow服务将通过WebSocket协议高效地将这些警报(包括车辆ID、警报类型、精确位置、时间戳和严重性)推送到所有连接的前端客户端1。这确保了关键警报的最小延迟交付。 +* **健壮的数据存储和历史分析:** 所有传入的实时车辆数据、检测到的事件和生成的警报都将持久存储在SuperMap iServer的Datastore中(利用Elasticsearch进行实时搜索,1)。这为历史回放、趋势分析、系统性能监控和事后事故调查创建了可靠的审计跟踪,这对于安全关键系统至关重要。 + +### **6.2 前端职责(SuperMap iClient)** + +SuperMap iClient Web应用程序将作为主要的用户界面,优化以实现高性能可视化和用户交互: + +* **车辆和警报的高性能实时地图可视化:** 前端将显示由SuperMap iServer提供的基础机场地图图层。关键在于,它将通过WebSocket从后端接收并叠加实时车辆位置和警报。iClient针对大型点图层(1秒内可渲染多达100万个点)的先进渲染能力,确保了所有活跃车辆的流畅和响应式显示13。警报将以醒目的方式在地图上进行视觉呈现(例如,闪烁的图标、彩色缓冲区、声音警报、弹出通知),以确保操作员即时感知。 +* **接收和显示来自后端的警报:** iClient应用程序将建立并维护与SuperMap iServer DataFlow服务的WebSocket连接,以持续接收实时警报和更新的车辆位置。 +* **用户交互和非关键客户端空间查询:** 前端可以支持不属于连续、安全关键预警逻辑的用户发起空间查询或分析。例如,使用iClient的客户端空间分析能力(结合Turf.js)测量点之间的距离、查询地图要素的属性或执行简单的空间选择13。这些操作通常对性能要求不高,并由用户按需执行。 + +### **6.3 后端中心化方案的合理性** + +* **可靠性:** 将核心预警逻辑集中在后端,确保了空间规则应用的一致性和准确性,消除了因不同客户端环境或网络条件可能导致的潜在差异。这对于安全关键系统至关重要。 +* **一致性:** 所有空间分析规则、电子围栏定义和速度限制都在一个单一、受控的服务器环境中进行管理和执行,保证了所有系统用户检测和警报的统一性。 +* **可扩展性:** 后端(Spring Boot服务和SuperMap iServer)可以进行水平扩展,以适应不断增加的车辆数量、复杂的机场几何结构和更高的计算需求。SuperMap iServer与Spark Streaming的集成1提供了强大的大数据处理能力,这比单个客户端资源更具可扩展性。 +* **安全性:** 将敏感业务逻辑和关键实时数据保留在服务器端,显著降低了它们暴露于客户端漏洞和未经授权访问的风险9。数据过滤和匿名化也可以在服务器端进行,然后再进行分发。 +* **优化开发:** 这种架构分离简化了前端开发,使前端团队能够专注于直观的可视化和用户体验,而后端团队则专注于开发健壮的空间算法、数据处理管道和系统集成。这直接符合用户“低开发难度,时间短”的目标。 +* **性能:** 尽管前端提供“实时访问”以供显示,但连续、多目标碰撞检测和复杂空间分析的繁重计算负载在具有专用资源和优化GIS服务的服务器上能更有效地管理。后端仅将“结果”(警报和相关车辆更新)推送到客户端,最大限度地减少了客户端处理负担和非警报数据的网络流量。这确保了客户端在用户交互和可视化方面保持响应性。 + +下表提供了所建议架构中各系统组件的职责蓝图: + +**表3:建议的系统组件职责** + +| 系统组件 | 主要职责 | 关键技术/超图功能 | +| :---- | :---- | :---- | +| **车辆数据源 (IoT设备, GPS追踪器)** | 生成并传输实时位置数据(GPS坐标、速度、航向、时间戳) | IoT传感器、车辆GPS设备、远程信息处理系统 | +| **Spring Boot 后端应用** | 摄取原始车辆数据,协调空间分析请求,管理业务逻辑,生成警报,管理用户认证/授权 | Java, Spring Boot, 消息队列 (例如 Kafka 用于数据摄取), REST API | +| **SuperMap iServer (GIS 服务器)** | 托管基础地图服务,摄取流数据,执行实时空间分析(碰撞、超速、电子围栏),存储实时/历史数据,向客户端推送警报 | SuperMap iServer 2024, 流数据技术, DataFlow 服务, Datastore (Elasticsearch), 分布式分析服务 | +| **SuperMap iClient 前端 (Web 应用)** | 显示实时地图,可视化车辆位置,接收并显示警报,处理用户交互,执行非关键客户端空间查询 | HTML5, JavaScript, OpenLayers, SuperMap iClient JavaScript (for OpenLayers), WebSockets | +| **数据存储 (SuperMap iServer Datastore/后端数据库)** | 持久化实时车辆轨迹、电子围栏定义、历史警报和系统配置 | Elasticsearch (通过 iServer Datastore), PostgreSQL/PostGIS (用于静态GIS数据和配置) | + +## **7\. 实施考量与最佳实践** + +为了实现一个高性能、高可靠、易于维护的机场车辆碰撞预警系统,以下实施考量和最佳实践至关重要: + +### **7.1 数据流与通信协议** + +高效可靠的数据流是实时系统的关键: + +* **车辆数据到后端:** 对于将原始车辆位置数据摄取到Spring Boot应用程序,应考虑高吞吐量、低延迟的协议,例如MQTT(消息队列遥测传输协议)或来自车辆跟踪设备/物联网网关的直接WebSocket连接。或者,Apache Kafka等消息队列可以有效地缓冲和分发数据流。 +* **后端到iServer:** Spring Boot应用程序将使用标准API调用(RESTful服务)向SuperMap iServer发送空间分析请求。对于连续数据流,应利用iServer专用的流数据输入机制。 +* **iServer到iClient:** 从iServer向前端推送实时警报和处理后的车辆位置更新的主要通信通道将是SuperMap iServer的DataFlow服务,通过WebSocket协议实现1。这确保了高效、全双工、低延迟的通信,允许服务器广播更新而无需客户端持续轮询。 + +### **7.2 性能优化策略** + +为了满足碰撞预警系统的实时需求,多层面的性能优化至关重要: + +* **后端数据库/数据存储:** 在后端数据库(如带有PostGIS的PostgreSQL)中实现强大的空间索引(例如,R树、四叉树),并利用iServer Datastore(基于Elasticsearch)的功能1,以显著加速空间查询和分析操作。 +* **碰撞算法:** 选择并优化高效的碰撞检测算法,以便在服务器上实时执行。对于粗略的碰撞检测(识别潜在碰撞对),简单的轴对齐包围盒(AABB)检查是有效的。对于精确的碰撞判断(狭义碰撞检测),分离轴定理(SAT)等算法适用于凸形16。这些算法应根据车辆和机场特征的特定几何表示进行仔细实现和调优。 +* **数据量管理:** 利用SuperMap iServer与Spark Streaming的集成1,高效处理和分析大量连续实时数据,必要时将计算负载分布到多个节点。 +* **系统延迟监控:** 主动监控系统延迟、数据新鲜度和处理瓶颈(如Google Dataflow的上下文中所强调的17)。应部署工具和仪表板,以识别和解决数据摄取、处理或警报交付中的任何延迟。 + +### **7.3 错误处理、弹性与监控** + +鉴于系统的安全关键性,健壮的运营方面是不可或缺的: + +* **错误处理:** 在整个数据管道中,从数据摄取到警报交付,实施全面的错误处理和优雅降级策略。包括针对瞬时故障的重试机制。 +* **高可用性和容错性:** 将Spring Boot应用程序和SuperMap iServer组件设计为高可用和容错。这可能涉及以集群配置部署iServer,并为Spring Boot应用程序使用负载均衡器和冗余后端服务。 +* **全面监控:** 建立一个强大的监控系统(与“可观察性”架构支柱保持一致4),以跟踪关键性能指标(KPI),例如系统健康状况、数据新鲜度、处理延迟17和警报交付率以及资源利用率。异常情况的自动警报至关重要。 +* **冗余:** 考虑关键数据源、网络连接和电源的冗余,以确保持续运行。 + +### **7.4 实时位置数据的安全考量** + +安全性必须从设计到部署阶段都作为基本考量: + +* **安全通信:** 所有通信通道,包括REST API和WebSocket,都必须使用行业标准加密(REST使用HTTPS,WebSocket使用WSS)进行保护。 +* **认证和授权:** 为所有访问后端和GIS服务的用户和服务实施强大的认证机制。细粒度的授权控制应确保只有授权人员或系统才能访问特定数据或功能。 +* **数据隐私:** 对于车辆位置数据,特别是如果它包含个人身份信息(PII),应根据相关法规实施健壮的数据隐私措施,包括匿名化、假名化或加密9。 +* **电子围栏和警报配置安全:** 保护电子围栏定义和警报配置的完整性和机密性,以防止未经授权的修改或访问。 + +一个真正的“实时”和可靠系统,其可靠性不仅仅体现在快速处理,还包括健壮的错误处理、弹性设计和全面的监控。用户对“时间短”和“开发难度低”的期望,可能会无意中导致忽视这些关键的非功能性需求。然而,对于安全关键型应用程序,在这些方面偷工减料可能会导致后期出现重大、代价高昂且耗时的问题(例如,警报遗漏、系统中断、调试困难)。因此,“时间短”和“低难度”应通过高效利用SuperMap iServer等强大、内置的工具能力来实现,而不是通过牺牲安全和长期运营完整性的基本架构原则来达成。成功的实施将需要在整个开发生命周期中,平衡关注功能需求(碰撞检测)和非功能需求(可靠性、可扩展性、安全性、可维护性)。 + +## **8\. 结论与建议** + +对于机场地面车辆碰撞预警系统,最佳且最健壮的架构设计是以后端为中心。Spring Boot应用程序与SuperMap iServer紧密集成,将作为核心引擎,处理碰撞检测、超速预警和电子围栏等所有实时空间分析。SuperMap iClient前端将针对车辆运动的高性能可视化以及后端推送的警报进行即时、直观的显示进行优化。这种职责划分充分利用了每个组件的优势,以实现最大的效率和可靠性。 + +为实现简洁清晰、开发难度低、时间短的开发路径,建议如下: + +* **充分利用SuperMap iServer的内置实时能力:** 最大限度地利用iServer的流数据技术进行数据摄取和分析,以及其基于WebSocket的DataFlow服务进行警报推送。这显著减少了定制开发复杂实时GIS后端基础设施的需求,直接有助于降低开发难度和缩短开发周期。 +* **将前端专注于可视化和交互:** 设计SuperMap iClient应用程序主要侧重于地图渲染、实时车辆显示和警报可视化。通过消费后端预先计算的警报和处理后的数据,前端逻辑将保持更简单、更易于管理。 +* **优先考虑可靠性和可测试性:** 对于所有安全关键功能,确保核心逻辑驻留在受控、可测试的后端环境中。实施严格的测试协议,包括基于模拟的评估,以验证系统的保护能力并最大限度地减少干扰警报。 +* **迭代开发,核心功能先行:** 首先实施并彻底测试后端的核心碰撞、超速和电子围栏预警逻辑。一旦其健壮性得到验证,再集成前端可视化和警报机制。这种迭代方法确保了基础的稳定性。 +* **采用标准协议:** 遵循既定的通信协议,如用于实时数据推送的WebSocket和用于其他交互的REST API。这有助于提高互操作性,简化集成,并增强长期可维护性。 + +#### **Works cited** + +1. SuperMap iServer Streaming Data Technology \- SuperMap, accessed June 4, 2025, [https://www.supermap.com/en-us/news/?82\_670.html](https://www.supermap.com/en-us/news/?82_670.html) +2. Analysis of the Ground Collision Avoidance System Within NASA's Expandable Vehicle Autonomy Architecture \- ROSA P, accessed June 4, 2025, [https://rosap.ntl.bts.gov/view/dot/82861/dot\_82861\_DS1.pdf](https://rosap.ntl.bts.gov/view/dot/82861/dot_82861_DS1.pdf) +3. Analysis of the Ground Collision Avoidance System Within NASA's Expandable Vehicle Autonomy Architecture \- ROSA P, accessed June 4, 2025, [https://rosap.ntl.bts.gov/view/dot/82861](https://rosap.ntl.bts.gov/view/dot/82861) +4. Empowering IT Professionals with Architecture Patterns, Practices ..., accessed June 4, 2025, [https://www.esri.com/about/newsroom/arcnews/empowering-it-professionals-with-architecture-patterns-practices-for-arcgis](https://www.esri.com/about/newsroom/arcnews/empowering-it-professionals-with-architecture-patterns-practices-for-arcgis) +5. Real-Time Visualization & Analytics | Gain Insights from Big Data & IoT, accessed June 4, 2025, [https://www.esri.com/en-us/capabilities/real-time/overview](https://www.esri.com/en-us/capabilities/real-time/overview) +6. Web GIS: Revolutionizing RealTime Spatial Data Access \- Satpalda, accessed June 4, 2025, [https://satpalda.com/web-gis-revolutionizing-realtime-spatial-data-access/](https://satpalda.com/web-gis-revolutionizing-realtime-spatial-data-access/) +7. GIS Platform | On‑Premise | 2GIS Documentation, accessed June 4, 2025, [https://docs.2gis.com/en/on-premise/architecture/services/gisplatform](https://docs.2gis.com/en/on-premise/architecture/services/gisplatform) +8. Client vs Server-Side Tracking \- Collecting the right data | Twilio Segment, accessed June 4, 2025, [https://segment.com/academy/collecting-data/when-to-track-on-the-client-vs-server/](https://segment.com/academy/collecting-data/when-to-track-on-the-client-vs-server/) +9. Server-Side vs. Client-Side Tracking \- Analytico, accessed June 4, 2025, [https://www.analyticodigital.com/blog/server-side-vs-client-side-tracking-which-one-should-you-choose](https://www.analyticodigital.com/blog/server-side-vs-client-side-tracking-which-one-should-you-choose) +10. accessed January 1, 1970, [https://www.supermap.com/zh-cn/a/product/gis-iserver-2024.html\#nav-list](https://www.supermap.com/zh-cn/a/product/gis-iserver-2024.html#nav-list) +11. Data flow service \- SuperMap iClient, accessed June 4, 2025, [https://iclientdev.supermap.io/iserver/help/html/en/iS/use\_iserver/usedataflow/dataflow.htm](https://iclientdev.supermap.io/iserver/help/html/en/iS/use_iserver/usedataflow/dataflow.htm) +12. Terminal GIS for Mobile Overview and Features \- SuperMap, accessed June 4, 2025, [https://www.supermap.com/en-us/list/?157\_1.html](https://www.supermap.com/en-us/list/?157_1.html) +13. SuperMap iClient JavaScript 10i, accessed June 4, 2025, [https://iclient.supermap.io/10.0.1/web/index.html](https://iclient.supermap.io/10.0.1/web/index.html) +14. SuperMap iClient JavaScript 11i(2023), accessed June 4, 2025, [https://iclient.supermap.io/11.1.0/web/index.html](https://iclient.supermap.io/11.1.0/web/index.html) +15. SUPERMAP GIS 6R: A REAL SPACE GIS, accessed June 4, 2025, [https://www.isprs.org/proceedings/xxxviii/4-w10/papers/VCGVA2009\_08617\_Luo.pdf](https://www.isprs.org/proceedings/xxxviii/4-w10/papers/VCGVA2009_08617_Luo.pdf) +16. jriecken/sat-js: A simple JavaScript library for performing 2D collision detection \- GitHub, accessed June 4, 2025, [https://github.com/jriecken/sat-js](https://github.com/jriecken/sat-js) +17. Dataflow job metrics | Google Cloud, accessed June 4, 2025, [https://cloud.google.com/dataflow/docs/guides/using-monitoring-intf](https://cloud.google.com/dataflow/docs/guides/using-monitoring-intf) +18. SuperMap iClient JavaScript 10i(2020) \-a cloud GIS web client development platform, accessed June 4, 2025, [https://iclient.supermap.io/10.1.1/en/web/index.html](https://iclient.supermap.io/10.1.1/en/web/index.html) +19. How Location Data Improves Airport Operations in 2025? \- Mapsted, accessed June 4, 2025, [https://mapsted.com/blog/how-location-data-improves-airport-operations](https://mapsted.com/blog/how-location-data-improves-airport-operations) +20. Airport Operations Management Software \- Veoci, accessed June 4, 2025, [https://veoci.com/aviation/](https://veoci.com/aviation/) +21. Collision avoidance strategies for special-purpose Unmanned Ground Vehicles in dynamic environments with human presence \- ResearchGate, accessed June 4, 2025, [https://www.researchgate.net/publication/390341371\_Collision\_avoidance\_strategies\_for\_special-purpose\_Unmanned\_Ground\_Vehicles\_in\_dynamic\_environments\_with\_human\_presence](https://www.researchgate.net/publication/390341371_Collision_avoidance_strategies_for_special-purpose_Unmanned_Ground_Vehicles_in_dynamic_environments_with_human_presence) +22. 2D collision detection \- Game development \- MDN Web Docs, accessed June 4, 2025, [https://developer.mozilla.org/en-US/docs/Games/Techniques/2D\_collision\_detection](https://developer.mozilla.org/en-US/docs/Games/Techniques/2D_collision_detection) +23. Real-Time Collision Detection (The Morgan Kaufmann Series in Interactive 3-D Technology), accessed June 4, 2025, [https://www.amazon.com/Real-Time-Collision-Detection-Interactive-Technology/dp/1558607323](https://www.amazon.com/Real-Time-Collision-Detection-Interactive-Technology/dp/1558607323) +24. Geofencing in Retail: Implementation Guide for Tech SaaS Product \- MobiDev, accessed June 4, 2025, [https://mobidev.biz/blog/geofencing-in-retail-implementation-guide-for-tech-saas-products](https://mobidev.biz/blog/geofencing-in-retail-implementation-guide-for-tech-saas-products) +25. Geofencing Time and Attendance \- TimeTrex, accessed June 4, 2025, [https://www.timetrex.com/blog/geofencing-time-and-attendance](https://www.timetrex.com/blog/geofencing-time-and-attendance) \ No newline at end of file diff --git a/src/main/java/com/dongni/collisionavoidance/common/model/Aircraft.java b/src/main/java/com/dongni/collisionavoidance/common/model/Aircraft.java index 72fd09b..0d50fe5 100644 --- a/src/main/java/com/dongni/collisionavoidance/common/model/Aircraft.java +++ b/src/main/java/com/dongni/collisionavoidance/common/model/Aircraft.java @@ -4,10 +4,10 @@ package com.dongni.collisionavoidance.common.model; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; /** @@ -17,6 +17,7 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor +@EqualsAndHashCode(callSuper=true) public class Aircraft extends MovingObject{ /** * 航班号 diff --git a/src/main/java/com/dongni/collisionavoidance/common/model/MovingObject.java b/src/main/java/com/dongni/collisionavoidance/common/model/MovingObject.java index fa17501..be03332 100644 --- a/src/main/java/com/dongni/collisionavoidance/common/model/MovingObject.java +++ b/src/main/java/com/dongni/collisionavoidance/common/model/MovingObject.java @@ -1,12 +1,8 @@ package com.dongni.collisionavoidance.common.model; -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; -import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; - import java.util.ArrayDeque; import java.util.Deque; diff --git a/src/main/java/com/dongni/collisionavoidance/common/model/SpecialVehicle.java b/src/main/java/com/dongni/collisionavoidance/common/model/SpecialVehicle.java index d7cc691..a2e0322 100644 --- a/src/main/java/com/dongni/collisionavoidance/common/model/SpecialVehicle.java +++ b/src/main/java/com/dongni/collisionavoidance/common/model/SpecialVehicle.java @@ -5,14 +5,14 @@ import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Deque; - @Data @Builder @NoArgsConstructor @AllArgsConstructor +@EqualsAndHashCode(callSuper=true) public class SpecialVehicle extends MovingObject{ /** * 车牌号 diff --git a/src/main/java/com/dongni/collisionavoidance/common/model/UnmannedVehicle.java b/src/main/java/com/dongni/collisionavoidance/common/model/UnmannedVehicle.java index 2335b77..1fa4dda 100644 --- a/src/main/java/com/dongni/collisionavoidance/common/model/UnmannedVehicle.java +++ b/src/main/java/com/dongni/collisionavoidance/common/model/UnmannedVehicle.java @@ -5,10 +5,9 @@ import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; -import java.util.Deque; - /** * 车辆实体类 */ @@ -16,6 +15,7 @@ import java.util.Deque; @Builder @NoArgsConstructor @AllArgsConstructor +@EqualsAndHashCode(callSuper=true) public class UnmannedVehicle extends MovingObject{ /** * 消息唯一ID,消息的唯一标识符 diff --git a/src/main/java/com/dongni/collisionavoidance/config/RedisConfig.java b/src/main/java/com/dongni/collisionavoidance/config/RedisConfig.java index 5ad0946..39de92d 100644 --- a/src/main/java/com/dongni/collisionavoidance/config/RedisConfig.java +++ b/src/main/java/com/dongni/collisionavoidance/config/RedisConfig.java @@ -19,12 +19,11 @@ public class RedisConfig { template.setConnectionFactory(connectionFactory); // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 - Jackson2JsonRedisSerializer serializer = - new Jackson2JsonRedisSerializer<>(VehicleLocationInfo.class); - ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JavaTimeModule()); - serializer.setObjectMapper(mapper); + + Jackson2JsonRedisSerializer serializer = + new Jackson2JsonRedisSerializer<>(mapper, VehicleLocationInfo.class); template.setValueSerializer(serializer); template.setHashValueSerializer(serializer); diff --git a/src/main/java/com/dongni/collisionavoidance/config/YamlPropertySourceFactory.java b/src/main/java/com/dongni/collisionavoidance/config/YamlPropertySourceFactory.java index 3cf9de0..97f406e 100644 --- a/src/main/java/com/dongni/collisionavoidance/config/YamlPropertySourceFactory.java +++ b/src/main/java/com/dongni/collisionavoidance/config/YamlPropertySourceFactory.java @@ -6,6 +6,7 @@ import org.springframework.core.env.PropertySource; import org.springframework.core.io.support.EncodedResource; import org.springframework.core.io.support.PropertySourceFactory; import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; import java.io.IOException; import java.util.Properties; @@ -18,7 +19,7 @@ public class YamlPropertySourceFactory implements PropertySourceFactory { @Override @NonNull - public PropertySource createPropertySource(String name, @NonNull EncodedResource resource) throws IOException { + public PropertySource createPropertySource(@Nullable String name, @NonNull EncodedResource resource) throws IOException { YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); factory.setResources(resource.getResource()); diff --git a/src/main/java/com/dongni/collisionavoidance/controller/DataMonitorController.java b/src/main/java/com/dongni/collisionavoidance/controller/DataMonitorController.java index 19b511e..5a89eb4 100644 --- a/src/main/java/com/dongni/collisionavoidance/controller/DataMonitorController.java +++ b/src/main/java/com/dongni/collisionavoidance/controller/DataMonitorController.java @@ -3,10 +3,6 @@ package com.dongni.collisionavoidance.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - @RestController @RequestMapping("/api/monitor") public class DataMonitorController { diff --git a/src/main/java/com/dongni/collisionavoidance/dataCollector/dao/DataCollectorDao.java b/src/main/java/com/dongni/collisionavoidance/dataCollector/dao/DataCollectorDao.java index 29fc7c0..00b91e8 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataCollector/dao/DataCollectorDao.java +++ b/src/main/java/com/dongni/collisionavoidance/dataCollector/dao/DataCollectorDao.java @@ -45,7 +45,7 @@ public class DataCollectorDao { public List collectAircraftData(String endpoint, String baseUrl) { try { String url = UriComponentsBuilder - .fromHttpUrl(baseUrl) + .fromUriString(baseUrl) .path(endpoint) .toUriString(); @@ -60,10 +60,13 @@ public class DataCollectorDao { new ParameterizedTypeReference>>() {} ); - if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { - List dataList = response.getBody().getData(); - log.info("成功获取航空器数据,数量: {}", dataList.size()); - return dataList; + if (response.getStatusCode().is2xxSuccessful()) { + Response> responseBody = response.getBody(); + if (responseBody != null) { + List dataList = responseBody.getData(); + log.info("成功获取航空器数据,数量: {}", dataList.size()); + return dataList; + } } } catch (Exception e) { log.error("采集航空器数据失败: {}", endpoint, e); @@ -74,7 +77,7 @@ public class DataCollectorDao { public List collectVehicleData(String endpoint, String baseUrl) { try { String url = UriComponentsBuilder - .fromHttpUrl(baseUrl) + .fromUriString(baseUrl) .path(endpoint) .toUriString(); @@ -89,10 +92,13 @@ public class DataCollectorDao { new ParameterizedTypeReference>>() {} ); - if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { - List dataList = response.getBody().getData(); - log.info("成功获取特种车辆数据,数量: {}", dataList.size()); - return dataList; + if (response.getStatusCode().is2xxSuccessful()) { + Response> responseBody = response.getBody(); + if (responseBody != null) { + List dataList = responseBody.getData(); + log.info("成功获取特种车辆数据,数量: {}", dataList.size()); + return dataList; + } } } catch (Exception e) { log.error("采集特种车辆数据失败: {}", endpoint, e); @@ -108,7 +114,7 @@ public class DataCollectorDao { System.out.println("接口被调用"); try { String url = UriComponentsBuilder - .fromHttpUrl(vehicleBaseUrl) + .fromUriString(vehicleBaseUrl) .path(vehicleLocationEndpoint) .toUriString(); @@ -122,17 +128,18 @@ public class DataCollectorDao { new ParameterizedTypeReference>() {} ); - if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { - log.info("成功获取车辆定位信息,数量: {}", response.getBody().size()); - return response.getBody(); - } else { - log.error("获取车辆定位信息失败,状态码: {}", response.getStatusCode()); - return Collections.emptyList(); - } + if (response.getStatusCode().is2xxSuccessful()) { + List responseBody = response.getBody(); + if (responseBody != null) { + log.info("成功获取车辆定位信息,数量: {}", responseBody.size()); + return responseBody; + } + } } catch (Exception e) { log.error("获取车辆定位信息时发生异常", e); return Collections.emptyList(); } + return Collections.emptyList(); } } diff --git a/src/main/java/com/dongni/collisionavoidance/dataCollector/service/AuthService.java b/src/main/java/com/dongni/collisionavoidance/dataCollector/service/AuthService.java index 88f54d9..4f4428c 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataCollector/service/AuthService.java +++ b/src/main/java/com/dongni/collisionavoidance/dataCollector/service/AuthService.java @@ -43,7 +43,7 @@ public class AuthService { //登录获取Token public String loginAndGetToken() { String loginUrl = UriComponentsBuilder - .fromHttpUrl(baseUrl) + .fromUriString(baseUrl) .path(loginEndpoint) .queryParam("username", username) .queryParam("password", password) @@ -58,11 +58,14 @@ public class AuthService { } ); - if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { - this.token = response.getBody().getData(); - this.tokenExpiryTime = System.currentTimeMillis() + 3600 * 1000; - log.info("Successfully obtained new token"); - return this.token; + if (response.getStatusCode().is2xxSuccessful()) { + Response responseBody = response.getBody(); + if (responseBody != null) { + this.token = responseBody.getData(); + this.tokenExpiryTime = System.currentTimeMillis() + 3600 * 1000; + log.info("Successfully obtained new token"); + return this.token; + } } } catch (Exception e) { log.error("Failed to login: ", e); @@ -73,7 +76,7 @@ public class AuthService { //Token续时 public String refreshToken() { String refreshUrl = UriComponentsBuilder - .fromHttpUrl(baseUrl) + .fromUriString(baseUrl) .path(refreshEndpoint) .toUriString(); @@ -88,11 +91,14 @@ public class AuthService { new ParameterizedTypeReference>() {} ); - if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) { - this.token = response.getBody().getData(); - this.tokenExpiryTime = System.currentTimeMillis() + 3600 * 1000; - log.info("Successfully refreshed token"); - return this.token; + if (response.getStatusCode().is2xxSuccessful()) { + Response responseBody = response.getBody(); + if (responseBody != null) { + this.token = responseBody.getData(); + this.tokenExpiryTime = System.currentTimeMillis() + 3600 * 1000; + log.info("Successfully refreshed token"); + return this.token; + } } } catch (Exception e) { log.error("Failed to refresh token: ", e); diff --git a/src/main/java/com/dongni/collisionavoidance/dataCollector/service/DataCollectorService.java b/src/main/java/com/dongni/collisionavoidance/dataCollector/service/DataCollectorService.java index 3aea147..c8f3fd1 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataCollector/service/DataCollectorService.java +++ b/src/main/java/com/dongni/collisionavoidance/dataCollector/service/DataCollectorService.java @@ -1,11 +1,8 @@ package com.dongni.collisionavoidance.dataCollector.service; import com.dongni.collisionavoidance.common.model.*; -import com.dongni.collisionavoidance.common.model.dto.AircraftDTO; -import com.dongni.collisionavoidance.common.model.dto.SpecialVehicleDTO; import com.dongni.collisionavoidance.common.model.repository.MovingObjectRepository; import com.dongni.collisionavoidance.dataCollector.dao.DataCollectorDao; -import com.dongni.collisionavoidance.dataCollector.model.VehicleLocationInfo; import jakarta.annotation.PreDestroy; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -17,8 +14,6 @@ import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.concurrent.*; -import java.util.ArrayList; -import java.util.LinkedList; import java.util.stream.Collectors; diff --git a/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/AirportCoordinateSystem.java b/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/AirportCoordinateSystem.java index e2edee3..797ab8f 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/AirportCoordinateSystem.java +++ b/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/AirportCoordinateSystem.java @@ -5,7 +5,6 @@ import org.geotools.api.referencing.operation.MathTransform; import org.geotools.geometry.jts.JTS; import org.geotools.referencing.CRS; import org.locationtech.jts.geom.Coordinate; -import org.springframework.stereotype.Component; public class AirportCoordinateSystem { diff --git a/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/DataProcessor.java b/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/DataProcessor.java index 93f04da..4aabb7d 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/DataProcessor.java +++ b/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/DataProcessor.java @@ -10,7 +10,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; diff --git a/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/SpeedCalculationService.java b/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/SpeedCalculationService.java index 6faaef4..1c2a7fe 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/SpeedCalculationService.java +++ b/src/main/java/com/dongni/collisionavoidance/dataProcessing/service/SpeedCalculationService.java @@ -6,7 +6,6 @@ import com.dongni.collisionavoidance.common.model.MovingObject; import com.dongni.collisionavoidance.common.model.Velocity; import org.springframework.stereotype.Service; -import java.util.ArrayDeque; import java.util.Deque; import java.util.List; import java.util.concurrent.locks.ReentrantLock; diff --git a/src/main/java/com/dongni/collisionavoidance/webSocket/config/WebSocketConfig.java b/src/main/java/com/dongni/collisionavoidance/webSocket/config/WebSocketConfig.java index b0ef375..138db84 100644 --- a/src/main/java/com/dongni/collisionavoidance/webSocket/config/WebSocketConfig.java +++ b/src/main/java/com/dongni/collisionavoidance/webSocket/config/WebSocketConfig.java @@ -14,6 +14,7 @@ import java.util.List; @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + @SuppressWarnings("null") @Override public void registerStompEndpoints(StompEndpointRegistry registry) { // 注册STOMP端点,客户端通过此URL连接WebSocket @@ -22,6 +23,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { .withSockJS(); // 启用SockJS支持 } + @SuppressWarnings("null") @Override public void configureMessageBroker(MessageBrokerRegistry registry) { // 启用内存消息代理,客户端订阅地址前缀为/topic @@ -31,6 +33,7 @@ public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { } // 关键配置:添加JSON消息转换器 + @SuppressWarnings("null") @Override public boolean configureMessageConverters(List messageConverters) { messageConverters.add(new MappingJackson2MessageConverter()); diff --git a/src/test/java/com/dongni/collisionavoidance/config/TestConfig.java b/src/test/java/com/dongni/collisionavoidance/config/TestConfig.java index e66da6a..dcc1d5f 100644 --- a/src/test/java/com/dongni/collisionavoidance/config/TestConfig.java +++ b/src/test/java/com/dongni/collisionavoidance/config/TestConfig.java @@ -1,6 +1,5 @@ package com.dongni.collisionavoidance.config; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -8,8 +7,6 @@ import org.springframework.context.annotation.Profile; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import com.dongni.collisionavoidance.common.model.MovingObject; -import com.dongni.collisionavoidance.common.model.MovingObjectType; import com.dongni.collisionavoidance.common.model.repository.MovingObjectRepository; import com.dongni.collisionavoidance.dataCollector.service.AuthService; import com.dongni.collisionavoidance.dataCollector.service.DataCollectorService; @@ -17,9 +14,6 @@ import com.dongni.collisionavoidance.dataProcessing.service.CoordinateSystemServ import com.dongni.collisionavoidance.dataProcessing.service.DataProcessor; import com.dongni.collisionavoidance.dataProcessing.service.SpeedCalculationService; -import java.util.List; -import java.util.Map; -import java.util.Set; import java.util.concurrent.Executor; import org.springframework.web.client.RestTemplate; diff --git a/src/test/java/com/dongni/collisionavoidance/dataProcessing/Test.java b/src/test/java/com/dongni/collisionavoidance/dataProcessing/Test.java index 8ddc7b9..49e2ea9 100644 --- a/src/test/java/com/dongni/collisionavoidance/dataProcessing/Test.java +++ b/src/test/java/com/dongni/collisionavoidance/dataProcessing/Test.java @@ -1,5 +1,5 @@ package com.dongni.collisionavoidance.dataProcessing; -import com.dongni.collisionavoidance.dataProcessing.service.AirportCoordinateSystem; + import com.dongni.collisionavoidance.dataProcessing.service.CoordinateSystemService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;