#ifndef CONFIG_H_H #define CONFIG_H_H #include #include #include #include "../DSP/export.h" #include "../Data_Feed/export.h" #include "../Data_Source/export.h" #include "Core/spdlog/export.h" #include "MLAT.h" #include "Source_Feed_Relation.h" inline bool delete_log = false; extern std::string default_config_path; std::string get_config_path(); struct Log_Config { ~Log_Config() { if (delete_log) std::cout << "~Log_Config()" << std::endl; } enum class Open_Mode { Append, Delete, Rename }; Open_Mode open_mode = Open_Mode::Rename; std::uint16_t piece_num{}; std::uint16_t size_MB{}; PSC_USE_JSON }; struct Console_Config { ~Console_Config() { if (delete_log) std::cout << "~Console_Config()" << std::endl; } bool record_playback; bool mode_s_console; bool post_request; bool mlat_server; PSC_USE_JSON }; struct Http_Monitor_Config { bool access_log = true; std::size_t slow_request_threshold_ms = 1000; std::size_t slow_scope_threshold_ms = 100; PSC_USE_JSON }; struct Mode_ACS_Config_Base_Data { Psc::Copyable_Atomic timeout_seconds{}; SSR::CPR::D max_speed_m_s{}; SSR::CPR::D air_pos_timeout = 8; SSR::CPR::D surface_pos_timeout = 32; Psc::Copyable_Atomic read_milliseconds{}; PSC_USE_JSON }; struct Mode_ACS_Config_Data { Psc::Copyable_Atomic wait_process_msg; Psc::Copyable_Atomic time_space_filter; Psc::Copyable_Atomic speed_filter; Psc::Copyable_Atomic max_track_point_size{}; Psc::Copyable_Atomic mode_s_max_num{}; Psc::Copyable_Atomic mode_other_max_num{}; Psc::Copyable_Atomic report_data_feed_msg_mum{}; Psc::Copyable_Atomic default_min_aircraft_list_num{}; Psc::Copyable_Atomic aircraft_change_list_min_position_points = 2; Psc::Copyable_Atomic aircraft_change_list_adsb_range_filter = true; Psc::Copyable_Atomic aircraft_change_list_adsb_range_factor = 1.2; Psc::Copyable_Atomic adsb_theoretical_target_altitude_meters = 10000.0; Psc::Copyable_Atomic ignore_df_11{}; Psc::Copyable_Atomic monitor_msg_live{}; PSC_USE_JSON }; struct Mode_ACS_Config : Mode_ACS_Config_Base_Data, Mode_ACS_Config_Data { DELETE_COPY(Mode_ACS_Config) Data_feed_Config data_feed_config; Data_Source_Config data_source_config; Source_Feed_Relation_Config source_feed_relation_config; Psc::Copyable_Atomic Report_Data_Feed_Message_Num{}; Mode_ACS_Config() = default; ~Mode_ACS_Config() { if (delete_log) std::cout << " ~Mode_S_Config()" << std::endl; } Psc::JSON to_base_json() const { return Mode_ACS_Config_Base_Data::to_base_json(); } void init_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { Mode_ACS_Config_Base_Data::from_base_json(that_json, not_exist_use_default_value); } void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { Mode_ACS_Config_Base_Data::from_base_json(that_json, not_exist_use_default_value); Mode_ACS_Config_Data::from_base_json(that_json, not_exist_use_default_value); data_feed_config.init(that_json->get("data_feed"), not_exist_use_default_value); data_source_config.init(that_json->get("data_source"), not_exist_use_default_value); source_feed_relation_config.from_json(that_json->get("source_feed_relation"), not_exist_use_default_value); if (monitor_msg_live) { SSR::Monitor_Mode_ACS_Message_Num = this->monitor_msg_live; } } Psc::JSON to_base_json() { Psc::JSON ret = Mode_ACS_Config_Base_Data::to_base_json(); ret += Mode_ACS_Config_Data::to_base_json(); ret.append(Psc::JSON("data_feed", data_feed_config.to_json())); ret.append(Psc::JSON("data_source", data_source_config.to_json())); ret.append(Psc::JSON("source_feed_relation", source_feed_relation_config.to_json())); return ret; } void server(Global* g); }; struct Web_Server_Config { [[nodiscard]] std::string get_true_webapp() const { return Psc::get_abs_path(webapp); } PSC_USE_JSON std::string webapp; }; enum class Map_Tile_File_Format { directory, mbtiles, online }; enum class Map_Tile_Y_Axis { xyz, tms }; enum class Map_Tile_Projection { web_mercator }; enum class Map_Tile_Type { imagery, terrain }; enum class Map_Tile_Request_Method { GET }; enum class Map_Tile_Zoom_Mode { native, upscale, both }; struct Map_Tile_Config_Data { Map_Tile_File_Format file_format = Map_Tile_File_Format::directory; std::string path_layout; Map_Tile_Y_Axis y_axis = Map_Tile_Y_Axis::xyz; Map_Tile_Projection projection = Map_Tile_Projection::web_mercator; std::string extension; std::uint32_t tile_size{}; std::uint32_t minimum_level{}; std::uint32_t maximum_level{}; PSC_USE_JSON }; struct Map_Tile_Config : Map_Tile_Config_Data { std::vector directories; std::vector files; std::string encoding; [[nodiscard]] std::vector get_true_directories() const { std::vector ret; ret.reserve(directories.size()); for (const auto& path : directories) { ret.emplace_back(Psc::get_abs_path(path)); } return ret; } [[nodiscard]] std::vector get_true_files() const { std::vector ret; ret.reserve(files.size()); for (const auto& path : files) { ret.emplace_back(Psc::get_abs_path(path)); } return ret; } void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; [[nodiscard]] Psc::JSON to_public_json(std::string_view url) const; }; struct Map_Tile_Source_Config_Data { std::string key; std::string name; Map_Tile_Type tile_type = Map_Tile_Type::imagery; Map_Tile_Request_Method request_method = Map_Tile_Request_Method::GET; PSC_USE_JSON }; struct Map_Tile_Source_Config : Map_Tile_Source_Config_Data { std::string url; Map_Tile_Config resource; [[nodiscard]] bool local() const { return resource.file_format != Map_Tile_File_Format::online; } void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; [[nodiscard]] Psc::JSON to_public_json(std::string_view local_url) const; }; struct Map_Resources_Config { std::string current_imagery_key = "imagery"; std::vector tile_sources; void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; [[nodiscard]] Psc::JSON to_public_json() const; [[nodiscard]] bool is_imagery_key(std::string_view key) const; [[nodiscard]] bool is_terrain_key(std::string_view key) const; }; struct Map_Camera_Config { double longitude = 121.27; double latitude = 37.41; double height = 300000.0; double heading = 0.0; double pitch = -90.0; double roll = 0.0; PSC_USE_JSON }; struct Map_Tile_View_Config { std::string current_imagery_key = "imagery"; std::string current_terrain_key = "terrain"; Map_Tile_Zoom_Mode tile_zoom_mode = Map_Tile_Zoom_Mode::native; std::uint32_t tile_display_maximum_level = 19; void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; }; struct Map_View_Config { std::string scene_mode = "3d"; Map_Tile_View_Config map2d; Map_Tile_View_Config map3d; Map_Camera_Config camera; double base_station_fly_to_height_offset_meters = 8000.0; void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; [[nodiscard]] static bool is_scene_mode(std::string_view mode); }; struct Cesium_Graphics_Config_Data { bool debug_show_frames_per_second = true; std::uint32_t target_frame_rate = 30; bool use_browser_recommended_resolution = true; double resolution_scale = 0.7; std::uint32_t msaa_samples = 1; bool fxaa = false; bool shadows = false; bool enable_lighting = false; bool solar_lighting = false; double solar_light_intensity = 1.5; std::uint32_t maximum_screen_space_error = 4; bool terrain_enabled_in_3d = false; double terrain_exaggeration = 1.0; bool terrain_limit_maximum_level = true; std::uint32_t terrain_maximum_level = 15; std::uint32_t terrain_cache_tiles = 128; bool terrain_occlusion_enabled = false; bool surface_navigation_reference_visible = false; bool view_axes_visible = false; double performance_panel_x = 12.0; double performance_panel_y = 92.0; double view_axes_panel_x = -1.0; double view_axes_panel_y = 76.0; double view_axes_panel_size = 84.0; double occlusion_sample_spacing_meters = 250.0; double occlusion_clearance_margin_meters = 10.0; PSC_USE_JSON }; struct Cesium_Graphics_Config : Cesium_Graphics_Config_Data { void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; }; struct Map_Model_Item_Config { std::string url; double built_in_size = 50.0; double heading_offset_degrees = 0.0; double pitch_offset_degrees = 0.0; double roll_offset_degrees = 0.0; Map_Model_Item_Config() = default; explicit Map_Model_Item_Config(std::string url); Map_Model_Item_Config(std::string url, double built_in_size, double heading, double pitch, double roll); void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; }; struct Map_Model_Config { Map_Model_Item_Config aircraft_model{"/ui/model/aircraft.glb", 50.0, -90.0, 0.0, 0.0}; std::map aircraft_models; Map_Model_Item_Config base_station_model{"/ui/model/base-station.glb", 16.635522, 0.0, 0.0, 0.0}; Map_Model_Item_Config device_model{"/ui/model/device.glb", 80.0, 0.0, 0.0, 0.0}; Map_Model_Config(); void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); [[nodiscard]] Psc::JSON to_base_json() const; }; struct Net_Config { std::string key{}; std::string ip{}; std::uint16_t port{}; std::string netmask{}; std::string gateway{}; PSC_USE_JSON }; struct Device_Config { Ordered_Map list; ~Device_Config() { if (delete_log) std::cout << "~Device_Config()" << std::endl; for (auto it : list.list()) { delete it; } list.clear(); } Psc::JSON to_base_json() { Psc::JSON ret = Psc::JSON::object(); Psc::JSON net = Psc::JSON::array(); for (auto& li : list.list()) { net.append(li->to_base_json()); } ret.append({"net", net}); return ret; } Device_Config() = default; void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { for (auto& li : that_json->get("net")->children) { auto cur = new Net_Config(); cur->from_base_json(&li, not_exist_use_default_value); list.push_back(cur); } } Psc::JSON to_net_json() { Psc::JSON ret = Psc::JSON::object(); Psc::JSON net = Psc::JSON::array(); for (auto& li : list.list()) { net.append(li->to_base_json()); } ret.append({"net", net}); return ret; } void server(Global* g); }; class Config { public: Config() = default; DELETE_COPY(Config) MLAT_Config mlat; Device_Config device_config; Web_Server_Config web_server_config; Map_Resources_Config map_resources_config; Map_View_Config map_view_config; Cesium_Graphics_Config cesium_graphics_config; Map_Model_Config map_model_config; Mode_ACS_Config mode_acs; Log_Config log_config; Console_Config console_config{}; DSP_Config dsp_config; Psc::JSON drogon_config; Http_Monitor_Config http_monitor_config; std::string version; External_Resources_Manager external_resources_manager; static Psc::JSON load() { std::string config_path = get_config_path(); std::ifstream iso(config_path); if (!iso.is_open()) { std::cerr << config_path << " can not open!" << std::endl; Psc::fail_fast(); } else { std::cout << get_current_date_string() << " 启动加载配置文件: 【" << config_path << "】" << std::endl; } std::stringstream ss; std::stringstream buffer; buffer << iso.rdbuf(); std::string fileContents = buffer.str(); return Psc::parse_json(fileContents); } void from_base_json(Psc::JSON* that_json, bool not_exist_use_default_value) { Get_J(version) mlat.from_json(that_json->get("mlat"), not_exist_use_default_value); web_server_config.from_base_json(that_json->get("web_server"), not_exist_use_default_value); map_resources_config.from_base_json(that_json->get("map_resources"), not_exist_use_default_value); map_view_config.from_base_json(that_json->get("map_view"), not_exist_use_default_value); cesium_graphics_config.from_base_json(that_json->get("cesium_graphics"), not_exist_use_default_value); map_model_config.from_base_json(that_json->get("map_models"), not_exist_use_default_value); device_config.from_json(that_json->get("device"), not_exist_use_default_value); mode_acs.from_json(that_json->get("mode_acs"), not_exist_use_default_value); console_config.from_base_json(that_json->get("console"), not_exist_use_default_value); dsp_config.from_json(that_json->get("dsp"), not_exist_use_default_value); drogon_config = *that_json->get("drogon"); http_monitor_config.from_base_json(that_json->get("http_monitor"), not_exist_use_default_value); external_resources_manager.from_json(that_json->get("external_database"), not_exist_use_default_value); } Psc::JSON toJson() { auto ret = Psc::JSON::object({ {"version", version}, {"dsp", dsp_config.to_base_json()}, {"drogon", drogon_config}, {"http_monitor", http_monitor_config.to_base_json()}, {"mlat", mlat.to_base_json()}, {"web_server", web_server_config.to_base_json()}, {"map_resources", map_resources_config.to_base_json()}, {"map_view", map_view_config.to_base_json()}, {"map_models", map_model_config.to_base_json()}, {"device", device_config.to_base_json()}, {"mode_acs", mode_acs.to_base_json()}, //{"ais", ais.to_json()}, {"log", log_config.to_base_json()}, {"console", console_config.to_base_json()}, {"external_database", external_resources_manager.to_base_json()}, {"cesium_graphics", cesium_graphics_config.to_base_json()}, }); return ret; } static void save(); }; #endif