135 lines
4.5 KiB
C++
135 lines
4.5 KiB
C++
#include "AirportBounds.h"
|
|
#include <nlohmann/json.hpp>
|
|
#include <fstream>
|
|
#include <filesystem>
|
|
#include "utils/Logger.h"
|
|
|
|
using json = nlohmann::json;
|
|
|
|
AirportBounds::AirportBounds(const std::string& configFile) {
|
|
// 如果配置文件路径为空,不加载配置
|
|
if (!configFile.empty()) {
|
|
loadConfig(configFile);
|
|
}
|
|
}
|
|
|
|
void AirportBounds::loadConfig(const std::string& configFile) {
|
|
// 检查文件是否存在
|
|
if (!std::filesystem::exists(configFile)) {
|
|
Logger::error("配置文件不存在: ", configFile);
|
|
Logger::error("当前工作目录: ", std::filesystem::current_path().string());
|
|
throw std::runtime_error("配置文件不存在: " + configFile);
|
|
}
|
|
|
|
std::ifstream file(configFile);
|
|
if (!file.is_open()) {
|
|
throw std::runtime_error("无法打开配置文件: " + configFile);
|
|
}
|
|
|
|
try {
|
|
json j;
|
|
file >> j;
|
|
|
|
// 检查必要的字段是否存在
|
|
if (!j.contains("airport") || !j["airport"].contains("bounds")) {
|
|
throw std::runtime_error("配置文件缺少 airport.bounds 字段");
|
|
}
|
|
|
|
// 加载机场边界
|
|
auto& airport = j["airport"]["bounds"];
|
|
airportBounds_ = {
|
|
airport["x"].get<double>(),
|
|
airport["y"].get<double>(),
|
|
airport["width"].get<double>(),
|
|
airport["height"].get<double>()
|
|
};
|
|
|
|
// 检查 areas 字段
|
|
if (!j.contains("areas")) {
|
|
throw std::runtime_error("配置文件缺少 areas 字段");
|
|
}
|
|
|
|
// 加载各区域配置
|
|
for (const auto& [key, value] : j["areas"].items()) {
|
|
AreaType type;
|
|
if (key == "runway") type = AreaType::RUNWAY;
|
|
else if (key == "taxiway") type = AreaType::TAXIWAY;
|
|
else if (key == "gate") type = AreaType::GATE;
|
|
else if (key == "service") type = AreaType::SERVICE;
|
|
else if (key == "test_zone") type = AreaType::TEST_ZONE;
|
|
else continue;
|
|
|
|
// 检查必要的字段
|
|
if (!value.contains("bounds") || !value.contains("config")) {
|
|
throw std::runtime_error("区域 " + key + " 缺少必要的字段");
|
|
}
|
|
|
|
// 加载区域边界
|
|
auto& bounds = value["bounds"];
|
|
areaBounds_[type] = {
|
|
bounds["x"].get<double>(),
|
|
bounds["y"].get<double>(),
|
|
bounds["width"].get<double>(),
|
|
bounds["height"].get<double>()
|
|
};
|
|
|
|
// 加载区域配置
|
|
auto& config = value["config"];
|
|
auto& collision_radius = config["collision_radius"];
|
|
auto& warning_zone_radius = config["warning_zone_radius"];
|
|
auto& alert_zone_radius = config["alert_zone_radius"];
|
|
|
|
RadiusConfig collision_config = {
|
|
collision_radius["aircraft"].get<double>(),
|
|
collision_radius["special"].get<double>(),
|
|
collision_radius["unmanned"].get<double>()
|
|
};
|
|
|
|
RadiusConfig warning_config = {
|
|
warning_zone_radius["aircraft"].get<double>(),
|
|
warning_zone_radius["special"].get<double>(),
|
|
warning_zone_radius["unmanned"].get<double>()
|
|
};
|
|
|
|
RadiusConfig alert_config = {
|
|
alert_zone_radius["aircraft"].get<double>(),
|
|
alert_zone_radius["special"].get<double>(),
|
|
alert_zone_radius["unmanned"].get<double>()
|
|
};
|
|
|
|
areaConfigs_[type] = {
|
|
collision_config,
|
|
config["height_threshold"].get<double>(),
|
|
warning_config,
|
|
alert_config
|
|
};
|
|
}
|
|
}
|
|
catch (const json::exception& e) {
|
|
Logger::error("JSON解析错误: ", e.what());
|
|
throw;
|
|
}
|
|
catch (const std::exception& e) {
|
|
Logger::error("加载配置文件失败: ", e.what());
|
|
throw;
|
|
}
|
|
}
|
|
|
|
AreaType AirportBounds::getAreaType(const Vector2D& position) const {
|
|
// 按优先级检查位置所在区域
|
|
for (const auto& [type, bounds] : areaBounds_) {
|
|
if (bounds.contains(position)) {
|
|
return type;
|
|
}
|
|
}
|
|
// 默认返回测试区
|
|
return AreaType::TEST_ZONE;
|
|
}
|
|
|
|
const AreaConfig& AirportBounds::getAreaConfig(AreaType type) const {
|
|
auto it = areaConfigs_.find(type);
|
|
if (it == areaConfigs_.end()) {
|
|
throw std::runtime_error("Invalid area type");
|
|
}
|
|
return it->second;
|
|
}
|