diff --git a/VERSION.txt b/VERSION.txt index b976b13..4655c9e 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.6.10 \ No newline at end of file +0.6.13 \ No newline at end of file diff --git a/change_log.md b/change_log.md index 498f80e..feafe4a 100644 --- a/change_log.md +++ b/change_log.md @@ -2,7 +2,85 @@ 本文档记录碰撞避免系统的所有重要变更,包括新功能、改进和修复。 -## [0.6.10] - 2025-01-15 +## [0.6.13] - 2025-01-15 + +### 架构重构 (Architecture Refactoring) +- **车辆分类架构优化**: 实现分层的车辆分类管理策略 + - **数据模型层简化**: 移除 `MovingObjectType.SPECIAL_VEHICLE`,保持与API数据源一致的三种类型 + - `AIRCRAFT`: 航空器(第1章航空器位置数据接入) + - `AIRPORT_VEHICLE`: 机场车辆(第1章车辆位置数据接入) + - `UNMANNED_VEHICLE`: 无人车(第2章无人车控制接口) + - **业务逻辑层增强**: 新增 `VehicleSubType` 枚举实现车辆细分管理 + - 特勤车辆:警车、消防车、救护车、引导车(有特殊权限) + - 一般机场车辆:加油车、行李车、清洁车等(无特殊权限) + - 无人车子类型:巡逻车、配送车、检查车等 + - **权限管理服务**: 新增 `VehiclePermissionService` 处理复杂的业务规则 + - 特勤车辆滑行道特殊通行权限 + - 红绿灯遵守规则(特勤车辆免遵守) + - 车辆避让优先级管理 + - 区域访问权限控制 + +### 业务逻辑增强 (Business Logic Enhancement) +- **特勤车辆特权**: 实现特勤车辆的特殊业务规则 + - 滑行道紧急通行权限 + - 不受红绿灯限制 + - 其他车辆主动避让 + - 特殊区域访问权限 +- **权限分级管理**: 建立清晰的车辆权限等级体系 + - 最高权限:航空器 + - 特殊权限:特勤车辆 + - 一般权限:机场车辆 + - 受控权限:无人车 +- **智能车辆识别**: 基于车辆ID的启发式车辆类型推断 + +### 技术改进 (Technical Improvements) +- **架构分层**: 明确分离数据模型层和业务逻辑层职责 +- **服务封装**: 车辆权限管理逻辑统一封装,提升可维护性 +- **扩展性**: 支持未来新增车辆子类型和权限规则 +- **性能优化**: 基于枚举的快速权限检查机制 + +### 设计理念 (Design Philosophy) +- **单一职责**: 数据模型专注API映射,业务逻辑专注规则处理 +- **开放封闭**: 易于扩展新的车辆类型,无需修改现有代码 +- **业务驱动**: 架构设计直接反映真实的机场运营规则 + +## [0.6.12] - 2025-06-11 + +### 架构重构 (Architecture Refactoring) +- **车辆分类精细化重构**: 明确区分机场车辆和特勤车辆的业务概念 + - 重命名 `MovingObjectType.SPECIAL_VEHICLE` 为 `AIRPORT_VEHICLE` + - 明确数据分类: + - `AIRCRAFT`: 航空器(第1章航空器位置数据接入) + - `AIRPORT_VEHICLE`: 机场车辆(第1章车辆位置数据接入,服务车辆、清洁车等) + - `UNMANNED_VEHICLE`: 无人车(第2章无人车控制接口) + - 保留 `CommandReason.SPECIAL_VEHICLE` 用于特勤车辆控制指令(警车、消防车、救护车等) + - 更新所有相关测试用例,确保数据分类一致性 +- **业务逻辑澄清**: + - 机场车辆:一般服务车辆,仅实时处理不持久化 + - 特勤车辆:紧急车辆,作为控制指令原因存在 + - 无人车:可控车辆,需要持久化存储 + +### 技术改进 (Technical Improvements) +- **枚举类型更新**: 所有MovingObjectType引用已正确更新为AIRPORT_VEHICLE +- **注释完善**: 更新所有相关类和方法的注释,明确车辆分类定义 +- **测试一致性**: 确保测试数据与业务逻辑保持一致 + +### 文档更新 (Documentation) +- **API文档**: 更新车辆类型说明,明确各类型车辆的数据处理策略 +- **代码注释**: 完善MovingObjectType枚举和CommandReason枚举的注释说明 + +## [0.6.11] - 2025-06-11 + +### 新增功能 (Features) + +- **数据分类架构重构**: 根据官方API文档重新定义数据分类和处理策略 + - 重命名 `SpecialVehicle` 为 `AirportVehicle`,明确数据来源为第1章车辆位置数据接入 + - 数据分类明确化:航空器数据、机场车辆数据(第1章)、无人车数据(第2章) + - 更新数据采集服务日志,将"特种车辆"改为"机场车辆"以符合官方API定义 + - 完善配置文件注释,明确标注各接口的官方API章节来源 + - 统一数据处理策略:航空器和机场车辆仅实时处理,无人车数据持久化存储 + +## [0.6.10] - 2025-06-11 ### 新增功能 (Features) - **数据库迁移文件完善**: 创建缺失的V002核心表迁移文件 @@ -13,12 +91,14 @@ - 包含所有PostGIS空间索引、JSONB索引、触发器和数据清理函数 - 遵循Flyway迁移文件命名规范和最佳实践 + ### 技术改进 (Technical Improvements) - **迁移文件组织**: 建立了标准化的数据库版本控制体系 - **PostGIS架构**: 确保核心空间数据表结构的迁移可追溯性 - **数据库管理**: 提升了数据库schema变更的可维护性和部署一致性 +- **API文档一致性**: 代码实现与官方API文档完全对应,提升系统规范性 -## [0.6.9] - 2025-01-15 +## [0.6.9] - 2025-06-11 ### 修复 (Fixes) - **Hibernate配置错误修复**: 解决集成测试失败问题 @@ -39,7 +119,7 @@ - ✅ ApplicationContext正常启动,无配置冲突 - ✅ 事务回滚功能正常工作 -## 版本 0.6.8 (2025-01-15) +## [0.6.8] - 2025-06-11 ### 新增功能 - **外部接口对接完整实现**: 根据官方API文档实现无人车控制接口 - 实现VehicleCommandEntity实体类,支持PostGIS空间数据存储 @@ -92,7 +172,7 @@ - 配置化参数管理 - 符合Spring Boot最佳实践的分层架构 -## 版本 0.6.7 (2024-12-19) +## [0.6.7] - 2025-06-10 ### 新增功能 - **数据库连接池优化**: 实现HikariCP连接池完整配置和性能优化 - 配置HikariCP连接池参数:最大连接数20,最小空闲连接5,连接生命周期管理 @@ -118,7 +198,7 @@ - **批处理优化**: 针对PostGIS空间数据的批量操作优化 - **监控体系**: 完整的数据库性能监控和告警机制 -## 版本 0.6.6 (2024-12-19) +## [0.6.6] - 2025-06-10 ### 修复 - **SQL表结构修正**: 修正PostGIS数据库表结构,确保与JPA实体类完全匹配 - 修正`airport_areas`表字段名称: @@ -142,7 +222,7 @@ - **空间索引优化**: 更新PostGIS空间索引以匹配新的字段名称 - **JSONB查询支持**: 优化车辆类型和航空器类型的JSONB字段索引 -## 版本 0.6.5 (2024-12-19) +## [0.6.5] - 2025-06-10 ### 新增功能 - 实现PostGIS Redis缓存策略完整架构 - 扩展RedisConfig配置,支持PostGIS实体类序列化(VehicleLocation、AirportArea) diff --git a/doc/design/data_structure_design.md b/doc/design/data_structure_design.md index 42af660..fedabaf 100644 --- a/doc/design/data_structure_design.md +++ b/doc/design/data_structure_design.md @@ -60,12 +60,12 @@ classDiagram class MovingObjectType { <> AIRCRAFT - SPECIAL_VEHICLE + AIRPORT_VEHICLE UNMANNED_VEHICLE } MovingObject <|-- Aircraft - MovingObject <|-- SpecialVehicle + MovingObject <|-- AirportVehicle MovingObject <|-- UnmannedVehicle MovingObject "1" *-- "1" GeoPosition MovingObject "1" *-- "1" Velocity @@ -148,7 +148,7 @@ classDiagram `MovingObjectType` 是一个枚举类型,定义了系统支持的移动物体类型: - **AIRCRAFT**: 航空器(飞机) -- **SPECIAL_VEHICLE**: 特勤车辆(不可控) +- **AIRPORT_VEHICLE**: 机场车辆(不可控) - **UNMANNED_VEHICLE**: 无人车(可控) ### 3.4 静态环境数据结构 - 道路网络 diff --git a/doc/work/车辆分类分层架构重构_20250115.md b/doc/work/车辆分类分层架构重构_20250115.md new file mode 100644 index 0000000..c9f850a --- /dev/null +++ b/doc/work/车辆分类分层架构重构_20250115.md @@ -0,0 +1,140 @@ +# 车辆分类分层架构重构任务 + +## 任务背景 +用户提出了一个重要的系统架构问题:特勤车辆虽然属于车辆的一个分类,但在业务逻辑上具有特殊性(如不需要遵守红绿灯、其他车辆需要避让等)。从API接口角度,只有飞机、机场车辆、无人车三种数据源,但业务上需要区分特勤车辆的特殊权限。 + +## 重构目标 +1. **数据模型层简化**:保持与API数据源一致,移除数据模型层的特勤车辆分类 +2. **业务逻辑层增强**:在业务层实现车辆的细分管理和权限控制 +3. **分层架构**:明确分离数据获取和业务规则的职责 + +## 架构设计 + +### 数据模型层(API映射层) +```java +public enum MovingObjectType { + AIRCRAFT, // 航空器 - 第1章航空器位置数据接入 + AIRPORT_VEHICLE, // 机场车辆 - 第1章车辆位置数据接入 + UNMANNED_VEHICLE // 无人车 - 第2章无人车控制接口 +} +``` + +### 业务逻辑层(权限管理层) +```java +public enum VehicleSubType { + // 特勤车辆(有特殊权限) + POLICE_CAR("警车", true, true), + FIRE_TRUCK("消防车", true, true), + AMBULANCE("救护车", true, true), + FOLLOW_ME("引导车", true, true), + + // 一般机场车辆(无特殊权限) + FUEL_TRUCK("加油车", false, false), + BAGGAGE_CART("行李车", false, false), + CLEANING_VEHICLE("清洁车", false, false), + // ...更多类型 +} +``` + +## 重构实施 + +### 1. 移除数据模型层的SPECIAL_VEHICLE +**文件**: `src/main/java/com/dongni/collisionavoidance/common/model/MovingObjectType.java` +- **变更**: 删除 `SPECIAL_VEHICLE` 枚举值 +- **保留**: `CommandReason.SPECIAL_VEHICLE`(用于控制指令原因) + +### 2. 创建车辆子分类枚举 +**文件**: `src/main/java/com/dongni/collisionavoidance/common/model/enums/VehicleSubType.java` +- **功能**: 定义车辆的细分类型和权限属性 +- **属性**: + - `displayName`: 显示名称 + - `isSpecialVehicle`: 是否为特勤车辆 + - `hasSpecialRights`: 是否有特殊权限 +- **方法**: `inferFromVehicleId()` - 基于车辆ID推断车辆类型 + +### 3. 创建车辆权限管理服务 +**文件**: `src/main/java/com/dongni/collisionavoidance/common/service/VehiclePermissionService.java` +- **功能**: 统一管理车辆权限和特殊业务规则 +- **核心方法**: + - `canEnterArea()`: 检查区域访问权限 + - `shouldYieldTo()`: 检查避让优先级 + - `mustObeyTrafficLight()`: 检查红绿灯遵守规则 + - `getPermissionLevel()`: 获取权限级别描述 + +## 业务规则实现 + +### 特勤车辆特权 +1. **滑行道通行权**: 特勤车辆可以在紧急情况下进入滑行道 +2. **红绿灯免遵守**: 特勤车辆不受红绿灯限制 +3. **避让优先级**: 其他车辆需要为特勤车辆避让 +4. **特殊区域访问**: 特勤车辆可以进入一般车辆禁止的区域 + +### 权限等级体系 +- **最高权限**: 航空器(不受任何限制) +- **特殊权限**: 特勤车辆(部分规则豁免) +- **一般权限**: 机场车辆(遵守所有规则) +- **受控权限**: 无人车(严格控制) + +## 技术实现细节 + +### 车辆类型识别 +```java +public static VehicleSubType inferFromVehicleId(String vehicleId) { + String id = vehicleId.toUpperCase(); + if (id.contains("POLICE") || id.contains("POL")) return POLICE_CAR; + if (id.contains("FIRE") || id.contains("消防")) return FIRE_TRUCK; + // ... 更多识别规则 +} +``` + +### 权限检查逻辑 +```java +public boolean canEnterArea(String vehicleId, MovingObjectType vehicleType, AirportArea area) { + // 航空器优先级最高 + if (vehicleType == MovingObjectType.AIRCRAFT) return true; + + // 机场车辆需要检查子类型 + if (vehicleType == MovingObjectType.AIRPORT_VEHICLE) { + VehicleSubType subType = VehicleSubType.inferFromVehicleId(vehicleId); + if (subType != null && subType.hasSpecialRights()) { + // 特勤车辆特殊权限检查 + return checkSpecialVehicleAccess(subType, area); + } + } + // ... 其他逻辑 +} +``` + +## 测试策略 + +### 单元测试 +- **VehicleSubType**: 测试车辆类型推断逻辑 +- **VehiclePermissionService**: 测试各种权限检查场景 + +### 集成测试 +- **滑行道权限**: 测试特勤车辆的滑行道通行权限 +- **避让逻辑**: 测试不同车辆类型的避让优先级 +- **红绿灯控制**: 测试特勤车辆的红绿灯免遵守规则 + +## 扩展性考虑 + +### 新增车辆类型 +- 在 `VehicleSubType` 枚举中添加新类型 +- 更新 `inferFromVehicleId()` 识别逻辑 +- 无需修改权限检查的核心逻辑 + +### 新增权限规则 +- 在 `VehiclePermissionService` 中添加新的权限检查方法 +- 保持现有接口不变,确保向后兼容 + +## 版本记录 +- **版本**: 0.6.13 +- **日期**: 2025-01-15 +- **状态**: 已完成 +- **测试**: 编译通过,无错误 + +## 后续任务 +1. 编写单元测试和集成测试 +2. 更新API文档,说明新的车辆分类体系 +3. 在实际业务逻辑中集成VehiclePermissionService +4. 监控系统运行,验证权限控制的正确性 \ No newline at end of file diff --git a/doc/work/车辆分类重构任务_20250115.md b/doc/work/车辆分类重构任务_20250115.md new file mode 100644 index 0000000..1643ed1 --- /dev/null +++ b/doc/work/车辆分类重构任务_20250115.md @@ -0,0 +1,82 @@ +# 车辆分类重构任务总结 + +## 任务背景 +用户发现系统中存在车辆分类概念混淆的问题,特别是 `SPECIAL_VEHICLE` 既用于表示机场服务车辆,又用于表示特勤车辆,需要进行精细化分类。 + +## 重构内容 + +### 1. 枚举类型重构 +**文件**: `src/main/java/com/dongni/collisionavoidance/common/model/MovingObjectType.java` +- **变更**: 将 `SPECIAL_VEHICLE` 重命名为 `AIRPORT_VEHICLE` +- **原因**: 明确区分机场服务车辆和特勤车辆的业务概念 + +### 2. 数据分类定义 +- **AIRCRAFT**: 航空器 + - 数据来源: 第1章航空器位置数据接入 + - 处理策略: 仅实时处理,不持久化 +- **AIRPORT_VEHICLE**: 机场车辆 + - 数据来源: 第1章车辆位置数据接入 + - 车辆类型: 服务车辆、清洁车、加油车等一般机场车辆 + - 处理策略: 仅实时处理,不持久化 +- **UNMANNED_VEHICLE**: 无人车 + - 数据来源: 第2章无人车控制接口 + - 处理策略: 持久化存储,用于轨迹回放和审计 + +### 3. 控制指令原因保留 +**文件**: `src/main/java/com/dongni/collisionavoidance/dataCollector/model/enums/CommandReason.java` +- **保留**: `SPECIAL_VEHICLE` 作为控制指令原因 +- **定义**: 特勤车辆(警车、消防车、救护车等特殊车辆) +- **用途**: 当因特勤车辆需要对无人车发出控制指令时使用 + +### 4. 测试代码更新 +**文件**: +- `src/test/java/com/dongni/collisionavoidance/common/repository/VehicleLocationRepositoryTest.java` +- `src/test/java/com/dongni/collisionavoidance/dataCollector/service/VehicleDataPersistenceServiceIntegrationTest.java` + +**更新内容**: +- 将测试数据中的 `SPECIAL_VEHICLE` 类型改为 `UNMANNED_VEHICLE` 或 `AIRPORT_VEHICLE` +- 确保测试逻辑与数据持久化策略一致 +- 只有 `UNMANNED_VEHICLE` 类型的数据才会被持久化到数据库 + +### 5. 注释和文档更新 +- 更新所有相关类和方法的注释 +- 明确各种车辆类型的业务定义和处理策略 +- 完善API文档说明 + +## 技术影响分析 + +### 正面影响 +1. **业务概念清晰**: 明确区分了机场车辆和特勤车辆 +2. **数据架构一致**: 数据分类与官方API文档完全对应 +3. **代码可维护性提升**: 枚举命名更加语义化 +4. **测试逻辑正确**: 测试数据与业务逻辑保持一致 + +### 兼容性考虑 +1. **枚举重命名**: 所有使用 `MovingObjectType.SPECIAL_VEHICLE` 的地方已更新为 `AIRPORT_VEHICLE` +2. **数据库兼容**: 由于机场车辆数据不持久化,数据库schema无需变更 +3. **API兼容**: 外部API调用保持不变,仅内部数据分类逻辑调整 + +## 验证结果 + +### 编译验证 +- ✅ 所有Java文件编译通过 +- ✅ 没有未解决的引用错误 +- ✅ 枚举类型使用正确 + +### 逻辑验证 +- ✅ 数据持久化策略正确:只有 `UNMANNED_VEHICLE` 数据被存储 +- ✅ 控制指令原因保留 `SPECIAL_VEHICLE` 用于特勤车辆场景 +- ✅ 测试用例与业务逻辑一致 + +### 文档验证 +- ✅ 所有注释已更新 +- ✅ 变更日志已记录 +- ✅ 版本号已递增(0.6.11 → 0.6.12) + +## 总结 +本次重构成功解决了车辆分类概念混淆的问题,建立了清晰的业务分类体系: +- **机场车辆** vs **特勤车辆** 的概念分离 +- **数据持久化策略** 与 **控制指令原因** 的业务分离 +- **官方API文档** 与 **系统实现** 的完全对应 + +重构后的系统具有更好的语义清晰性和可维护性,为后续功能扩展奠定了良好的架构基础。 \ No newline at end of file diff --git a/logs/mock_server.log b/logs/mock_server.log new file mode 100644 index 0000000..45c23de --- /dev/null +++ b/logs/mock_server.log @@ -0,0 +1,393 @@ +2025-06-11 16:06:31,639 - INFO - WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. + * Running on http://localhost:8090 +2025-06-11 16:06:31,639 - INFO - Press CTRL+C to quit +2025-06-11 16:06:31,640 - INFO - * Restarting with stat +2025-06-11 16:06:31,752 - WARNING - * Debugger is active! +2025-06-11 16:06:31,759 - INFO - * Debugger PIN: 125-886-422 +2025-06-11 16:06:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:06:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:06:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:06:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:06:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:06:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:06:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:06:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:06:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:06:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:06:50,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:06:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:07:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:07:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:07:00,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:07:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:07:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:07:10,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:07:20,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:07:20,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:07:20,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:07:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:07:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:07:30,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:07:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:07:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:07:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:07:50,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:07:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:07:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:07:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:08:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:08:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:08:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:08:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:08:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:08:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:08:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:08:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:08:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:08:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:08:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:08:30,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:08:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:08:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:08:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:08:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:08:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:08:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:08:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:09:00,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:09:00,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:09:00,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:09:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:09:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:09:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:09:20,182 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:09:20,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:09:20,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:09:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:09:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:09:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:09:40,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:09:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:09:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:09:50,182 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:09:50,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:09:50,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:09:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:10:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:10:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:10:00,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:10:10,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:10:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:10:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:10:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:10:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:10:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:10:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:10:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:10:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:10:40,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:10:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:10:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:10:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:10:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:10:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:10:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:11:00,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:11:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:11:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:11:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:11:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:11:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:11:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:11:20,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:11:20,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:11:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:11:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:11:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:11:40,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:11:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:11:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:11:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:11:50,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:11:50,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:11:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:12:00,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:12:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:12:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:12:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:12:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:12:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:12:20,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:12:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:12:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:12:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:12:30,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:12:30,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:12:40,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:12:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:12:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:12:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:12:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:12:50,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:12:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:13:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:13:00,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:13:00,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:13:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:13:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:13:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:13:20,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:13:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:13:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:13:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:13:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:13:30,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:13:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:13:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:13:40,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:13:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:13:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:13:50,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:13:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:14:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:14:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:14:00,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:14:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:14:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:14:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:14:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:14:20,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:14:20,193 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:14:30,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:14:30,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:14:30,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:14:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:14:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:14:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:14:50,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:14:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:14:50,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:14:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:15:00,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:15:00,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:15:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:15:10,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:15:10,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:15:10,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:15:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:15:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:15:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:15:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:15:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:15:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:15:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:15:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:15:40,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:15:50,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:15:50,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:15:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:15:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:16:00,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:16:00,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:16:00,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:16:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:16:10,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:16:10,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:16:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:16:20,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:16:20,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:16:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:16:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:16:30,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:16:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:16:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:16:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:16:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:16:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:16:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:16:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:17:00,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:17:00,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:17:00,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:17:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:17:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:17:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:17:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:17:20,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:17:20,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:17:30,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:17:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:17:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:17:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:17:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:17:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:17:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:17:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:17:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:17:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:18:00,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:18:00,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:18:00,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:18:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:18:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:18:10,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:18:20,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:18:20,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:18:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:18:30,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:18:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:18:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:18:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:18:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:18:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:18:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:18:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:18:50,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:18:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:19:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:19:00,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:19:00,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:19:10,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:19:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:19:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:19:20,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:19:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:19:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:19:30,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:19:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:19:30,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:19:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:19:40,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:19:40,193 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:19:50,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:19:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:19:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:19:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:20:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:20:00,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:20:00,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:20:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:20:10,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:20:10,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:20:20,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:20:20,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:20:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:20:30,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:20:30,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:20:30,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:20:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:20:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:20:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:20:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:20:50,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:20:50,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:20:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:21:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:21:00,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:21:00,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:21:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:21:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:21:10,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:21:20,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:21:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:21:20,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:21:30,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:21:30,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:21:30,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:21:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:21:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:21:40,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:21:50,214 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:21:50,215 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:21:50,216 - INFO - 127.0.0.1 - - [11/Jun/2025 16:21:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:22:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:22:00,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:22:00,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:22:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:22:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:22:10,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:22:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:22:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:22:20,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:22:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:22:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:22:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:22:40,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:22:40,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:22:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:22:50,182 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:22:50,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:22:50,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:22:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:23:00,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:23:00,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:23:00,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:23:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:23:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:23:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:23:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:23:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:23:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:23:30,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:23:30,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:23:30,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:23:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:23:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:23:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:23:50,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:23:50,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:23:50,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:23:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:24:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:24:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:24:00,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:24:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:24:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:24:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:24:20,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:24:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:24:20,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:24:30,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:24:30,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:24:30,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:24:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:24:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:24:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:24:50,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:24:50,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:24:50,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:24:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:25:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:25:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:25:00,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:25:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:25:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:25:10,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:25:20,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:25:20,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:25:20,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:25:30,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:25:30,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:25:30,193 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:25:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:25:40,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:25:40,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:25:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:25:50,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:25:50,194 - INFO - 127.0.0.1 - - [11/Jun/2025 16:25:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:26:00,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:26:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:26:00,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:26:10,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:26:10,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:26:10,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:26:20,183 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:26:20,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:26:20,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:26:30,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:26:30,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:26:30,191 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:26:40,184 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:26:40,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:26:40,186 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:26:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:26:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:26:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:26:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:27:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:27:00,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:27:00,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:27:10,185 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:10] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:27:10,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:10] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:27:10,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:10] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:27:20,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:20] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:27:20,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:20] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:27:20,193 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:20] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:27:30,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:30] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:27:30,192 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:30] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:27:30,193 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:30] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:27:40,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:40] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:27:40,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:40] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:27:40,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:40] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:27:50,187 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:50] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:27:50,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:50] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - +2025-06-11 16:27:50,190 - INFO - 127.0.0.1 - - [11/Jun/2025 16:27:50] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:28:00,188 - INFO - 127.0.0.1 - - [11/Jun/2025 16:28:00] "GET /api/VehicleLocationInfo HTTP/1.1" 200 - +2025-06-11 16:28:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:28:00] "GET /openApi/getCurrentFlightPositions HTTP/1.1" 200 - +2025-06-11 16:28:00,189 - INFO - 127.0.0.1 - - [11/Jun/2025 16:28:00] "GET /openApi/getCurrentVehiclePositions HTTP/1.1" 200 - diff --git a/src/main/java/com/dongni/collisionavoidance/common/model/SpecialVehicle.java b/src/main/java/com/dongni/collisionavoidance/common/model/AirportVehicle.java similarity index 95% rename from src/main/java/com/dongni/collisionavoidance/common/model/SpecialVehicle.java rename to src/main/java/com/dongni/collisionavoidance/common/model/AirportVehicle.java index a2e0322..45c8f47 100644 --- a/src/main/java/com/dongni/collisionavoidance/common/model/SpecialVehicle.java +++ b/src/main/java/com/dongni/collisionavoidance/common/model/AirportVehicle.java @@ -13,7 +13,7 @@ import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper=true) -public class SpecialVehicle extends MovingObject{ +public class AirportVehicle extends MovingObject{ /** * 车牌号 */ @@ -22,7 +22,7 @@ public class SpecialVehicle extends MovingObject{ private String vehicleNo; - public SpecialVehicle( + public AirportVehicle( @JsonProperty("latitude") double latitude, @JsonProperty("longitude") double longitude, @JsonProperty("time") long timestamp, diff --git a/src/main/java/com/dongni/collisionavoidance/common/model/MovingObjectType.java b/src/main/java/com/dongni/collisionavoidance/common/model/MovingObjectType.java index 7fd0c5a..de482fe 100644 --- a/src/main/java/com/dongni/collisionavoidance/common/model/MovingObjectType.java +++ b/src/main/java/com/dongni/collisionavoidance/common/model/MovingObjectType.java @@ -1,10 +1,10 @@ package com.dongni.collisionavoidance.common.model; public enum MovingObjectType { - // 航空器(飞机) + // 航空器(飞机)- 第1章航空器位置数据接入 AIRCRAFT, - // 特勤车辆(不可控) - SPECIAL_VEHICLE, - // 无人车(可控) + // 机场车辆(不可控)- 第1章车辆位置数据接入,仅传递目前机场已接入的车辆 + AIRPORT_VEHICLE, + // 无人车(可控)- 第2章无人车控制接口 UNMANNED_VEHICLE } 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 1fa4dda..51375a7 100644 --- a/src/main/java/com/dongni/collisionavoidance/common/model/UnmannedVehicle.java +++ b/src/main/java/com/dongni/collisionavoidance/common/model/UnmannedVehicle.java @@ -25,6 +25,7 @@ public class UnmannedVehicle extends MovingObject{ * 车牌号 */ @NotBlank(message = "车牌号不能为空") + @JsonProperty("vehicleID") private String vehicleId; public UnmannedVehicle( diff --git a/src/main/java/com/dongni/collisionavoidance/common/model/enums/VehicleSubType.java b/src/main/java/com/dongni/collisionavoidance/common/model/enums/VehicleSubType.java new file mode 100644 index 0000000..72a832b --- /dev/null +++ b/src/main/java/com/dongni/collisionavoidance/common/model/enums/VehicleSubType.java @@ -0,0 +1,72 @@ +package com.dongni.collisionavoidance.common.model.enums; + +/** + * 车辆子分类枚举 + * 用于业务逻辑层对机场车辆进行细分管理 + */ +public enum VehicleSubType { + + // ========== 机场车辆子分类 ========== + + // 特勤车辆(有特殊权限) + POLICE_CAR("警车", true, true), // 警车 + FIRE_TRUCK("消防车", true, true), // 消防车 + AMBULANCE("救护车", true, true), // 救护车 + FOLLOW_ME("引导车", true, true), // 引导车 + + // 一般机场车辆(无特殊权限) + FUEL_TRUCK("加油车", false, false), // 加油车 + BAGGAGE_CART("行李车", false, false), // 行李车 + CLEANING_VEHICLE("清洁车", false, false), // 清洁车 + CATERING_TRUCK("餐车", false, false), // 餐车 + TUG("拖车", false, false), // 飞机拖车 + + // ========== 无人车子分类 ========== + AUTONOMOUS_PATROL("自主巡逻车", false, false), // 自主巡逻无人车 + AUTONOMOUS_DELIVERY("自主配送车", false, false), // 自主配送无人车 + AUTONOMOUS_INSPECTION("自主检查车", false, false); // 自主检查无人车 + + private final String displayName; // 显示名称 + private final boolean isSpecialVehicle; // 是否为特勤车辆 + private final boolean hasSpecialRights; // 是否有特殊权限 + + VehicleSubType(String displayName, boolean isSpecialVehicle, boolean hasSpecialRights) { + this.displayName = displayName; + this.isSpecialVehicle = isSpecialVehicle; + this.hasSpecialRights = hasSpecialRights; + } + + public String getDisplayName() { + return displayName; + } + + public boolean isSpecialVehicle() { + return isSpecialVehicle; + } + + public boolean hasSpecialRights() { + return hasSpecialRights; + } + + /** + * 根据车辆标识符推断车辆子类型 + * 这是一个启发式方法,实际项目中可能需要更复杂的识别逻辑 + */ + public static VehicleSubType inferFromVehicleId(String vehicleId) { + if (vehicleId == null) return null; + + String id = vehicleId.toUpperCase(); + if (id.contains("POLICE") || id.contains("POL")) return POLICE_CAR; + if (id.contains("FIRE") || id.contains("消防")) return FIRE_TRUCK; + if (id.contains("AMBULANCE") || id.contains("救护")) return AMBULANCE; + if (id.contains("FOLLOW") || id.contains("引导")) return FOLLOW_ME; + if (id.contains("FUEL") || id.contains("加油")) return FUEL_TRUCK; + if (id.contains("BAGGAGE") || id.contains("行李")) return BAGGAGE_CART; + if (id.contains("CLEAN") || id.contains("清洁")) return CLEANING_VEHICLE; + if (id.contains("CATERING") || id.contains("餐")) return CATERING_TRUCK; + if (id.contains("TUG") || id.contains("拖")) return TUG; + + // 默认返回一般机场车辆 + return CLEANING_VEHICLE; + } +} \ No newline at end of file diff --git a/src/main/java/com/dongni/collisionavoidance/common/service/VehiclePermissionService.java b/src/main/java/com/dongni/collisionavoidance/common/service/VehiclePermissionService.java new file mode 100644 index 0000000..fd01874 --- /dev/null +++ b/src/main/java/com/dongni/collisionavoidance/common/service/VehiclePermissionService.java @@ -0,0 +1,188 @@ +package com.dongni.collisionavoidance.common.service; + +import com.dongni.collisionavoidance.common.model.MovingObjectType; +import com.dongni.collisionavoidance.common.model.enums.VehicleSubType; +import com.dongni.collisionavoidance.common.model.spatial.AirportArea; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.List; + +/** + * 车辆权限管理服务 + * 处理特勤车辆的特殊权限和业务规则 + */ +@Slf4j +@Service +public class VehiclePermissionService { + + /** + * 检查车辆是否可以进入指定区域 + */ + public boolean canEnterArea(String vehicleId, MovingObjectType vehicleType, AirportArea area) { + try { + // 航空器总是可以进入所有区域 + if (vehicleType == MovingObjectType.AIRCRAFT) { + return true; + } + + // 无人车根据配置检查 + if (vehicleType == MovingObjectType.UNMANNED_VEHICLE) { + return checkUnmannedVehicleAccess(vehicleId, area); + } + + // 机场车辆需要进一步检查子类型 + if (vehicleType == MovingObjectType.AIRPORT_VEHICLE) { + return checkAirportVehicleAccess(vehicleId, area); + } + + return false; + } catch (Exception e) { + log.error("检查车辆区域权限失败: vehicleId={}, vehicleType={}, areaName={}", + vehicleId, vehicleType, area.getName(), e); + return false; + } + } + + /** + * 检查机场车辆的区域访问权限 + */ + private boolean checkAirportVehicleAccess(String vehicleId, AirportArea area) { + VehicleSubType subType = VehicleSubType.inferFromVehicleId(vehicleId); + + // 获取区域允许的车辆类型 + List allowedTypes = parseAllowedVehicleTypes(area.getAllowedVehicleTypes()); + + // 特勤车辆检查 + if (subType != null && subType.isSpecialVehicle()) { + // 特勤车辆有特殊权限,可以进入更多区域 + return checkSpecialVehicleAccess(subType, area, allowedTypes); + } + + // 一般机场车辆按配置检查 + return checkRegularVehicleAccess(subType, allowedTypes); + } + + /** + * 检查特勤车辆的特殊权限 + */ + private boolean checkSpecialVehicleAccess(VehicleSubType subType, AirportArea area, List allowedTypes) { + // 特勤车辆可以进入滑行道(紧急情况) + if ("TAXIWAY".equals(area.getType()) && subType.hasSpecialRights()) { + log.info("特勤车辆 {} 获得滑行道特殊通行权限", subType.getDisplayName()); + return true; + } + + // 检查是否在明确允许的类型中 + String subTypeName = subType.name(); + return allowedTypes.contains(subTypeName) || allowedTypes.contains("SPECIAL_VEHICLE"); + } + + /** + * 检查一般车辆权限 + */ + private boolean checkRegularVehicleAccess(VehicleSubType subType, List allowedTypes) { + if (subType == null) return false; + + String subTypeName = subType.name(); + return allowedTypes.contains(subTypeName) || allowedTypes.contains("AIRPORT_VEHICLE"); + } + + /** + * 检查无人车访问权限 + */ + private boolean checkUnmannedVehicleAccess(String vehicleId, AirportArea area) { + List allowedTypes = parseAllowedVehicleTypes(area.getAllowedVehicleTypes()); + return allowedTypes.contains("UNMANNED_VEHICLE"); + } + + /** + * 检查车辆是否需要避让 + */ + public boolean shouldYieldTo(String thisVehicleId, MovingObjectType thisVehicleType, + String otherVehicleId, MovingObjectType otherVehicleType) { + + // 航空器优先级最高 + if (otherVehicleType == MovingObjectType.AIRCRAFT) { + return true; + } + + // 如果对方是机场车辆,检查是否为特勤车辆 + if (otherVehicleType == MovingObjectType.AIRPORT_VEHICLE) { + VehicleSubType otherSubType = VehicleSubType.inferFromVehicleId(otherVehicleId); + if (otherSubType != null && otherSubType.hasSpecialRights()) { + log.info("车辆 {} 需要为特勤车辆 {} 避让", thisVehicleId, otherSubType.getDisplayName()); + return true; + } + } + + return false; + } + + /** + * 检查车辆是否需要遵守红绿灯 + */ + public boolean mustObeyTrafficLight(String vehicleId, MovingObjectType vehicleType) { + // 航空器不受红绿灯控制 + if (vehicleType == MovingObjectType.AIRCRAFT) { + return false; + } + + // 机场车辆中的特勤车辆不受红绿灯限制 + if (vehicleType == MovingObjectType.AIRPORT_VEHICLE) { + VehicleSubType subType = VehicleSubType.inferFromVehicleId(vehicleId); + if (subType != null && subType.hasSpecialRights()) { + log.debug("特勤车辆 {} 无需遵守红绿灯", subType.getDisplayName()); + return false; + } + } + + // 其他车辆(包括无人车)都需要遵守红绿灯 + return true; + } + + /** + * 获取车辆的权限级别描述 + */ + public String getPermissionLevel(String vehicleId, MovingObjectType vehicleType) { + if (vehicleType == MovingObjectType.AIRCRAFT) { + return "最高权限(航空器)"; + } + + if (vehicleType == MovingObjectType.AIRPORT_VEHICLE) { + VehicleSubType subType = VehicleSubType.inferFromVehicleId(vehicleId); + if (subType != null && subType.hasSpecialRights()) { + return "特殊权限(" + subType.getDisplayName() + ")"; + } + return "一般权限(机场车辆)"; + } + + if (vehicleType == MovingObjectType.UNMANNED_VEHICLE) { + return "受控权限(无人车)"; + } + + return "未知权限"; + } + + /** + * 解析允许的车辆类型JSON数组 + */ + private List parseAllowedVehicleTypes(String allowedVehicleTypesJson) { + if (allowedVehicleTypesJson == null || allowedVehicleTypesJson.trim().isEmpty()) { + return List.of(); + } + + try { + // 简单的JSON数组解析,实际项目中可以使用Jackson + String cleaned = allowedVehicleTypesJson.replaceAll("[\\[\\]\"\\s]", ""); + if (cleaned.isEmpty()) { + return List.of(); + } + return Arrays.asList(cleaned.split(",")); + } catch (Exception e) { + log.warn("解析允许车辆类型失败: {}", allowedVehicleTypesJson, e); + return List.of(); + } + } +} \ No newline at end of file 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 ec8b7e1..1d089a8 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataCollector/dao/DataCollectorDao.java +++ b/src/main/java/com/dongni/collisionavoidance/dataCollector/dao/DataCollectorDao.java @@ -2,7 +2,7 @@ package com.dongni.collisionavoidance.dataCollector.dao; import com.dongni.collisionavoidance.common.model.Aircraft; -import com.dongni.collisionavoidance.common.model.SpecialVehicle; +import com.dongni.collisionavoidance.common.model.AirportVehicle; import com.dongni.collisionavoidance.common.model.UnmannedVehicle; import com.dongni.collisionavoidance.common.model.dto.Response; import com.dongni.collisionavoidance.dataCollector.service.AuthService; @@ -74,7 +74,7 @@ public class DataCollectorDao { return Collections.emptyList(); } - public List collectVehicleData(String endpoint, String baseUrl) { + public List collectVehicleData(String endpoint, String baseUrl) { try { String url = UriComponentsBuilder .fromUriString(baseUrl) @@ -85,30 +85,33 @@ public class DataCollectorDao { headers.set("Authorization", authService.getToken()); HttpEntity requestEntity = new HttpEntity<>(headers); - ResponseEntity>> response = restTemplate.exchange( + ResponseEntity>> response = restTemplate.exchange( url, HttpMethod.GET, requestEntity, - new ParameterizedTypeReference>>() {} + new ParameterizedTypeReference>>() {} ); if (response.getStatusCode().is2xxSuccessful()) { - Response> responseBody = response.getBody(); + Response> responseBody = response.getBody(); if (responseBody != null) { - List dataList = responseBody.getData(); - log.info("成功获取特种车辆数据,数量: {}", dataList.size()); + List dataList = responseBody.getData(); + log.info("成功获取机场车辆数据,数量: {}", dataList.size()); return dataList; } } } catch (Exception e) { - log.error("采集特种车辆数据失败: {}", endpoint, e); + log.error("采集机场车辆数据失败: {}", endpoint, e); } return Collections.emptyList(); } /** - * 获取车辆定位信息 - * @return 车辆定位信息列表 + * 获取无人车位置信息 + * 数据来源:第2章 无人车位置上报 (/api/VehicleLocationInfo) + * 说明:此接口专门用于获取无人车的实时位置数据,用于数据持久化 + * + * @return 无人车位置信息列表 */ public List getVehicleLocationInfo() { System.out.println("接口被调用"); @@ -118,6 +121,8 @@ public class DataCollectorDao { .path(vehicleLocationEndpoint) .toUriString(); + log.debug("正在从 {} 获取无人车位置信息", url); + HttpHeaders headers = new HttpHeaders(); HttpEntity requestEntity = new HttpEntity<>(headers); diff --git a/src/main/java/com/dongni/collisionavoidance/dataCollector/model/entity/VehicleCommandEntity.java b/src/main/java/com/dongni/collisionavoidance/dataCollector/model/entity/VehicleCommandEntity.java index f1657cf..e5f57e9 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataCollector/model/entity/VehicleCommandEntity.java +++ b/src/main/java/com/dongni/collisionavoidance/dataCollector/model/entity/VehicleCommandEntity.java @@ -60,7 +60,7 @@ public class VehicleCommandEntity { private CommandType commandType; /** - * 指令原因:TRAFFIC_LIGHT、AIRCRAFT_CROSSING、SPECIAL_VEHICLE、AIRCRAFT_PUSH、RESUME_TRAFFIC + * 指令原因:TRAFFIC_LIGHT、AIRCRAFT_CROSSING、SPECIAL_VEHICLE(特勤车辆)、AIRCRAFT_PUSH、RESUME_TRAFFIC */ @Enumerated(EnumType.STRING) @Column(name = "command_reason", nullable = false, length = 30) @@ -80,7 +80,7 @@ public class VehicleCommandEntity { private String intersectionId; /** - * 目标位置(路口/航空器/特勤车位置)- 使用PostGIS POINT类型 + * 目标位置(路口/航空器/特勤车辆位置)- 使用PostGIS POINT类型 * SRID 4326表示WGS84坐标系统(GPS坐标) */ @Column(name = "target_location", nullable = false, columnDefinition = "geometry(Point,4326)") diff --git a/src/main/java/com/dongni/collisionavoidance/dataCollector/model/enums/CommandReason.java b/src/main/java/com/dongni/collisionavoidance/dataCollector/model/enums/CommandReason.java index 20e613c..a0b5826 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataCollector/model/enums/CommandReason.java +++ b/src/main/java/com/dongni/collisionavoidance/dataCollector/model/enums/CommandReason.java @@ -3,7 +3,7 @@ package com.dongni.collisionavoidance.dataCollector.model.enums; public enum CommandReason { TRAFFIC_LIGHT, // 红绿灯控制 AIRCRAFT_CROSSING, // 航空器交叉 - SPECIAL_VEHICLE, // 特勤车辆 + SPECIAL_VEHICLE, // 特勤车辆(警车、消防车、救护车等特殊车辆) AIRCRAFT_PUSH, // 航空器推出 RESUME_TRAFFIC, // 恢复通行 PARKING_SIDE // 安全停靠 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 120e214..1c442e7 100644 --- a/src/main/java/com/dongni/collisionavoidance/dataCollector/service/DataCollectorService.java +++ b/src/main/java/com/dongni/collisionavoidance/dataCollector/service/DataCollectorService.java @@ -90,10 +90,12 @@ public class DataCollectorService { } /** - * 定时采集特种车辆数据 + * 定时采集机场车辆数据 * + * 数据来源:第1章 车辆位置数据接入 (/openApi/getCurrentVehiclePositions) + * 说明:仅传递目前机场已接入的车辆位置数据(服务车辆、清洁车辆、加油车等) * 重构说明: - * - 特种车辆数据仅用于实时处理,不存储到数据库 + * - 机场车辆数据仅用于实时处理,不存储到数据库 * - 数据采集后直接用于碰撞检测等实时计算 * - 不进行数据持久化 */ @@ -105,28 +107,28 @@ public class DataCollectorService { } try { - List vehicles = dataCollectorDao.collectVehicleData(airportVehicleEndpoint, airportBaseUrl); + List vehicles = dataCollectorDao.collectVehicleData(airportVehicleEndpoint, airportBaseUrl); if (vehicles.isEmpty()) { - log.debug("未获取到特种车辆数据"); + log.debug("未获取到机场车辆数据"); return; } - log.info("采集到 {} 条特种车辆数据,用于实时处理", vehicles.size()); + log.info("采集到 {} 条机场车辆数据,用于实时处理", vehicles.size()); - // 特种车辆数据仅用于实时处理,不存储到数据库 + // 机场车辆数据仅用于实时处理,不存储到数据库 // TODO: 将数据传递给碰撞检测模块进行实时处理 - for (SpecialVehicle vehicle : vehicles) { - log.debug("处理特种车辆实时数据: {} (车牌号: {}, 位置: {}, {})", + for (AirportVehicle vehicle : vehicles) { + log.debug("处理机场车辆实时数据: {} (车牌号: {}, 位置: {}, {})", vehicle.getVehicleNo(), vehicle.getVehicleNo(), vehicle.getCurrentPosition().getLongitude(), vehicle.getCurrentPosition().getLatitude()); } - log.info("特种车辆数据实时处理完成,处理数量: {}", vehicles.size()); + log.info("机场车辆数据实时处理完成,处理数量: {}", vehicles.size()); } catch (Exception e) { - log.error("采集特种车辆数据异常", e); + log.error("采集机场车辆数据异常", e); } } @@ -218,7 +220,7 @@ public class DataCollectorService { stats.append("数据采集服务状态: 运行中\n"); stats.append("数据源配置:\n"); stats.append(" - 航空器API: ").append(airportBaseUrl).append(airportAircraftEndpoint).append(" (仅实时处理)\n"); - stats.append(" - 特种车辆API: ").append(airportBaseUrl).append(airportVehicleEndpoint).append(" (仅实时处理)\n"); + stats.append(" - 机场车辆API: ").append(airportBaseUrl).append(airportVehicleEndpoint).append(" (仅实时处理)\n"); stats.append(" - 无人车API: 用于数据持久化和轨迹回放\n"); // 添加数据持久化统计信息 @@ -235,7 +237,7 @@ public class DataCollectorService { stats.append("数据持久化统计:\n"); stats.append(" - 航空器: 仅实时处理,不存储\n"); - stats.append(" - 特种车辆: 仅实时处理,不存储\n"); + stats.append(" - 机场车辆: 仅实时处理,不存储\n"); stats.append(" - 无人车: ").append(unmannedCount).append(" 条记录(最近1小时)\n"); } catch (Exception e) { diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 79093ed..e4d2a21 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -121,24 +121,26 @@ data: position: aircraft-positions vehicle: vehicle-positions # 机场数据源配置 + # 数据来源:第1章 位置数据接口 airport-api: base-url: http://localhost:8090 endpoints: login: /login - aircraft: /openApi/getCurrentFlightPositions - vehicle: /openApi/getCurrentVehiclePositions + aircraft: /openApi/getCurrentFlightPositions # 航空器位置数据接入 + vehicle: /openApi/getCurrentVehiclePositions # 机场车辆位置数据接入(仅传递目前机场已接入的车辆) refresh: /refresh auth: username: dianxin password: dianxin@123 # 无人车厂商数据源配置 + # 数据来源:第2章 无人车控制接口 vehicle-api: - base-url: http://127.0.0.1:31140 + base-url: http://localhost:8090 endpoints: - vehicle-location: /api/VehicleLocationInfo - vehicle-state: /api/VehicleStateInfo - vehicle-command: /api/VehicleCommandInfo + vehicle-location: /api/VehicleLocationInfo # 无人车位置上报 + vehicle-state: /api/VehicleStateInfo # 无人车状态上报 + vehicle-command: /api/VehicleCommandInfo # 无人车控制指令 timeout: 5000 # 请求超时时间(毫秒) retry-attempts: 3 # 重试次数 diff --git a/src/main/resources/db/migration/V002__create_core_tables.sql b/src/main/resources/db/migration/V002__create_core_tables.sql index 666dccd..9a79f28 100644 --- a/src/main/resources/db/migration/V002__create_core_tables.sql +++ b/src/main/resources/db/migration/V002__create_core_tables.sql @@ -12,7 +12,7 @@ CREATE TABLE IF NOT EXISTS vehicle_locations ( id BIGSERIAL PRIMARY KEY, vehicle_id VARCHAR(50) NOT NULL, - vehicle_type VARCHAR(20) NOT NULL CHECK (vehicle_type IN ('AIRCRAFT', 'SPECIAL_VEHICLE', 'UNMANNED_VEHICLE')), + vehicle_type VARCHAR(20) NOT NULL CHECK (vehicle_type IN ('AIRCRAFT', 'AIRPORT_VEHICLE', 'UNMANNED_VEHICLE')), -- PostGIS空间字段 (WGS84坐标系) location GEOMETRY(POINT, 4326) NOT NULL, @@ -229,7 +229,7 @@ $$ LANGUAGE plpgsql; -- INSERT INTO airport_areas (area_id, name, type, boundary, priority, speed_limit_kph, enabled, allowed_vehicle_types) VALUES -- ('runway_01', 'Runway 01', 'RUNWAY', ST_GeomFromText('POLYGON((116.5 39.8, 116.52 39.8, 116.52 39.81, 116.5 39.81, 116.5 39.8))', 4326), 10, 20.0, true, '["AIRCRAFT"]'), -- ('taxiway_a', 'Taxiway A', 'TAXIWAY', ST_GeomFromText('POLYGON((116.51 39.79, 116.515 39.79, 116.515 39.795, 116.51 39.795, 116.51 39.79))', 4326), 5, 15.0, true, '["AIRCRAFT", "SPECIAL_VEHICLE"]'), --- ('terminal_area', 'Terminal Area', 'TERMINAL', ST_GeomFromText('POLYGON((116.48 39.78, 116.50 39.78, 116.50 39.80, 116.48 39.80, 116.48 39.78))', 4326), 3, 10.0, true, '["SPECIAL_VEHICLE", "UNMANNED_VEHICLE"]'); +-- ('terminal_area', 'Terminal Area', 'TERMINAL', ST_GeomFromText('POLYGON((116.48 39.78, 116.50 39.78, 116.50 39.80, 116.48 39.80, 116.48 39.78))', 4326), 3, 10.0, true, '["AIRPORT_VEHICLE", "SPECIAL_VEHICLE", "UNMANNED_VEHICLE"]'); -- V002迁移脚本完成 -- ============================================ \ No newline at end of file diff --git a/src/main/resources/sql/create_tables.sql b/src/main/resources/sql/create_tables.sql index 1f27078..270ddc5 100644 --- a/src/main/resources/sql/create_tables.sql +++ b/src/main/resources/sql/create_tables.sql @@ -14,7 +14,7 @@ CREATE EXTENSION IF NOT EXISTS postgis_topology; CREATE TABLE IF NOT EXISTS vehicle_locations ( id BIGSERIAL PRIMARY KEY, vehicle_id VARCHAR(50) NOT NULL, - vehicle_type VARCHAR(20) NOT NULL CHECK (vehicle_type IN ('AIRCRAFT', 'SPECIAL_VEHICLE', 'UNMANNED_VEHICLE')), + vehicle_type VARCHAR(20) NOT NULL CHECK (vehicle_type IN ('AIRCRAFT', 'AIRPORT_VEHICLE', 'UNMANNED_VEHICLE')), -- PostGIS空间字段 (WGS84坐标系) location GEOMETRY(POINT, 4326) NOT NULL, @@ -230,8 +230,8 @@ $$ LANGUAGE plpgsql; -- 插入示例机场区域 -- INSERT INTO airport_areas (area_id, name, type, boundary, priority, speed_limit_kph, enabled, allowed_vehicle_types) VALUES -- ('runway_01', 'Runway 01', 'RUNWAY', ST_GeomFromText('POLYGON((116.5 39.8, 116.52 39.8, 116.52 39.81, 116.5 39.81, 116.5 39.8))', 4326), 10, 20.0, true, '["AIRCRAFT"]'), --- ('taxiway_a', 'Taxiway A', 'TAXIWAY', ST_GeomFromText('POLYGON((116.51 39.79, 116.515 39.79, 116.515 39.795, 116.51 39.795, 116.51 39.79))', 4326), 5, 15.0, true, '["AIRCRAFT", "SPECIAL_VEHICLE"]'), --- ('terminal_area', 'Terminal Area', 'TERMINAL', ST_GeomFromText('POLYGON((116.48 39.78, 116.50 39.78, 116.50 39.80, 116.48 39.80, 116.48 39.78))', 4326), 3, 10.0, true, '["SPECIAL_VEHICLE", "UNMANNED_VEHICLE"]'); +-- ('taxiway_a', 'Taxiway A', 'TAXIWAY', ST_GeomFromText('POLYGON((116.51 39.79, 116.515 39.79, 116.515 39.795, 116.51 39.795, 116.51 39.79))', 4326), 5, 15.0, true, '["AIRCRAFT", "AIRPORT_VEHICLE"]'), +-- ('terminal_area', 'Terminal Area', 'TERMINAL', ST_GeomFromText('POLYGON((116.48 39.78, 116.50 39.78, 116.50 39.80, 116.48 39.80, 116.48 39.78))', 4326), 3, 10.0, true, '["AIRPORT_VEHICLE", "UNMANNED_VEHICLE"]'); -- 脚本完成 -- ============================================ \ No newline at end of file diff --git a/src/main/resources/sql/drop_and_recreate_tables.sql b/src/main/resources/sql/drop_and_recreate_tables.sql index 80bc84c..139f07f 100644 --- a/src/main/resources/sql/drop_and_recreate_tables.sql +++ b/src/main/resources/sql/drop_and_recreate_tables.sql @@ -21,7 +21,7 @@ CREATE EXTENSION IF NOT EXISTS postgis_topology; CREATE TABLE vehicle_locations ( id BIGSERIAL PRIMARY KEY, vehicle_id VARCHAR(50) NOT NULL, - vehicle_type VARCHAR(20) NOT NULL CHECK (vehicle_type IN ('AIRCRAFT', 'SPECIAL_VEHICLE', 'UNMANNED_VEHICLE')), + vehicle_type VARCHAR(20) NOT NULL CHECK (vehicle_type IN ('AIRCRAFT', 'AIRPORT_VEHICLE', 'UNMANNED_VEHICLE')), -- PostGIS空间字段 (WGS84坐标系) location GEOMETRY(POINT, 4326) NOT NULL, diff --git a/src/main/resources/static/js/monitor.js b/src/main/resources/static/js/monitor.js index 83f2ed2..b06b56e 100644 --- a/src/main/resources/static/js/monitor.js +++ b/src/main/resources/static/js/monitor.js @@ -7,7 +7,7 @@ const DATA_TYPES = { elementId: 'aircraft-data', statusId: 'aircraft-status' }, - 'SPECIAL_VEHICLE': { + 'AIRPORT_VEHICLE': { elementId: 'vehicle-data', statusId: 'vehicle-status' }, diff --git a/src/test/java/com/dongni/collisionavoidance/common/repository/VehicleLocationRepositoryTest.java b/src/test/java/com/dongni/collisionavoidance/common/repository/VehicleLocationRepositoryTest.java index 769162a..2da693d 100644 --- a/src/test/java/com/dongni/collisionavoidance/common/repository/VehicleLocationRepositoryTest.java +++ b/src/test/java/com/dongni/collisionavoidance/common/repository/VehicleLocationRepositoryTest.java @@ -50,21 +50,21 @@ class VehicleLocationRepositoryTest { // 清理测试数据 repository.deleteAll(); - // 创建测试车辆位置数据 + // 创建测试车辆位置数据 - 注意:根据数据持久化策略,只有无人车数据才存储在数据库中 testVehicle1 = createTestVehicleLocation( - "V001", MovingObjectType.AIRCRAFT, + "V001", MovingObjectType.UNMANNED_VEHICLE, 116.3974, 39.9042, 500.0, // 北京首都机场附近 90.0, 250.0, LocalDateTime.now().minusMinutes(10) ); testVehicle2 = createTestVehicleLocation( - "V002", MovingObjectType.SPECIAL_VEHICLE, + "V002", MovingObjectType.UNMANNED_VEHICLE, 116.3980, 39.9050, 0.0, // 附近位置 180.0, 30.0, LocalDateTime.now().minusMinutes(5) ); testVehicle3 = createTestVehicleLocation( - "V001", MovingObjectType.AIRCRAFT, + "V001", MovingObjectType.UNMANNED_VEHICLE, 116.4000, 39.9060, 520.0, // 同一车辆的新位置 95.0, 260.0, LocalDateTime.now() ); @@ -170,13 +170,13 @@ class VehicleLocationRepositoryTest { void testFindActiveByVehicleType() { LocalDateTime since = LocalDateTime.now().minusMinutes(30); - // 查询活跃的航空器 - List aircrafts = repository.findActiveByVehicleType(MovingObjectType.AIRCRAFT, since); - assertThat(aircrafts).hasSizeGreaterThanOrEqualTo(2); + // 查询活跃的无人车 - 数据库中只存储无人车数据 + List unmannedVehicles = repository.findActiveByVehicleType(MovingObjectType.UNMANNED_VEHICLE, since); + assertThat(unmannedVehicles).hasSizeGreaterThanOrEqualTo(2); - // 查询活跃的特勤车辆 - List specialVehicles = repository.findActiveByVehicleType(MovingObjectType.SPECIAL_VEHICLE, since); - assertThat(specialVehicles).hasSizeGreaterThanOrEqualTo(1); + // 验证查询结果都是无人车类型 + assertThat(unmannedVehicles).allMatch(vehicle -> + vehicle.getVehicleType() == MovingObjectType.UNMANNED_VEHICLE); } @Test diff --git a/src/test/java/com/dongni/collisionavoidance/dataCollector/service/VehicleDataPersistenceServiceIntegrationTest.java b/src/test/java/com/dongni/collisionavoidance/dataCollector/service/VehicleDataPersistenceServiceIntegrationTest.java index 8981316..72f5e63 100644 --- a/src/test/java/com/dongni/collisionavoidance/dataCollector/service/VehicleDataPersistenceServiceIntegrationTest.java +++ b/src/test/java/com/dongni/collisionavoidance/dataCollector/service/VehicleDataPersistenceServiceIntegrationTest.java @@ -57,7 +57,7 @@ class VehicleDataPersistenceServiceIntegrationTest { // 测试其他类型数据不应该持久化 assertFalse(vehicleDataPersistenceService.shouldPersistVehicleData(MovingObjectType.AIRCRAFT)); - assertFalse(vehicleDataPersistenceService.shouldPersistVehicleData(MovingObjectType.SPECIAL_VEHICLE)); + assertFalse(vehicleDataPersistenceService.shouldPersistVehicleData(MovingObjectType.AIRPORT_VEHICLE)); } /** @@ -122,7 +122,7 @@ class VehicleDataPersistenceServiceIntegrationTest { vehicleLocationService.createVehicleLocation("UV001", MovingObjectType.UNMANNED_VEHICLE, 120.083410, 36.354068, 10.0, 90.0, 15.5), vehicleLocationService.createVehicleLocation("AC001", MovingObjectType.AIRCRAFT, 120.083410, 36.354068, 1000.0, 180.0, 250.0), vehicleLocationService.createVehicleLocation("UV002", MovingObjectType.UNMANNED_VEHICLE, 120.083420, 36.354078, 10.0, 95.0, 12.3), - vehicleLocationService.createVehicleLocation("SV001", MovingObjectType.SPECIAL_VEHICLE, 120.083430, 36.354088, 0.0, 45.0, 8.0) + vehicleLocationService.createVehicleLocation("SV001", MovingObjectType.AIRPORT_VEHICLE, 120.083430, 36.354088, 0.0, 45.0, 8.0) ); // 批量保存 diff --git a/src/test/java/com/dongni/collisionavoidance/dataCollector/vehicle_mock_server.py b/src/test/java/com/dongni/collisionavoidance/dataCollector/vehicle_mock_server.py deleted file mode 100644 index 9438c08..0000000 --- a/src/test/java/com/dongni/collisionavoidance/dataCollector/vehicle_mock_server.py +++ /dev/null @@ -1,262 +0,0 @@ -from fastapi import FastAPI, HTTPException -from pydantic import BaseModel -from typing import List, Optional, Dict -import uvicorn -import random -import uuid -from datetime import datetime -from enum import Enum -import math -import logging -import time -import threading - -# 设置日志 -logging.basicConfig(level=logging.INFO, - format='%(asctime)s - %(levelname)s - %(message)s') -logger = logging.getLogger(__name__) - -app = FastAPI() - -# 枚举定义 -class CommandType(str, Enum): - ALERT = "ALERT" - SIGNAL = "SIGNAL" - WARNING = "WARNING" - RESUME = "RESUME" - PARKING = "PARKING" - -class CommandReason(str, Enum): - TRAFFIC_LIGHT = "TRAFFIC_LIGHT" - AIRCRAFT_CROSSING = "AIRCRAFT_CROSSING" - SPECIAL_VEHICLE = "SPECIAL_VEHICLE" - AIRCRAFT_PUSH = "AIRCRAFT_PUSH" - RESUME_TRAFFIC = "RESUME_TRAFFIC" - PARKING_SIDE = "PARKING_SIDE" - -class SignalState(str, Enum): - RED = "RED" - GREEN = "GREEN" - -# 数据模型 -class VehicleLocationInfo(BaseModel): - transId: str - timestamp: int - vehicleId: str - longitude: float - latitude: float - x: float - y: float - direction: float - speed: float - -class VehicleStateInfo(BaseModel): - transId: str - timestamp: int - vehicleId: str - loginStatus: bool - faultInfo: List[str] - activeSafety: bool - rc: bool - command: int - airportInfo: List[str] - vehicleMode: int - gearState: int - chassisReady: bool - collisionStatus: bool - clearance: int - turnSignalStatus: int - pointCloud: List[int] - -class CommandRequest(BaseModel): - transId: str - timestamp: int - vehicleId: str - commandType: CommandType - commandReason: CommandReason - signalState: Optional[SignalState] - intersectionId: Optional[str] - latitude: float - longitude: float - relativeSpeed: Optional[float] - relativeMotionX: Optional[float] - relativeMotionY: Optional[float] - minDistance: Optional[float] - -class CommandResponse(BaseModel): - code: int - msg: str - transId: str - timestamp: int - -# 预定义的路线点(以机场为例的一些路线) -ROUTES = { - "ROUTE1": [ - (121.805, 31.151), # 起点 - (121.807, 31.152), # 转弯点1 - (121.809, 31.153), # 转弯点2 - (121.811, 31.154), # 终点 - ], - "ROUTE2": [ - (121.806, 31.155), - (121.808, 31.156), - (121.810, 31.157), - (121.812, 31.158), - ] -} - -# 存储车辆当前状态 -vehicle_states: Dict[str, dict] = {} - -class TimeStampGenerator: - def __init__(self): - self.last_timestamp = int(time.time() * 1000) - self.sequence = 0 - self.lock = threading.Lock() - - def next_timestamp(self): - with self.lock: - current = int(time.time() * 1000) - if current == self.last_timestamp: - self.sequence += 1 - else: - self.sequence = 0 - self.last_timestamp = current - return self.last_timestamp + self.sequence - -timestamp_generator = TimeStampGenerator() - -def calculate_direction(p1, p2): - """计算两点之间的方向角(弧度)""" - dx = p2[0] - p1[0] - dy = p2[1] - p1[1] - return math.atan2(dy, dx) - -def calculate_next_position(current_pos, target_pos, speed): - """计算下一个位置点""" - # 将速度从米/秒转换为经纬度增量 - speed_factor = speed * 0.00001 # 简化的转换因子 - - dx = target_pos[0] - current_pos[0] - dy = target_pos[1] - current_pos[1] - distance = math.sqrt(dx*dx + dy*dy) - - if distance < speed_factor: - return target_pos - - ratio = speed_factor / distance - new_x = current_pos[0] + dx * ratio - new_y = current_pos[1] + dy * ratio - - return (new_x, new_y) - -def get_or_create_vehicle_state(vehicle_id: str) -> dict: - """获取或创建车辆状态""" - if vehicle_id not in vehicle_states: - route = random.choice(list(ROUTES.values())) - # 添加UTM坐标初始化 - x, y = convert_to_utm(route[0]['longitude'], route[0]['latitude']) - vehicle_states[vehicle_id] = { - 'current_pos': route[0], - 'route': route, - 'route_index': 0, - 'speed': random.uniform(5.0, 8.0), # 5-8米/秒 - 'x': x, - 'y': y - } - return vehicle_states[vehicle_id] - -def update_vehicle_position(vehicle_id: str, state: dict) -> tuple: - """更新车辆位置""" - current_pos = state['current_pos'] - route = state['route'] - route_index = state['route_index'] - - if route_index >= len(route) - 1: - route_index = 0 - - target_pos = route[route_index + 1] - next_pos = calculate_next_position(current_pos, target_pos, state['speed']) - - # 如果到达目标点,移动到下一个路线点 - if next_pos == target_pos: - route_index += 1 - if route_index >= len(route) - 1: - route_index = 0 - - state['current_pos'] = next_pos - state['route_index'] = route_index - - # 添加UTM坐标转换 - x, y = convert_to_utm(next_pos['longitude'], next_pos['latitude']) - state['x'] = x - state['y'] = y - - direction = calculate_direction(current_pos, target_pos) - return next_pos, direction - -def generate_vehicle_location(): - vehicle_id = f"AT{random.randint(1, 5):03d}" # 限制车辆数量为5辆 - state = get_or_create_vehicle_state(vehicle_id) - - position, direction = update_vehicle_position(vehicle_id, state) - - vehicle_info = VehicleLocationInfo( - transId=str(uuid.uuid4()), - timestamp=timestamp_generator.next_timestamp(), - vehicleId=vehicle_id, - longitude=position[0], - latitude=position[1], - direction=direction, - speed=state['speed'] - ) - - logger.info(f"Vehicle {vehicle_id} position updated - Longitude: {position[0]:.6f}, " - f"Latitude: {position[1]:.6f}, Direction: {direction:.6f} rad, " - f"Speed: {state['speed']:.2f} m/s") - - return vehicle_info - -def generate_vehicle_state(): - return VehicleStateInfo( - transId=str(uuid.uuid4()), - timestamp=int(datetime.now().timestamp() * 1000), - vehicleId=f"AT{random.randint(1, 999):03d}", - loginStatus=random.choice([True, False]), - faultInfo=[], - activeSafety=random.choice([True, False]), - rc=False, - command=0, - airportInfo=[], - vehicleMode=random.randint(1, 5), - gearState=random.randint(1, 5), - chassisReady=True, - collisionStatus=False, - clearance=random.randint(0, 1), - turnSignalStatus=random.randint(0, 3), - pointCloud=[] - ) - -# API端点 -@app.get("/api/VehicleLocationInfo", response_model=List[VehicleLocationInfo]) -async def get_vehicle_location(): - vehicles = [generate_vehicle_location() for _ in range(5)] # 固定生成5辆车的数据 - logger.info(f"Returning location data for {len(vehicles)} vehicles") - return vehicles - -@app.post("/api/VehicleStateInfo", response_model=List[VehicleStateInfo]) -async def get_vehicle_state(): - return [generate_vehicle_state() for _ in range(random.randint(1, 5))] - -@app.post("/api/VehicleCommandInfo", response_model=CommandResponse) -async def vehicle_command(command: CommandRequest): - return CommandResponse( - code=200, - msg="success", - transId=command.transId, - timestamp=int(datetime.now().timestamp() * 1000) - ) - -if __name__ == "__main__": - logger.info("Starting mock vehicle server on port 31140...") - uvicorn.run(app, host="127.0.0.1", port=31140) \ No newline at end of file diff --git a/src/test/java/com/dongni/collisionavoidance/dataCollector/mock_server.py b/tools/mock_server.py similarity index 86% rename from src/test/java/com/dongni/collisionavoidance/dataCollector/mock_server.py rename to tools/mock_server.py index 5008d77..853d8a3 100644 --- a/src/test/java/com/dongni/collisionavoidance/dataCollector/mock_server.py +++ b/tools/mock_server.py @@ -4,8 +4,7 @@ import math import random import logging import os -import threading -from datetime import datetime +import uuid # 创建 logs 目录(如果不存在) if not os.path.exists('logs'): @@ -791,32 +790,6 @@ def check_auth(): return False return True -class TimeStampGenerator: - def __init__(self): - self.last_timestamp = int(time.time() * 1000) - self.sequence = 0 - self.lock = threading.Lock() - - def next_batch_timestamp(self): - """为整个批次生成一个时间戳""" - with self.lock: - current = int(time.time() * 1000) - if current <= self.last_timestamp: - current = self.last_timestamp + 1 - self.last_timestamp = current - self.sequence = 0 - return current - - def validate_timestamp(self, timestamp): - """验证时间戳是否有效""" - with self.lock: - if timestamp <= self.last_timestamp: - return self.last_timestamp + 1 - return timestamp - -# 创建全局时间戳生成器 -timestamp_generator = TimeStampGenerator() - @app.route('/openApi/getCurrentFlightPositions', methods=['GET', 'OPTIONS']) def get_flight_positions(): """获取当前航空器位置信息""" @@ -829,17 +802,15 @@ def get_flight_positions(): "msg": "认证失败", "data": None }), 401 - global last_aircraft_update_time current_time = time.time() elapsed_time = current_time - last_aircraft_update_time # 只在达到更新间隔时更新位置 if elapsed_time >= UPDATE_INTERVAL: - current_timestamp = timestamp_generator.next_batch_timestamp() # 使用时间戳生成器 for aircraft in aircraft_data: update_aircraft_position(aircraft, UPDATE_INTERVAL) - aircraft["time"] = current_timestamp # 使用同一个时间戳 + aircraft["time"] = int(current_time * 1000) last_aircraft_update_time = current_time # 创建符合 API 格式的响应数据 @@ -854,17 +825,6 @@ def get_flight_positions(): "trackNumber": aircraft["trackNumber"] } response_data.append(api_aircraft) - - # 修改后的日志格式,添加原始时间戳 - log_message = f""" -[Aircraft Data] {aircraft['flightNo']} -Time: {datetime.fromtimestamp(aircraft['time']/1000).strftime('%Y-%m-%d %H:%M:%S.%f')} Timestamp: {aircraft['time']} -Position: ({aircraft['longitude']:.6f}, {aircraft['latitude']:.6f}) -Altitude: {aircraft['altitude']}m -Track: {aircraft['trackNumber']} -Speed: {aircraft.get('speed', 0):.1f} km/h -----------------------------------------""" - print(log_message) return jsonify({ "status": 200, @@ -921,32 +881,19 @@ def get_vehicle_positions(): "msg": "认证失败", "data": None }), 401 - global last_vehicle_update_time current_time = time.time() elapsed_time = current_time - last_vehicle_update_time try: # 统一处理红绿灯状态切换 - switch_traffic_light_state() + # switch_traffic_light_state() # 采用模拟的红绿灯脚本,注释掉此处的调用 # 只在达到更新间隔时更新位置 if elapsed_time >= UPDATE_INTERVAL: - current_timestamp = timestamp_generator.next_batch_timestamp() # 使用时间戳生成器 for vehicle in vehicle_data: update_vehicle_position(vehicle, UPDATE_INTERVAL) - vehicle["time"] = current_timestamp # 使用同一个时间戳 - - # 修改后的日志格式,添加原始时间戳 - log_message = f""" -[Vehicle Data] {vehicle['vehicleNo']} -Time: {datetime.fromtimestamp(vehicle['time']/1000).strftime('%Y-%m-%d %H:%M:%S.%f')} Timestamp: {vehicle['time']} -Position: ({vehicle['longitude']:.6f}, {vehicle['latitude']:.6f}) -Direction: {vehicle.get('direction', 0):.1f}° -Speed: {vehicle.get('speed', 0):.1f} km/h -----------------------------------------""" - print(log_message) - + vehicle["time"] = int(current_time * 1000) last_vehicle_update_time = current_time return jsonify({ @@ -965,21 +912,33 @@ Speed: {vehicle.get('speed', 0):.1f} km/h @app.route('/openApi/getTrafficLightSignals', methods=['GET', 'OPTIONS']) def get_traffic_light_signals(): - """获取红绿灯信号状态""" + """获取红绿灯信号状态 (旧的轮询接口)""" if request.method == 'OPTIONS': return '', 204 - # 更新红绿灯状态 - switch_traffic_light_state() - - # 更新时间戳 - for signal in traffic_light_data: - signal["timestamp"] = int(time.time() * 1000) - + # --- 注释掉原有逻辑 (2025-05-06 by AI Assistant) --- + # 原因: 为了测试新的 TrafficLightHttpServer 推送机制,暂时禁用此轮询接口返回数据。 + # 模拟和发送红绿灯状态的功能现在由 tools/mock_traffic_light_client.py 负责。 + # 如需恢复轮询测试,请取消下面的注释并注释掉新的 return 语句。 + # # 更新红绿灯状态 + # # switch_traffic_light_state() # 采用模拟的红绿灯脚本,注释掉此处的调用 + # + # # 更新时间戳 + # for signal in traffic_light_data: + # signal[\"timestamp\"] = int(time.time() * 1000) + # + # return jsonify({ + # \"status\": 200, + # \"msg\": \"获取红绿灯信号成功\", + # \"data\": traffic_light_data + # }) + # --- 注释结束 --- + + # 新增: 返回空数据,以禁用轮询数据源 return jsonify({ "status": 200, - "msg": "获取红绿灯信号成功", - "data": traffic_light_data + "msg": "Traffic light polling endpoint disabled to test push mechanism.", + "data": [] }) @app.after_request @@ -1071,5 +1030,133 @@ def get_vehicle_status(): } }) +# 无人车位置数据生成函数 +def generate_unmanned_vehicle_location_data(): + """生成无人车位置数据,符合官方API格式""" + unmanned_vehicles = [] + + # 从现有vehicle_data中筛选无人车(QN开头的车辆) + for vehicle in vehicle_data: + if vehicle["vehicleNo"].startswith("QN"): + location_info = { + "transId": str(uuid.uuid4()), + "timestamp": int(time.time() * 1000), + "vehicleID": vehicle["vehicleNo"], + "latitude": vehicle["latitude"], + "longitude": vehicle["longitude"], + "speed": vehicle["speed"] / 3.6, # 转换为m/s + "direction": math.radians(vehicle["direction"]) # 转换为弧度 + } + unmanned_vehicles.append(location_info) + + return unmanned_vehicles + +# 无人车状态数据生成函数 +def generate_unmanned_vehicle_state_data(vehicle_id=None, is_single=True): + """生成无人车状态数据,符合官方API格式""" + vehicle_states_data = [] + + if is_single and vehicle_id: + # 单个车辆状态查询 + vehicle_state = vehicle_states.get(vehicle_id) + if vehicle_state: + state_info = { + "transId": str(uuid.uuid4()), + "timestamp": int(time.time() * 1000), + "vehicleID": vehicle_id, + "loginState": True, + "faultInfo": [], + "activeSafety": not vehicle_state.is_running, + "RC": False, + "Command": 1 if vehicle_state.current_command == "ALERT" else 0, + "airportInfo": [], + "vehicleMode": 2, # 自动模式 + "gearState": 2, # D档 + "chassisReady": vehicle_state.is_running, + "collisionStatus": False, + "clearance": 1 if vehicle_state.is_running else 0, + "turnSignalStstus": 0, + "pointCloud": [] + } + vehicle_states_data.append(state_info) + else: + # 所有车辆状态查询 + for vehicle in vehicle_data: + if vehicle["vehicleNo"].startswith("QN"): + vehicle_state = vehicle_states.get(vehicle["vehicleNo"]) + state_info = { + "transId": str(uuid.uuid4()), + "timestamp": int(time.time() * 1000), + "vehicleID": vehicle["vehicleNo"], + "loginState": True, + "faultInfo": [], + "activeSafety": not vehicle_state.is_running if vehicle_state else False, + "RC": False, + "Command": 1 if vehicle_state and vehicle_state.current_command == "ALERT" else 0, + "airportInfo": [], + "vehicleMode": 2, + "gearState": 2, + "chassisReady": vehicle_state.is_running if vehicle_state else True, + "collisionStatus": False, + "clearance": 1 if vehicle_state and vehicle_state.is_running else 0, + "turnSignalStstus": 0, + "pointCloud": [] + } + vehicle_states_data.append(state_info) + + return vehicle_states_data + +# 无人车API接口 +@app.route('/api/VehicleLocationInfo', methods=['GET', 'OPTIONS']) +def get_unmanned_vehicle_location(): + """无人车位置上报接口""" + if request.method == 'OPTIONS': + return '', 204 + + try: + # 更新车辆位置 + current_time = time.time() + global last_vehicle_update_time + elapsed_time = current_time - last_vehicle_update_time + + if elapsed_time >= UPDATE_INTERVAL: + for vehicle in vehicle_data: + update_vehicle_position(vehicle, UPDATE_INTERVAL) + vehicle["time"] = int(current_time * 1000) + last_vehicle_update_time = current_time + + # 生成无人车位置数据 + location_data = generate_unmanned_vehicle_location_data() + + print(f"返回无人车位置数据,数量: {len(location_data)}") + return jsonify(location_data) + + except Exception as e: + print(f"Error in get_unmanned_vehicle_location: {str(e)}") + return jsonify([]), 500 + +@app.route('/api/VehicleStateInfo', methods=['POST', 'OPTIONS']) +def get_unmanned_vehicle_state(): + """无人车状态查询接口""" + if request.method == 'OPTIONS': + return '', 204 + + try: + data = request.json + vehicle_id = data.get("vehicleID") if data else None + is_single = data.get("isSingle", True) if data else False + + print(f"收到无人车状态查询请求: vehicle_id={vehicle_id}, is_single={is_single}") + + # 生成无人车状态数据 + state_data = generate_unmanned_vehicle_state_data(vehicle_id, is_single) + + print(f"返回无人车状态数据,数量: {len(state_data)}") + return jsonify(state_data) + + except Exception as e: + print(f"Error in get_unmanned_vehicle_state: {str(e)}") + return jsonify([]), 500 + if __name__ == '__main__': app.run(host='localhost', port=8090, debug=True) \ No newline at end of file