配置生成逻辑优化
This commit is contained in:
@@ -7,259 +7,11 @@
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include "Config_Default/Config_Default.h"
|
||||
#include "Global.h"
|
||||
#include "Psc_Cpp_Core/Base/Check.h"
|
||||
std::string default_config_directory;
|
||||
namespace {
|
||||
Map_Tile_Source_Config make_local_tile_source(std::string key, std::string name, Map_Tile_Type tile_type,
|
||||
std::vector<std::string> files,
|
||||
std::optional<Map_Tile_Encoding> encoding = std::nullopt) {
|
||||
Map_Tile_Source_Config source;
|
||||
source.key = std::move(key);
|
||||
source.name = std::move(name);
|
||||
source.tile_type = tile_type;
|
||||
source.resource.file_format = Map_Tile_File_Format::mbtiles;
|
||||
source.resource.files = std::move(files);
|
||||
source.resource.y_axis = Map_Tile_Y_Axis::tms;
|
||||
source.resource.extension = ".png";
|
||||
source.resource.tile_size = 256;
|
||||
source.resource.maximum_level = 11;
|
||||
source.resource.encoding = encoding;
|
||||
return source;
|
||||
}
|
||||
Map_Tile_Source_Config make_online_tile_source(std::string key, std::string name, std::string url,
|
||||
std::uint32_t maximum_level) {
|
||||
Map_Tile_Source_Config source;
|
||||
source.key = std::move(key);
|
||||
source.name = std::move(name);
|
||||
source.url = std::move(url);
|
||||
source.resource.file_format = Map_Tile_File_Format::online;
|
||||
source.resource.extension = ".png";
|
||||
source.resource.tile_size = 256;
|
||||
source.resource.maximum_level = maximum_level;
|
||||
return source;
|
||||
}
|
||||
void configure_source_display(Data_Source_Map_Display_Data& display, std::string color,
|
||||
std::uint32_t aircraft_pixel_size, std::uint32_t base_station_pixel_size,
|
||||
double aircraft_scale, bool show_call_sign, bool show_fly_status) {
|
||||
display.color = std::move(color);
|
||||
display.aircraft_pixel_size = aircraft_pixel_size;
|
||||
display.base_station_pixel_size = base_station_pixel_size;
|
||||
display.aircraft_scale = aircraft_scale;
|
||||
display.base_station_scale = 0.44;
|
||||
display.show_call_sign = show_call_sign;
|
||||
display.show_fly_status = show_fly_status;
|
||||
}
|
||||
std::shared_ptr<Dll_Data_Source> make_default_dll_source() {
|
||||
auto source = std::make_shared<Dll_Data_Source>();
|
||||
source->key = "lzy_dll";
|
||||
source->set_enabled(true);
|
||||
source->settings.write([](auto& value) {
|
||||
value.base_station_has_valid_position = true;
|
||||
configure_source_display(value.map_display.map2d, "#454641", 34, 30, 2.0, false, false);
|
||||
configure_source_display(value.map_display.map3d, "#454641", 50, 100, 1.0, false, false);
|
||||
value.lat = 37.433547;
|
||||
value.lon = 121.40873;
|
||||
value.alt = 2300.0;
|
||||
value.ignore_msg_time = true;
|
||||
});
|
||||
source->specific.write([](auto& value) {
|
||||
value.library_path = "@/dll_source.dll";
|
||||
value.function_name = "adsb_read";
|
||||
value.data_type = File_Data_Type::BIN_Blank_Text;
|
||||
value.buffer_size = 200000;
|
||||
});
|
||||
return source;
|
||||
}
|
||||
std::shared_ptr<File_Data_Source> make_default_file_source() {
|
||||
auto source = std::make_shared<File_Data_Source>();
|
||||
source->key = "aaaa";
|
||||
source->set_enabled(false);
|
||||
source->settings.write([](auto& value) {
|
||||
configure_source_display(value.map_display.map2d, "#d1a54c", 50, 100, 2.0, true, true);
|
||||
configure_source_display(value.map_display.map3d, "#d1a54c", 50, 100, 2.0, true, true);
|
||||
value.lat = 37.0;
|
||||
value.lon = 121.0;
|
||||
value.alt = 1000.0;
|
||||
value.ignore_msg_time = true;
|
||||
});
|
||||
source->specific.write([](auto& value) {
|
||||
value.file_path = R"(D:\ae\proj\projects\ECAP_Server\data\BIN_Blank_Text\ADS-B_195_0205.txt)";
|
||||
value.data_type = File_Data_Type::BIN_Blank_Text;
|
||||
value.play_mode = Play_Mode::loop;
|
||||
});
|
||||
return source;
|
||||
}
|
||||
void configure_feed(Data_Feed& feed, std::string type, std::string key, bool enabled, Output_Data_Format format,
|
||||
bool use_status, Mode_S_Output_Type mode_s_output_type, bool use_mode_ac, bool sbs_only_pos) {
|
||||
feed.type = std::move(type);
|
||||
feed.key = std::move(key);
|
||||
feed.set_enabled(enabled);
|
||||
feed.source_key = "lzy_dll";
|
||||
feed.output_format.write([&](auto& value) {
|
||||
value.type = format;
|
||||
value.use_status = use_status;
|
||||
value.mode_s_output_type = mode_s_output_type;
|
||||
value.use_mode_ac = use_mode_ac;
|
||||
value.sbs_only_pos = sbs_only_pos;
|
||||
});
|
||||
}
|
||||
std::shared_ptr<Data_Feed_TCP_Server> make_default_tcp_server_feed(std::string key, bool enabled,
|
||||
Output_Data_Format format, bool use_status,
|
||||
Mode_S_Output_Type mode_s_output_type,
|
||||
bool use_mode_ac, bool sbs_only_pos,
|
||||
std::uint16_t port, std::size_t user_buffer_size,
|
||||
std::size_t system_buffer_size) {
|
||||
auto feed = std::make_shared<Data_Feed_TCP_Server>();
|
||||
configure_feed(*feed, "Data_Feed_TCP_Server", std::move(key), enabled, format, use_status, mode_s_output_type,
|
||||
use_mode_ac, sbs_only_pos);
|
||||
feed->specific.write([&](auto& value) {
|
||||
value.port = port;
|
||||
value.connect_user_buffer_size = user_buffer_size;
|
||||
value.connect_system_buffer_size = system_buffer_size;
|
||||
});
|
||||
return feed;
|
||||
}
|
||||
Psc::JSON make_external_resource(std::string name, std::string download_url, std::string description,
|
||||
std::uint64_t update_interval_seconds, std::time_t last_updated_at) {
|
||||
External_Resources_Data resource;
|
||||
resource.name = std::move(name);
|
||||
resource.download_url = std::move(download_url);
|
||||
resource.description = std::move(description);
|
||||
resource.update_interval_seconds = update_interval_seconds;
|
||||
resource.last_updated_at = last_updated_at;
|
||||
return resource.to_base_json();
|
||||
}
|
||||
void configure_windows_defaults(Config& config) {
|
||||
config.version = "windows_v1.0.5";
|
||||
config.dsp_config.library_path = "@/dll_source.dll";
|
||||
config.dsp_config.center_freq = 16000000;
|
||||
config.dsp_config.band_width = 6000;
|
||||
config.dsp_config.sample_rate = 60000;
|
||||
config.dsp_config.fft_point_number = 2048;
|
||||
config.dsp_config.fft_period_ms = 50;
|
||||
config.dsp_config.fft_win_type = UHD_FFTWin::blkmc;
|
||||
config.dsp_config.frame_rate = 60;
|
||||
config.dsp_config.debug = false;
|
||||
config.drogon_config = Psc::JSON::object({{"app", Psc::JSON::object({{"threads_num", 0},
|
||||
{"client_max_body_size", "1000M"},
|
||||
{"client_max_memory_body_size", "1000M"}})}});
|
||||
config.http_monitor_config.access_log = false;
|
||||
config.http_monitor_config.slow_request_threshold_ms = 3000;
|
||||
config.http_monitor_config.slow_scope_threshold_ms = 1000;
|
||||
config.mlat.settings.write([](auto& value) { value.merge = false; });
|
||||
config.web_server_config.webapp = "@/../third_party/eacp_webapp/wwwroot";
|
||||
config.web_server_config.listen_port = 9081;
|
||||
config.map_resources_config.write([](auto& value) {
|
||||
value.current_imagery_key = "mixed_imagery";
|
||||
value.tile_sources = {
|
||||
make_local_tile_source("mixed_imagery", "本地混合图", Map_Tile_Type::imagery,
|
||||
{"C:/tiles/混合图-世界-0-8.mbtiles", "C:/tiles/混合图-中国-9-10.mbtiles",
|
||||
"C:/tiles/混合图-中国-11.mbtiles"}),
|
||||
make_local_tile_source("height_terrain", "本地高程", Map_Tile_Type::terrain,
|
||||
{"C:/tiles/高程-世界-0-8.mbtiles", "C:/tiles/高程-中国-9-10.mbtiles",
|
||||
"C:/tiles/高程-中国-11.mbtiles"}, Map_Tile_Encoding::terrarium),
|
||||
make_online_tile_source("osm_online", "OpenStreetMap在线", "https://tile.openstreetmap.org/{z}/{x}/{y}.png", 19),
|
||||
make_online_tile_source("osm_hot_online", "OpenStreetMap HOT在线", "https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", 19),
|
||||
make_online_tile_source("cyclosm_online", "CyclOSM在线", "https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_light_online", "Carto Light在线", "https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_dark_online", "Carto Dark在线", "https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_voyager_online", "Carto Voyager在线", "https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_dark_nolabels_online", "Carto Dark无标注在线", "https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("opentopomap_online", "OpenTopoMap在线", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png", 17)};
|
||||
});
|
||||
config.map_view_config.write([](auto& value) {
|
||||
value.scene_mode = Map_Scene_Mode::map_3d;
|
||||
value.map2d.current_imagery_key = "mixed_imagery";
|
||||
value.map2d.current_terrain_key = "terrain";
|
||||
value.map2d.tile_display_maximum_level = 8;
|
||||
value.map3d.current_imagery_key = "mixed_imagery";
|
||||
value.map3d.current_terrain_key = "terrain";
|
||||
value.map3d.tile_display_maximum_level = 19;
|
||||
value.camera.longitude = 122.014707;
|
||||
value.camera.latitude = 35.714108;
|
||||
value.camera.height = 241660.03182;
|
||||
value.camera.heading = 347.582854;
|
||||
value.camera.pitch = -54.917211;
|
||||
value.camera.roll = 359.999884;
|
||||
});
|
||||
config.mode_acs.settings.write([](auto& value) {
|
||||
value.timeout_seconds = 160;
|
||||
value.max_speed_m_s = 1000;
|
||||
value.wait_process_msg = true;
|
||||
value.time_space_filter = true;
|
||||
value.speed_filter = true;
|
||||
value.max_track_point_size = 20000;
|
||||
value.mode_s_max_num = 700000;
|
||||
value.mode_other_max_num = 10000;
|
||||
value.report_data_feed_msg_mum = 10000;
|
||||
value.default_min_aircraft_list_num = 10;
|
||||
});
|
||||
config.mode_acs.data_source_config.map.push_back(make_default_dll_source());
|
||||
config.mode_acs.data_source_config.map.push_back(make_default_file_source());
|
||||
config.mode_acs.data_feed_config.map.push_back(make_default_tcp_server_feed(
|
||||
"Port_10003", true, Output_Data_Format::BIN, true, Mode_S_Output_Type::ALL_Mode_S, true, true, 10003,
|
||||
409600, 409600));
|
||||
auto udp_server = std::make_shared<Data_Feed_UDP_Server>();
|
||||
configure_feed(*udp_server, "Data_Feed_UDP_Server", "22333", false, Output_Data_Format::BIN, false,
|
||||
Mode_S_Output_Type::ALL_Mode_S, false, false);
|
||||
udp_server->specific.write([](auto& value) { value.port = 50001; });
|
||||
config.mode_acs.data_feed_config.map.push_back(udp_server);
|
||||
auto udp_client = std::make_shared<Data_Feed_UDP_Client>();
|
||||
configure_feed(*udp_client, "Data_Feed_UDP_Client", "Port_10004", false, Output_Data_Format::AVR, false,
|
||||
Mode_S_Output_Type::DF_11_17_18, false, true);
|
||||
udp_client->specific.write([](auto& value) {
|
||||
value.port = 30004;
|
||||
value.url = "192.168.1.75";
|
||||
});
|
||||
config.mode_acs.data_feed_config.map.push_back(udp_client);
|
||||
auto tcp_client = std::make_shared<Data_Feed_TCP_Client>();
|
||||
configure_feed(*tcp_client, "Data_Feed_TCP_Client", "Port_10005", false, Output_Data_Format::BIN, true,
|
||||
Mode_S_Output_Type::NO_POS_Mode_S, true, true);
|
||||
tcp_client->specific.write([](auto& value) {
|
||||
value.url = "192.168.1.167";
|
||||
value.port = 10005;
|
||||
});
|
||||
config.mode_acs.data_feed_config.map.push_back(tcp_client);
|
||||
config.mode_acs.data_feed_config.map.push_back(make_default_tcp_server_feed(
|
||||
"Port_30003", false, Output_Data_Format::SBS, false, Mode_S_Output_Type::ALL_Mode_S, true, true, 30003, 0, 0));
|
||||
config.log_config.open_mode = Log_Config::Open_Mode::Delete;
|
||||
config.log_config.piece_num = 10;
|
||||
config.log_config.size_MB = 10;
|
||||
config.console_config.record_playback = false;
|
||||
config.console_config.mode_s_console = false;
|
||||
config.external_resources_manager.ecap_sqlite_path = "@/../data/sqlite/ecap.sqlite";
|
||||
auto external_database = Psc::JSON::object();
|
||||
external_database.append({"ecap_sqlite_path", config.external_resources_manager.ecap_sqlite_path});
|
||||
auto external_resources = Psc::JSON::array();
|
||||
external_resources.append(make_external_resource("tar1090_db_aircraft", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", "wiedehopf/tar1090-db 发布的轻量 ICAO24 飞机静态库,提供注册号、机型、年份和运营方备注。", 604800, 1780388281));
|
||||
external_resources.append(make_external_resource("wiedehopf_tar1090_db_aircraft", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", "wiedehopf/tar1090-db 项目发布的飞机静态数据库镜像,供 tar1090 本地识别飞机。", 604800, 1780381804));
|
||||
external_resources.append(make_external_resource("mictronics_aircraft_database", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", "Mictronics 社区飞机数据库的 tar1090 汇总镜像,可按 ICAO24 查询注册号、机型和运营方。", 604800, 1780381804));
|
||||
external_resources.append(make_external_resource("opensky_aircraft_database", "https://opensky-network.org/datasets/metadata/aircraftDatabase.csv", "OpenSky Network 飞机元数据 CSV,包含制造商、型号、注册号和运营方等字段。", 604800, 1780381804));
|
||||
external_resources.append(make_external_resource("faa_aircraft_registry", "https://registry.faa.gov/database/ReleasableAircraft.zip", "FAA 官方可公开下载的美国飞机注册库,MASTER.txt 包含 Mode-S Hex 注册信息。", 86400, 1780381804));
|
||||
external_resources.append(make_external_resource("icao_doc_8643_aircraft_type_designators", "", "ICAO Doc 8643 机型代码表,用于将 A320、B738 等 designator 映射为制造商、型号和类别。", 2419200, 1780381804));
|
||||
external_resources.append(make_external_resource("vrs_routes", "https://vrs-standing-data.adsb.lol/routes.csv", "VRS 航线表,以 callsign 查询机场代码序列,用于推断起飞机场、经停机场和目的机场。", 3600, 1780381804));
|
||||
external_resources.append(make_external_resource("vrs_airports", "https://vrs-standing-data.adsb.lol/airports.csv", "VRS 机场字典,提供机场代码、名称、国家、经纬度和高度。", 3600, 1780381804));
|
||||
external_resources.append(make_external_resource("adsblol_vrs_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv", "ADSB.lol 发布的 VRS standing-data 航线镜像,以 callsign 查询机场代码序列。", 3600, 1780381804));
|
||||
external_resources.append(make_external_resource("vradarserver_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv", "Virtual Radar Server standing-data 的航线适配表;当前在线更新使用 ADSB.lol 公共镜像。", 3600, 1780381804));
|
||||
external_resources.append(make_external_resource("opensky_flightdata_api_cache", "", "OpenSky FlightData API 查询缓存,按 ICAO24 和时间范围保存历史航班起降机场结果。", 0, 1780381804));
|
||||
external_database.append({"list", external_resources});
|
||||
config.external_resources_manager.from_json(&external_database);
|
||||
config.cesium_graphics_config.settings.write([](auto& value) {
|
||||
value.resolution_scale = 1.0;
|
||||
value.fxaa = true;
|
||||
value.shadows = true;
|
||||
value.enable_lighting = true;
|
||||
value.solar_lighting = true;
|
||||
value.terrain_enabled_in_3d = true;
|
||||
value.terrain_exaggeration = 5.0;
|
||||
value.surface_navigation_reference_visible = true;
|
||||
value.view_axes_visible = true;
|
||||
value.view_axes_panel_x = 3.0;
|
||||
value.view_axes_panel_y = 337.0;
|
||||
value.view_axes_panel_size = 184.0;
|
||||
});
|
||||
}
|
||||
std::filesystem::path config_directory() {
|
||||
if (!default_config_directory.empty()) {
|
||||
return default_config_directory;
|
||||
@@ -270,10 +22,8 @@ std::filesystem::path config_section_path(Config_Section section) {
|
||||
return config_directory() / (std::string(config_section_name(section)) + ".json");
|
||||
}
|
||||
std::array<std::mutex, static_cast<std::size_t>(Config_Section::count)> config_section_mutexes;
|
||||
void write_config_section_unlocked(Config_Section section, const Psc::JSON& value) {
|
||||
const auto directory = config_directory();
|
||||
std::filesystem::create_directories(directory);
|
||||
const auto path = config_section_path(section);
|
||||
void write_config_file_unlocked(const std::filesystem::path& path, const Psc::JSON& value) {
|
||||
std::filesystem::create_directories(path.parent_path());
|
||||
auto temporary = path;
|
||||
temporary += ".tmp";
|
||||
std::ofstream output(temporary, std::ios::binary | std::ios::trunc);
|
||||
@@ -290,6 +40,9 @@ void write_config_section_unlocked(Config_Section section, const Psc::JSON& valu
|
||||
std::filesystem::remove(path, error);
|
||||
std::filesystem::rename(temporary, path);
|
||||
}
|
||||
void write_config_section_unlocked(Config_Section section, const Psc::JSON& value) {
|
||||
write_config_file_unlocked(config_section_path(section), value);
|
||||
}
|
||||
void write_config_section(Config_Section section, const Psc::JSON& value) {
|
||||
std::lock_guard lock(config_section_mutexes[static_cast<std::size_t>(section)]);
|
||||
write_config_section_unlocked(section, value);
|
||||
@@ -306,9 +59,8 @@ Psc::JSON read_existing_config_section_unlocked(Config_Section section) {
|
||||
}
|
||||
void merge_json_object(Psc::JSON& target, const Psc::JSON& value) {
|
||||
for (const auto& child : value.children) {
|
||||
auto iterator = std::find_if(target.children.begin(), target.children.end(), [&](const Psc::JSON& current) {
|
||||
return current.key == child.key;
|
||||
});
|
||||
auto iterator = std::find_if(target.children.begin(), target.children.end(),
|
||||
[&](const Psc::JSON& current) { return current.key == child.key; });
|
||||
if (iterator == target.children.end()) {
|
||||
target.append(child);
|
||||
continue;
|
||||
@@ -319,11 +71,6 @@ void merge_json_object(Psc::JSON& target, const Psc::JSON& value) {
|
||||
*iterator = child;
|
||||
}
|
||||
}
|
||||
Psc::JSON default_config() {
|
||||
Config config;
|
||||
configure_windows_defaults(config);
|
||||
return config.toJson();
|
||||
}
|
||||
[[noreturn]] void config_load_failed(Config_Section section, std::string_view reason) {
|
||||
std::cerr << "配置文件加载失败: 【" << config_section_path(section).string() << "】 配置: 【"
|
||||
<< config_section_name(section) << "】 原因: " << reason << std::endl;
|
||||
@@ -348,30 +95,36 @@ void assign_config_section(Config_Section section, Function&& function) {
|
||||
}
|
||||
Psc::JSON config_section_value(Global& global, Config_Section section) {
|
||||
switch (section) {
|
||||
case Config_Section::version: return Psc::JSON(global.version);
|
||||
case Config_Section::dsp: return global.dsp_config.to_base_json();
|
||||
case Config_Section::drogon: return global.drogon_config;
|
||||
case Config_Section::http_monitor: return global.http_monitor_config.to_base_json();
|
||||
case Config_Section::mlat: return global.mlat.to_base_json();
|
||||
case Config_Section::web_server: return global.web_server_config.to_base_json();
|
||||
case Config_Section::version:
|
||||
return Psc::JSON(global.version);
|
||||
case Config_Section::dsp:
|
||||
return global.dsp_config.to_base_json();
|
||||
case Config_Section::drogon:
|
||||
return global.drogon_config;
|
||||
case Config_Section::http_monitor:
|
||||
return global.http_monitor_config.to_base_json();
|
||||
case Config_Section::mlat:
|
||||
return global.mlat.to_base_json();
|
||||
case Config_Section::web_server:
|
||||
return global.web_server_config.to_base_json();
|
||||
case Config_Section::map_resources:
|
||||
return global.map_resources_config.read([](const auto& value) {
|
||||
return value.to_base_json();
|
||||
});
|
||||
return global.map_resources_config.read([](const auto& value) { return value.to_base_json(); });
|
||||
case Config_Section::map_view:
|
||||
return global.map_view_config.read([](const auto& value) {
|
||||
return value.to_base_json();
|
||||
});
|
||||
return global.map_view_config.read([](const auto& value) { return value.to_base_json(); });
|
||||
case Config_Section::map_models:
|
||||
return global.map_model_config.read([](const auto& value) {
|
||||
return value.to_base_json();
|
||||
});
|
||||
case Config_Section::mode_acs: return global.mode_acs.to_base_json();
|
||||
case Config_Section::log: return global.log_config.to_base_json();
|
||||
case Config_Section::console: return global.console_config.to_base_json();
|
||||
case Config_Section::external_database: return global.external_resources_manager.to_base_json();
|
||||
case Config_Section::cesium_graphics: return global.cesium_graphics_config.to_base_json();
|
||||
case Config_Section::count: break;
|
||||
return global.map_model_config.read([](const auto& value) { return value.to_base_json(); });
|
||||
case Config_Section::mode_acs:
|
||||
return global.mode_acs.to_base_json();
|
||||
case Config_Section::log:
|
||||
return global.log_config.to_base_json();
|
||||
case Config_Section::console:
|
||||
return global.console_config.to_base_json();
|
||||
case Config_Section::external_database:
|
||||
return global.external_resources_manager.to_base_json();
|
||||
case Config_Section::cesium_graphics:
|
||||
return global.cesium_graphics_config.to_base_json();
|
||||
case Config_Section::count:
|
||||
break;
|
||||
}
|
||||
std::terminate();
|
||||
}
|
||||
@@ -417,9 +170,8 @@ void migrate_legacy_source_feed_relations(const Psc::JSON* mode_acs, Data_Source
|
||||
});
|
||||
if (default_relation != list->children.end()) {
|
||||
const auto source_list = sources.map.list();
|
||||
const auto first_source = std::find_if(source_list.begin(), source_list.end(), [](const auto& source) {
|
||||
return source->enabled();
|
||||
});
|
||||
const auto first_source =
|
||||
std::find_if(source_list.begin(), source_list.end(), [](const auto& source) { return source->enabled(); });
|
||||
if (first_source != source_list.end()) {
|
||||
for (const auto& feed : feed_list) {
|
||||
if (!assignments.contains(feed->key))
|
||||
@@ -433,13 +185,14 @@ void migrate_legacy_source_feed_relations(const Psc::JSON* mode_acs, Data_Source
|
||||
feed->source_key = assignment->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
void Data_Topology_View_Config::from_json(const Psc::JSON* that_json) {
|
||||
if (that_json == nullptr || that_json->valueType != Psc::Object)
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "data_topology_view");
|
||||
Get_J(initialized) Get_J(layout_revision) Get_J(zoom) Get_J(pan_x) Get_J(pan_y)
|
||||
if (!std::isfinite(zoom) || zoom <= 0.0 || !std::isfinite(pan_x) || !std::isfinite(pan_y))
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "data_topology_view");
|
||||
Get_J(initialized) Get_J(layout_revision) Get_J(zoom) Get_J(pan_x) Get_J(
|
||||
pan_y) if (!std::isfinite(zoom) || zoom <= 0.0 || !std::isfinite(pan_x) ||
|
||||
!std::isfinite(pan_y)) throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument),
|
||||
"data_topology_view");
|
||||
const auto* positions = that_json->get("node_positions");
|
||||
if (positions == nullptr || positions->valueType != Psc::Object)
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "node_positions");
|
||||
@@ -458,14 +211,19 @@ Psc::JSON Data_Topology_View_Config::to_json() const {
|
||||
auto positions = Psc::JSON::object();
|
||||
for (const auto& [id, position] : node_positions)
|
||||
positions.append({id, Psc::JSON::object({{"x", position.x}, {"y", position.y}})});
|
||||
return Psc::JSON::object({{"initialized", initialized}, {"layout_revision", layout_revision}, {"zoom", zoom}, {"pan_x", pan_x}, {"pan_y", pan_y},
|
||||
return Psc::JSON::object({{"initialized", initialized},
|
||||
{"layout_revision", layout_revision},
|
||||
{"zoom", zoom},
|
||||
{"pan_x", pan_x},
|
||||
{"pan_y", pan_y},
|
||||
{"node_positions", positions}});
|
||||
}
|
||||
Psc::JSON Mode_ACS_Config::to_base_json() const {
|
||||
auto result = settings.read([](const auto& value) { return value.to_base_json(); });
|
||||
result.append(Psc::JSON("data_feed", data_feed_config.to_json()));
|
||||
result.append(Psc::JSON("data_source", data_source_config.to_json()));
|
||||
result.append(Psc::JSON("data_topology_view", data_topology_view.read([](const auto& value) { return value.to_json(); })));
|
||||
result.append(
|
||||
Psc::JSON("data_topology_view", data_topology_view.read([](const auto& value) { return value.to_json(); })));
|
||||
return result;
|
||||
}
|
||||
void Mode_ACS_Config::from_json(const Psc::JSON* that_json) {
|
||||
@@ -482,21 +240,19 @@ void Config::create_missing_config_files() {
|
||||
std::filesystem::create_directories(config_directory());
|
||||
std::error_code ignored_error;
|
||||
std::filesystem::remove(config_directory() / "device.json", ignored_error);
|
||||
const auto defaults = default_config();
|
||||
for (std::size_t index = 0; index < static_cast<std::size_t>(Config_Section::count); ++index) {
|
||||
const auto section = static_cast<Config_Section>(index);
|
||||
if (std::filesystem::exists(config_section_path(section)))
|
||||
continue;
|
||||
const auto* value = defaults.get(config_section_name(section));
|
||||
if (value == nullptr)
|
||||
config_load_failed(section, "内置 Windows 默认配置缺少该分片");
|
||||
const auto file = make_default_config_file(section, config_directory());
|
||||
try {
|
||||
write_config_section(section, *value);
|
||||
std::lock_guard lock(config_section_mutexes[static_cast<std::size_t>(file.section)]);
|
||||
write_config_file_unlocked(file.path, file.value);
|
||||
}
|
||||
catch (const std::exception& error) {
|
||||
config_load_failed(section, error.what());
|
||||
}
|
||||
std::cout << "生成默认配置文件: 【" << config_section_path(section).string() << "】" << std::endl;
|
||||
std::cout << "生成默认配置文件: 【" << file.path.string() << "】" << std::endl;
|
||||
}
|
||||
}
|
||||
Psc::JSON Config::load() {
|
||||
@@ -506,7 +262,8 @@ Psc::JSON Config::load() {
|
||||
const auto section = static_cast<Config_Section>(index);
|
||||
result.append({std::string(config_section_name(section)), read_config_section(section)});
|
||||
}
|
||||
std::cout << get_current_date_string() << " 启动加载配置目录: 【" << config_directory().string() << "】" << std::endl;
|
||||
std::cout << get_current_date_string() << " 启动加载配置目录: 【" << config_directory().string() << "】"
|
||||
<< std::endl;
|
||||
return result;
|
||||
}
|
||||
void Config::from_log_json(const Psc::JSON* that_json) {
|
||||
@@ -515,16 +272,16 @@ void Config::from_log_json(const Psc::JSON* that_json) {
|
||||
void Config::from_base_json(Psc::JSON* that_json) {
|
||||
assign_config_section(Config_Section::version, [&] { Get_J(version) });
|
||||
assign_config_section(Config_Section::mlat, [&] { mlat.from_json(that_json->get("mlat")); });
|
||||
assign_config_section(Config_Section::web_server, [&] { web_server_config.from_base_json(that_json->get("web_server")); });
|
||||
assign_config_section(Config_Section::web_server,
|
||||
[&] { web_server_config.from_base_json(that_json->get("web_server")); });
|
||||
assign_config_section(Config_Section::map_resources, [&] {
|
||||
map_resources_config.write([&](auto& value) { value.from_base_json(that_json->get("map_resources")); });
|
||||
});
|
||||
assign_config_section(Config_Section::map_view, [&] {
|
||||
map_view_config.write([&](auto& value) { value.from_base_json(that_json->get("map_view")); });
|
||||
});
|
||||
assign_config_section(Config_Section::cesium_graphics, [&] {
|
||||
cesium_graphics_config.from_base_json(that_json->get("cesium_graphics"));
|
||||
});
|
||||
assign_config_section(Config_Section::cesium_graphics,
|
||||
[&] { cesium_graphics_config.from_base_json(that_json->get("cesium_graphics")); });
|
||||
assign_config_section(Config_Section::map_models, [&] {
|
||||
map_model_config.write([&](auto& value) { value.from_base_json(that_json->get("map_models")); });
|
||||
});
|
||||
@@ -532,10 +289,10 @@ void Config::from_base_json(Psc::JSON* that_json) {
|
||||
assign_config_section(Config_Section::console, [&] { console_config.from_base_json(that_json->get("console")); });
|
||||
assign_config_section(Config_Section::dsp, [&] { dsp_config.from_json(that_json->get("dsp")); });
|
||||
assign_config_section(Config_Section::drogon, [&] { drogon_config = *that_json->get("drogon"); });
|
||||
assign_config_section(Config_Section::http_monitor, [&] { http_monitor_config.from_base_json(that_json->get("http_monitor")); });
|
||||
assign_config_section(Config_Section::external_database, [&] {
|
||||
external_resources_manager.from_json(that_json->get("external_database"));
|
||||
});
|
||||
assign_config_section(Config_Section::http_monitor,
|
||||
[&] { http_monitor_config.from_base_json(that_json->get("http_monitor")); });
|
||||
assign_config_section(Config_Section::external_database,
|
||||
[&] { external_resources_manager.from_json(that_json->get("external_database")); });
|
||||
}
|
||||
Psc::JSON Web_Server_Config::to_base_json() const {
|
||||
return Psc::JSON::object({{"webapp", webapp}, {"listen_port", listen_port}});
|
||||
@@ -599,7 +356,8 @@ static std::map<std::string, Map_Model_Item_Config> make_default_aircraft_models
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static std::map<std::string, Map_Model_Item_Config> read_model_object_field(const Psc::JSON* json, std::string_view key) {
|
||||
static std::map<std::string, Map_Model_Item_Config> read_model_object_field(const Psc::JSON* json,
|
||||
std::string_view key) {
|
||||
auto field = json->get(key);
|
||||
if (field == nullptr || field->valueType != Psc::Object) {
|
||||
throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key));
|
||||
@@ -818,7 +576,8 @@ void Map_View_Config::from_base_json(const Psc::JSON* that_json) {
|
||||
map2d.from_base_json(that_json->get("map2d"));
|
||||
map3d.from_base_json(that_json->get("map3d"));
|
||||
camera.from_base_json(that_json->get("camera"));
|
||||
base_station_fly_to_height_offset_meters = std::max(100.0, read_double_field(that_json, "base_station_fly_to_height_offset_meters"));
|
||||
base_station_fly_to_height_offset_meters =
|
||||
std::max(100.0, read_double_field(that_json, "base_station_fly_to_height_offset_meters"));
|
||||
}
|
||||
Psc::JSON Map_View_Config::to_base_json() const {
|
||||
auto ret = Psc::JSON::object();
|
||||
@@ -848,9 +607,7 @@ void Cesium_Graphics_Config::from_base_json(const Psc::JSON* that_json) {
|
||||
});
|
||||
}
|
||||
Psc::JSON Cesium_Graphics_Config::to_base_json() const {
|
||||
return settings.read([](const auto& value) {
|
||||
return value.to_base_json();
|
||||
});
|
||||
return settings.read([](const auto& value) { return value.to_base_json(); });
|
||||
}
|
||||
Map_Model_Item_Config::Map_Model_Item_Config(std::string url) : url(std::move(url)) {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_config_file(Config_Section section, const std::filesystem::path& directory) {
|
||||
switch (section) {
|
||||
case Config_Section::version:
|
||||
return make_default_version_config(directory);
|
||||
case Config_Section::dsp:
|
||||
return make_default_dsp_config(directory);
|
||||
case Config_Section::drogon:
|
||||
return make_default_drogon_config(directory);
|
||||
case Config_Section::http_monitor:
|
||||
return make_default_http_monitor_config(directory);
|
||||
case Config_Section::mlat:
|
||||
return make_default_mlat_config(directory);
|
||||
case Config_Section::web_server:
|
||||
return make_default_web_server_config(directory);
|
||||
case Config_Section::map_resources:
|
||||
return make_default_map_resources_config(directory);
|
||||
case Config_Section::map_view:
|
||||
return make_default_map_view_config(directory);
|
||||
case Config_Section::map_models:
|
||||
return make_default_map_models_config(directory);
|
||||
case Config_Section::mode_acs:
|
||||
return make_default_mode_acs_config(directory);
|
||||
case Config_Section::log:
|
||||
return make_default_log_config(directory);
|
||||
case Config_Section::console:
|
||||
return make_default_console_config(directory);
|
||||
case Config_Section::external_database:
|
||||
return make_default_external_database_config(directory);
|
||||
case Config_Section::cesium_graphics:
|
||||
return make_default_cesium_graphics_config(directory);
|
||||
case Config_Section::count:
|
||||
std::terminate();
|
||||
}
|
||||
std::terminate();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
#include <filesystem>
|
||||
#include "../Config.h"
|
||||
struct Default_Config_File {
|
||||
Config_Section section;
|
||||
std::filesystem::path path;
|
||||
Psc::JSON value;
|
||||
};
|
||||
Default_Config_File make_default_config_file(Config_Section section, const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_version_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_dsp_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_drogon_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_http_monitor_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_mlat_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_web_server_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_map_resources_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_map_view_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_map_models_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_mode_acs_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_log_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_console_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_external_database_config(const std::filesystem::path& directory);
|
||||
Default_Config_File make_default_cesium_graphics_config(const std::filesystem::path& directory);
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_cesium_graphics_config(const std::filesystem::path& directory) {
|
||||
Cesium_Graphics_Config config;
|
||||
config.settings.write([](auto& value) {
|
||||
value.resolution_scale = 1.0;
|
||||
value.fxaa = true;
|
||||
value.shadows = true;
|
||||
value.enable_lighting = true;
|
||||
value.solar_lighting = true;
|
||||
value.terrain_enabled_in_3d = true;
|
||||
value.terrain_exaggeration = 5.0;
|
||||
value.surface_navigation_reference_visible = true;
|
||||
value.view_axes_visible = true;
|
||||
value.view_axes_panel_x = 3.0;
|
||||
value.view_axes_panel_y = 337.0;
|
||||
value.view_axes_panel_size = 184.0;
|
||||
});
|
||||
return {Config_Section::cesium_graphics, directory / "cesium_graphics.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_console_config(const std::filesystem::path& directory) {
|
||||
Console_Config config{};
|
||||
config.record_playback = false;
|
||||
config.mode_s_console = false;
|
||||
return {Config_Section::console, directory / "console.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_drogon_config(const std::filesystem::path& directory) {
|
||||
auto app = Psc::JSON::object(
|
||||
{{"threads_num", 0}, {"client_max_body_size", "1000M"}, {"client_max_memory_body_size", "1000M"}});
|
||||
return {Config_Section::drogon, directory / "drogon.json", Psc::JSON::object({{"app", app}})};
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_dsp_config(const std::filesystem::path& directory) {
|
||||
DSP_Config config;
|
||||
config.library_path = ECAP_DEFAULT_DSP_LIBRARY_PATH;
|
||||
config.center_freq = 16000000;
|
||||
config.band_width = 6000;
|
||||
config.sample_rate = 60000;
|
||||
config.fft_point_number = 2048;
|
||||
config.fft_period_ms = 50;
|
||||
config.fft_win_type = UHD_FFTWin::blkmc;
|
||||
config.frame_rate = 60;
|
||||
config.debug = false;
|
||||
return {Config_Section::dsp, directory / "dsp.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "Config_Default.h"
|
||||
namespace {
|
||||
Psc::JSON make_resource(std::string name, std::string download_url, std::string description,
|
||||
std::uint64_t update_interval_seconds, std::time_t last_updated_at) {
|
||||
External_Resources_Data resource;
|
||||
resource.name = std::move(name);
|
||||
resource.download_url = std::move(download_url);
|
||||
resource.description = std::move(description);
|
||||
resource.update_interval_seconds = update_interval_seconds;
|
||||
resource.last_updated_at = last_updated_at;
|
||||
return resource.to_base_json();
|
||||
}
|
||||
} // namespace
|
||||
Default_Config_File make_default_external_database_config(const std::filesystem::path& directory) {
|
||||
External_Resources_Manager config;
|
||||
config.ecap_sqlite_path = ECAP_DEFAULT_SQLITE_PATH;
|
||||
auto value = Psc::JSON::object();
|
||||
value.append({"ecap_sqlite_path", config.ecap_sqlite_path});
|
||||
auto resources = Psc::JSON::array();
|
||||
resources.append(make_resource(
|
||||
"tar1090_db_aircraft", "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz",
|
||||
"wiedehopf/tar1090-db 发布的轻量 ICAO24 飞机静态库,提供注册号、机型、年份和运营方备注。", 604800, 1780388281));
|
||||
resources.append(
|
||||
make_resource("wiedehopf_tar1090_db_aircraft",
|
||||
"https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz",
|
||||
"wiedehopf/tar1090-db 项目发布的飞机静态数据库镜像,供 tar1090 本地识别飞机。", 604800, 1780381804));
|
||||
resources.append(make_resource(
|
||||
"mictronics_aircraft_database",
|
||||
"https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz",
|
||||
"Mictronics 社区飞机数据库的 tar1090 汇总镜像,可按 ICAO24 查询注册号、机型和运营方。", 604800, 1780381804));
|
||||
resources.append(
|
||||
make_resource("opensky_aircraft_database", "https://opensky-network.org/datasets/metadata/aircraftDatabase.csv",
|
||||
"OpenSky Network 飞机元数据 CSV,包含制造商、型号、注册号和运营方等字段。", 604800, 1780381804));
|
||||
resources.append(make_resource("faa_aircraft_registry", "https://registry.faa.gov/database/ReleasableAircraft.zip",
|
||||
"FAA 官方可公开下载的美国飞机注册库,MASTER.txt 包含 Mode-S Hex 注册信息。", 86400,
|
||||
1780381804));
|
||||
resources.append(make_resource(
|
||||
"icao_doc_8643_aircraft_type_designators", "",
|
||||
"ICAO Doc 8643 机型代码表,用于将 A320、B738 等 designator 映射为制造商、型号和类别。", 2419200, 1780381804));
|
||||
resources.append(make_resource("vrs_routes", "https://vrs-standing-data.adsb.lol/routes.csv",
|
||||
"VRS 航线表,以 callsign 查询机场代码序列,用于推断起飞机场、经停机场和目的机场。",
|
||||
3600, 1780381804));
|
||||
resources.append(make_resource("vrs_airports", "https://vrs-standing-data.adsb.lol/airports.csv",
|
||||
"VRS 机场字典,提供机场代码、名称、国家、经纬度和高度。", 3600, 1780381804));
|
||||
resources.append(make_resource("adsblol_vrs_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv",
|
||||
"ADSB.lol 发布的 VRS standing-data 航线镜像,以 callsign 查询机场代码序列。", 3600,
|
||||
1780381804));
|
||||
resources.append(make_resource(
|
||||
"vradarserver_standing_data_routes", "https://vrs-standing-data.adsb.lol/routes.csv",
|
||||
"Virtual Radar Server standing-data 的航线适配表;当前在线更新使用 ADSB.lol 公共镜像。", 3600, 1780381804));
|
||||
resources.append(make_resource("opensky_flightdata_api_cache", "",
|
||||
"OpenSky FlightData API 查询缓存,按 ICAO24 和时间范围保存历史航班起降机场结果。", 0,
|
||||
1780381804));
|
||||
value.append({"list", resources});
|
||||
config.from_json(&value);
|
||||
return {Config_Section::external_database, directory / "external_database.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_http_monitor_config(const std::filesystem::path& directory) {
|
||||
Http_Monitor_Config config;
|
||||
config.access_log = false;
|
||||
config.slow_request_threshold_ms = 3000;
|
||||
config.slow_scope_threshold_ms = 1000;
|
||||
return {Config_Section::http_monitor, directory / "http_monitor.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_log_config(const std::filesystem::path& directory) {
|
||||
Log_Config config;
|
||||
config.open_mode = Log_Config::Open_Mode::Delete;
|
||||
config.piece_num = 10;
|
||||
config.size_MB = 10;
|
||||
return {Config_Section::log, directory / "log.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_map_models_config(const std::filesystem::path& directory) {
|
||||
Map_Model_Config config;
|
||||
return {Config_Section::map_models, directory / "map_models.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "Config_Default.h"
|
||||
namespace {
|
||||
Map_Tile_Source_Config make_local_tile_source(std::string key, std::string name, Map_Tile_Type tile_type,
|
||||
std::vector<std::string> files,
|
||||
std::optional<Map_Tile_Encoding> encoding = std::nullopt) {
|
||||
Map_Tile_Source_Config source;
|
||||
source.key = std::move(key);
|
||||
source.name = std::move(name);
|
||||
source.tile_type = tile_type;
|
||||
source.resource.file_format = Map_Tile_File_Format::mbtiles;
|
||||
source.resource.files = std::move(files);
|
||||
source.resource.y_axis = Map_Tile_Y_Axis::tms;
|
||||
source.resource.extension = ".png";
|
||||
source.resource.tile_size = 256;
|
||||
source.resource.maximum_level = 11;
|
||||
source.resource.encoding = encoding;
|
||||
return source;
|
||||
}
|
||||
Map_Tile_Source_Config make_online_tile_source(std::string key, std::string name, std::string url,
|
||||
std::uint32_t maximum_level) {
|
||||
Map_Tile_Source_Config source;
|
||||
source.key = std::move(key);
|
||||
source.name = std::move(name);
|
||||
source.url = std::move(url);
|
||||
source.resource.file_format = Map_Tile_File_Format::online;
|
||||
source.resource.extension = ".png";
|
||||
source.resource.tile_size = 256;
|
||||
source.resource.maximum_level = maximum_level;
|
||||
return source;
|
||||
}
|
||||
} // namespace
|
||||
Default_Config_File make_default_map_resources_config(const std::filesystem::path& directory) {
|
||||
Map_Resources_Config config;
|
||||
config.current_imagery_key = "mixed_imagery";
|
||||
const auto tile_directory = std::string(ECAP_DEFAULT_TILE_DIRECTORY);
|
||||
config.tile_sources = {
|
||||
make_local_tile_source("mixed_imagery", "本地混合图", Map_Tile_Type::imagery,
|
||||
{tile_directory + "/混合图-世界-0-8.mbtiles", tile_directory + "/混合图-中国-9-10.mbtiles",
|
||||
tile_directory + "/混合图-中国-11.mbtiles"}),
|
||||
make_local_tile_source("height_terrain", "本地高程", Map_Tile_Type::terrain,
|
||||
{tile_directory + "/高程-世界-0-8.mbtiles", tile_directory + "/高程-中国-9-10.mbtiles",
|
||||
tile_directory + "/高程-中国-11.mbtiles"},
|
||||
Map_Tile_Encoding::terrarium),
|
||||
make_online_tile_source("osm_online", "OpenStreetMap在线", "https://tile.openstreetmap.org/{z}/{x}/{y}.png", 19),
|
||||
make_online_tile_source("osm_hot_online", "OpenStreetMap HOT在线",
|
||||
"https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", 19),
|
||||
make_online_tile_source("cyclosm_online", "CyclOSM在线",
|
||||
"https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_light_online", "Carto Light在线",
|
||||
"https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_dark_online", "Carto Dark在线",
|
||||
"https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_voyager_online", "Carto Voyager在线",
|
||||
"https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("carto_dark_nolabels_online", "Carto Dark无标注在线",
|
||||
"https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png", 20),
|
||||
make_online_tile_source("opentopomap_online", "OpenTopoMap在线", "https://a.tile.opentopomap.org/{z}/{x}/{y}.png",
|
||||
17)};
|
||||
return {Config_Section::map_resources, directory / "map_resources.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_map_view_config(const std::filesystem::path& directory) {
|
||||
Map_View_Config config;
|
||||
config.scene_mode = Map_Scene_Mode::map_3d;
|
||||
config.map2d.current_imagery_key = "mixed_imagery";
|
||||
config.map2d.current_terrain_key = "terrain";
|
||||
config.map2d.tile_display_maximum_level = 8;
|
||||
config.map3d.current_imagery_key = "mixed_imagery";
|
||||
config.map3d.current_terrain_key = "terrain";
|
||||
config.map3d.tile_display_maximum_level = 19;
|
||||
config.camera.longitude = 122.014707;
|
||||
config.camera.latitude = 35.714108;
|
||||
config.camera.height = 241660.03182;
|
||||
config.camera.heading = 347.582854;
|
||||
config.camera.pitch = -54.917211;
|
||||
config.camera.roll = 359.999884;
|
||||
return {Config_Section::map_view, directory / "map_view.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_mlat_config(const std::filesystem::path& directory) {
|
||||
MLAT_Config config;
|
||||
config.settings.write([](auto& value) { value.merge = false; });
|
||||
return {Config_Section::mlat, directory / "mlat.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "Config_Default.h"
|
||||
namespace {
|
||||
void configure_source_display(Data_Source_Map_Display_Data& display, std::string color,
|
||||
std::uint32_t aircraft_pixel_size, std::uint32_t base_station_pixel_size,
|
||||
double aircraft_scale, bool show_call_sign, bool show_fly_status) {
|
||||
display.color = std::move(color);
|
||||
display.aircraft_pixel_size = aircraft_pixel_size;
|
||||
display.base_station_pixel_size = base_station_pixel_size;
|
||||
display.aircraft_scale = aircraft_scale;
|
||||
display.base_station_scale = 0.44;
|
||||
display.show_call_sign = show_call_sign;
|
||||
display.show_fly_status = show_fly_status;
|
||||
}
|
||||
std::shared_ptr<Dll_Data_Source> make_dll_source() {
|
||||
auto source = std::make_shared<Dll_Data_Source>();
|
||||
source->key = "lzy_dll";
|
||||
source->set_enabled(true);
|
||||
source->settings.write([](auto& value) {
|
||||
value.base_station_has_valid_position = true;
|
||||
configure_source_display(value.map_display.map2d, "#454641", 34, 30, 2.0, false, false);
|
||||
configure_source_display(value.map_display.map3d, "#454641", 50, 100, 1.0, false, false);
|
||||
value.lat = 37.433547;
|
||||
value.lon = 121.40873;
|
||||
value.alt = 2300.0;
|
||||
value.ignore_msg_time = true;
|
||||
});
|
||||
source->specific.write([](auto& value) {
|
||||
value.library_path = ECAP_DEFAULT_DSP_LIBRARY_PATH;
|
||||
value.function_name = "adsb_read";
|
||||
value.data_type = File_Data_Type::BIN_Blank_Text;
|
||||
value.buffer_size = 200000;
|
||||
});
|
||||
return source;
|
||||
}
|
||||
#if ECAP_DEFAULT_FILE_SOURCE
|
||||
std::shared_ptr<File_Data_Source> make_file_source() {
|
||||
auto source = std::make_shared<File_Data_Source>();
|
||||
source->key = "aaaa";
|
||||
source->set_enabled(false);
|
||||
source->settings.write([](auto& value) {
|
||||
configure_source_display(value.map_display.map2d, "#d1a54c", 50, 100, 2.0, true, true);
|
||||
configure_source_display(value.map_display.map3d, "#d1a54c", 50, 100, 2.0, true, true);
|
||||
value.lat = 37.0;
|
||||
value.lon = 121.0;
|
||||
value.alt = 1000.0;
|
||||
value.ignore_msg_time = true;
|
||||
});
|
||||
source->specific.write([](auto& value) {
|
||||
value.file_path = ECAP_DEFAULT_FILE_SOURCE_PATH;
|
||||
value.data_type = File_Data_Type::BIN_Blank_Text;
|
||||
value.play_mode = Play_Mode::loop;
|
||||
});
|
||||
return source;
|
||||
}
|
||||
#endif
|
||||
void configure_feed(Data_Feed& feed, std::string type, std::string key, bool enabled, Output_Data_Format format,
|
||||
bool use_status, Mode_S_Output_Type mode_s_output_type, bool use_mode_ac, bool sbs_only_pos) {
|
||||
feed.type = std::move(type);
|
||||
feed.key = std::move(key);
|
||||
feed.set_enabled(enabled);
|
||||
feed.source_key = "lzy_dll";
|
||||
feed.output_format.write([&](auto& value) {
|
||||
value.type = format;
|
||||
value.use_status = use_status;
|
||||
value.mode_s_output_type = mode_s_output_type;
|
||||
value.use_mode_ac = use_mode_ac;
|
||||
value.sbs_only_pos = sbs_only_pos;
|
||||
});
|
||||
}
|
||||
std::shared_ptr<Data_Feed_TCP_Server> make_tcp_server_feed(std::string key, bool enabled, Output_Data_Format format,
|
||||
bool use_status, Mode_S_Output_Type mode_s_output_type,
|
||||
bool use_mode_ac, bool sbs_only_pos, std::uint16_t port,
|
||||
std::size_t user_buffer_size,
|
||||
std::size_t system_buffer_size) {
|
||||
auto feed = std::make_shared<Data_Feed_TCP_Server>();
|
||||
configure_feed(*feed, "Data_Feed_TCP_Server", std::move(key), enabled, format, use_status, mode_s_output_type,
|
||||
use_mode_ac, sbs_only_pos);
|
||||
feed->specific.write([&](auto& value) {
|
||||
value.port = port;
|
||||
value.connect_user_buffer_size = user_buffer_size;
|
||||
value.connect_system_buffer_size = system_buffer_size;
|
||||
});
|
||||
return feed;
|
||||
}
|
||||
} // namespace
|
||||
Default_Config_File make_default_mode_acs_config(const std::filesystem::path& directory) {
|
||||
Mode_ACS_Config config;
|
||||
config.settings.write([](auto& value) {
|
||||
value.timeout_seconds = 160;
|
||||
value.max_speed_m_s = 1000;
|
||||
value.wait_process_msg = true;
|
||||
value.time_space_filter = true;
|
||||
value.speed_filter = true;
|
||||
value.max_track_point_size = 20000;
|
||||
value.mode_s_max_num = 700000;
|
||||
value.mode_other_max_num = 10000;
|
||||
value.report_data_feed_msg_mum = 10000;
|
||||
value.default_min_aircraft_list_num = 10;
|
||||
});
|
||||
config.data_source_config.map.push_back(make_dll_source());
|
||||
#if ECAP_DEFAULT_FILE_SOURCE
|
||||
config.data_source_config.map.push_back(make_file_source());
|
||||
#endif
|
||||
config.data_feed_config.map.push_back(make_tcp_server_feed("Port_10003", true, Output_Data_Format::BIN, true,
|
||||
Mode_S_Output_Type::ALL_Mode_S, true, true, 10003,
|
||||
409600, 409600));
|
||||
auto udp_server = std::make_shared<Data_Feed_UDP_Server>();
|
||||
configure_feed(*udp_server, "Data_Feed_UDP_Server", "22333", false, Output_Data_Format::BIN, false,
|
||||
Mode_S_Output_Type::ALL_Mode_S, false, false);
|
||||
udp_server->specific.write([](auto& value) { value.port = 50001; });
|
||||
config.data_feed_config.map.push_back(udp_server);
|
||||
auto udp_client = std::make_shared<Data_Feed_UDP_Client>();
|
||||
configure_feed(*udp_client, "Data_Feed_UDP_Client", "Port_10004", false, Output_Data_Format::AVR, false,
|
||||
Mode_S_Output_Type::DF_11_17_18, false, true);
|
||||
udp_client->specific.write([](auto& value) {
|
||||
value.port = 30004;
|
||||
value.url = "192.168.1.75";
|
||||
});
|
||||
config.data_feed_config.map.push_back(udp_client);
|
||||
auto tcp_client = std::make_shared<Data_Feed_TCP_Client>();
|
||||
configure_feed(*tcp_client, "Data_Feed_TCP_Client", "Port_10005", false, Output_Data_Format::BIN, true,
|
||||
Mode_S_Output_Type::NO_POS_Mode_S, true, true);
|
||||
tcp_client->specific.write([](auto& value) {
|
||||
value.url = "192.168.1.167";
|
||||
value.port = 10005;
|
||||
});
|
||||
config.data_feed_config.map.push_back(tcp_client);
|
||||
config.data_feed_config.map.push_back(make_tcp_server_feed(
|
||||
"Port_30003", false, Output_Data_Format::SBS, false, Mode_S_Output_Type::ALL_Mode_S, true, true, 30003, 0, 0));
|
||||
return {Config_Section::mode_acs, directory / "mode_acs.json", config.to_base_json()};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_version_config(const std::filesystem::path& directory) {
|
||||
return {Config_Section::version, directory / "version.json", Psc::JSON("v1.0.5")};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#include "Config_Default.h"
|
||||
Default_Config_File make_default_web_server_config(const std::filesystem::path& directory) {
|
||||
Web_Server_Config config;
|
||||
config.webapp = ECAP_DEFAULT_WEBAPP_PATH;
|
||||
config.listen_port = 9081;
|
||||
return {Config_Section::web_server, directory / "web_server.json", config.to_base_json()};
|
||||
}
|
||||
Reference in New Issue
Block a user