diff --git a/config/config.json b/config/config.json deleted file mode 100644 index a5839d9..0000000 --- a/config/config.json +++ /dev/null @@ -1,758 +0,0 @@ -{ - "version": "windows_v1.0.5", - "dsp": { - "library_path": "@/dll_source.dll", - "center_freq": 16000000, - "band_width": 6000, - "sample_rate": 60000, - "fft_point_number": 2048, - "fft_period_ms": 50, - "fft_win_type": "blkmc", - "frame_rate": 60, - "debug": false - }, - "drogon": { - "app": { - "threads_num": 0, - "client_max_body_size": "1000M", - "client_max_memory_body_size": "1000M" - } - }, - "http_monitor": { - "access_log": false, - "slow_request_threshold_ms": 3000, - "slow_scope_threshold_ms": 1000 - }, - "mlat": { - "merge": false - }, - "web_server": { - "webapp": "@/../third_party/eacp_webapp/wwwroot", - "listen_port": 9081 - }, - "map_resources": { - "current_imagery_key": "mixed_imagery", - "tile_sources": [ - { - "key": "mixed_imagery", - "name": "本地混合图", - "tile_type": "imagery", - "request_method": "GET", - "resource": { - "file_format": "mbtiles", - "directories": [], - "files": [ - "C:/tiles/混合图-世界-0-8.mbtiles", - "C:/tiles/混合图-中国-9-10.mbtiles", - "C:/tiles/混合图-中国-11.mbtiles" - ], - "path_layout": "z/x/y", - "y_axis": "tms", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 11 - } - }, - { - "key": "height_terrain", - "name": "本地高程", - "tile_type": "terrain", - "request_method": "GET", - "resource": { - "file_format": "mbtiles", - "directories": [], - "files": [ - "C:/tiles/高程-世界-0-8.mbtiles", - "C:/tiles/高程-中国-9-10.mbtiles", - "C:/tiles/高程-中国-11.mbtiles" - ], - "path_layout": "z/x/y", - "y_axis": "tms", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 11, - "encoding": "terrarium" - } - }, - { - "key": "osm_online", - "name": "OpenStreetMap在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 19 - } - }, - { - "key": "osm_hot_online", - "name": "OpenStreetMap HOT在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 19 - } - }, - { - "key": "cyclosm_online", - "name": "CyclOSM在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_light_online", - "name": "Carto Light在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_dark_online", - "name": "Carto Dark在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_voyager_online", - "name": "Carto Voyager在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_dark_nolabels_online", - "name": "Carto Dark无标注在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "opentopomap_online", - "name": "OpenTopoMap在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.tile.opentopomap.org/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 17 - } - } - ] - }, - "map_view": { - "scene_mode": "3d", - "map2d": { - "current_imagery_key": "mixed_imagery", - "tile_zoom_mode": "native", - "tile_display_maximum_level": 8 - }, - "map3d": { - "current_imagery_key": "mixed_imagery", - "tile_zoom_mode": "native", - "tile_display_maximum_level": 19 - }, - "camera": { - "longitude": 122.014707, - "latitude": 35.714108, - "height": 241660.03182, - "heading": 347.582854, - "pitch": -54.917211, - "roll": 359.999884 - }, - "base_station_fly_to_height_offset_meters": 8000.0 - }, - "map_models": { - "aircraft_model": { - "url": "/ui/model/aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "aircraft_models": { - "glider": { - "url": "/ui/model/aircraft-glider.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_4": { - "url": "/ui/model/aircraft-ground-obstruction-4.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_5": { - "url": "/ui/model/aircraft-ground-obstruction-5.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_6": { - "url": "/ui/model/aircraft-ground-obstruction-6.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_7": { - "url": "/ui/model/aircraft-ground-obstruction-7.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "heavy_aircraft": { - "url": "/ui/model/aircraft-heavy-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "high_performance_aircraft": { - "url": "/ui/model/aircraft-high-performance-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "high_vortex_aircraft": { - "url": "/ui/model/aircraft-high-vortex-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "light_aircraft": { - "url": "/ui/model/aircraft-light-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "lighter_than_air": { - "url": "/ui/model/aircraft-lighter-than-air.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "medium_1_aircraft": { - "url": "/ui/model/aircraft-medium-1-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "medium_2_aircraft": { - "url": "/ui/model/aircraft-medium-2-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "no_category_information": { - "url": "/ui/model/aircraft-no-category-information.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "parachutist": { - "url": "/ui/model/aircraft-parachutist.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "reserved_3_5": { - "url": "/ui/model/aircraft-reserved-3-5.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "rotorcraft": { - "url": "/ui/model/aircraft-rotorcraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "space_transatmospheric_vehicle": { - "url": "/ui/model/aircraft-space-transatmospheric-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "surface_emergency_vehicle": { - "url": "/ui/model/aircraft-surface-emergency-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "surface_service_vehicle": { - "url": "/ui/model/aircraft-surface-service-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ultralight_hangglider_paraglider": { - "url": "/ui/model/aircraft-ultralight-hangglider-paraglider.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "unmanned_aerial_vehicle": { - "url": "/ui/model/aircraft-unmanned-aerial-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - } - }, - "base_station_model": { - "url": "/ui/model/base-station.glb", - "built_in_size": 16.635522, - "heading_offset_degrees": 0.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "device_model": { - "url": "/ui/model/device.glb", - "built_in_size": 80.0, - "heading_offset_degrees": 0.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - } - }, - "mode_acs": { - "timeout_seconds": 160, - "max_speed_m_s": 1000.0, - "air_pos_timeout": 8.0, - "surface_pos_timeout": 32.0, - "wait_process_msg": true, - "time_space_filter": true, - "speed_filter": true, - "max_track_point_size": 20000, - "mode_s_max_num": 700000, - "mode_other_max_num": 10000, - "report_data_feed_msg_mum": 10000, - "default_min_aircraft_list_num": 10, - "aircraft_change_list_min_position_points": 2, - "aircraft_change_list_adsb_range_filter": true, - "aircraft_change_list_adsb_range_factor": 1.2, - "adsb_theoretical_target_altitude_meters": 10000.0, - "monitor_msg_live": false, - "data_feed": { - "packet_byte_size": 0, - "list": [ - { - "type": "Data_Feed_TCP_Server", - "key": "Port_10003", - "enable": true, - "source_key": "lzy_dll", - "output_format": { - "type": "BIN", - "use_status": true, - "mode_s_output_type": "ALL_Mode_S", - "use_mode_ac": true, - "sbs_only_pos": true - }, - "port": 10003, - "connect_user_buffer_size": 409600, - "connect_system_buffer_size": 409600 - }, - { - "type": "Data_Feed_UDP_Server", - "key": "22333", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "BIN", - "use_status": false, - "mode_s_output_type": "ALL_Mode_S", - "use_mode_ac": false, - "sbs_only_pos": false - }, - "port": 50001 - }, - { - "type": "Data_Feed_UDP_Client", - "key": "Port_10004", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "AVR", - "use_status": false, - "mode_s_output_type": "DF_11_17_18", - "use_mode_ac": false, - "sbs_only_pos": true - }, - "port": 30004, - "url": "192.168.1.75" - }, - { - "type": "Data_Feed_TCP_Client", - "key": "Port_10005", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "BIN", - "use_status": true, - "mode_s_output_type": "NO_POS_Mode_S", - "use_mode_ac": true, - "sbs_only_pos": true - }, - "url": "192.168.1.167", - "port": 10005 - }, - { - "type": "Data_Feed_TCP_Server", - "key": "Port_30003", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "SBS", - "use_status": false, - "mode_s_output_type": "ALL_Mode_S", - "use_mode_ac": true, - "sbs_only_pos": true - }, - "port": 30003, - "connect_user_buffer_size": 0, - "connect_system_buffer_size": 0 - } - ] - }, - "data_source": { - "list": [ - { - "type": "Dll_Data_Source", - "key": "lzy_dll", - "enable": true, - "base_station_has_valid_position": true, - "map_display": { - "map2d": { - "base_station_show": true, - "aircraft_show": true, - "constant_screen_size": true, - "color": "#454641", - "track_point_color": "#ffff00", - "base_station_color": "#1677ff", - "aircraft_pixel_size": 34, - "base_station_pixel_size": 30, - "aircraft_scale": 2.0, - "base_station_scale": 0.44, - "show_icao": true, - "show_call_sign": false, - "show_fly_status": false, - "track_point_pixel_size": 8 - }, - "map3d": { - "base_station_show": true, - "aircraft_show": true, - "constant_screen_size": true, - "color": "#454641", - "track_point_color": "#ffff00", - "base_station_color": "#1677ff", - "aircraft_pixel_size": 50, - "base_station_pixel_size": 100, - "aircraft_scale": 1.0, - "base_station_scale": 0.44, - "show_icao": true, - "show_call_sign": false, - "show_fly_status": false, - "track_point_pixel_size": 8 - } - }, - "lat": 37.433547, - "lon": 121.40873, - "alt": 2300.0, - "ignore_msg_time": true, - "update_form_gps": false, - "keep_mode": true, - "library_path": "@/dll_source.dll", - "function_name": "adsb_read", - "data_type": "BIN_Blank_Text", - "buffer_size": 200000 - }, - { - "type": "File_Data_Source", - "key": "aaaa", - "enable": false, - "base_station_has_valid_position": false, - "map_display": { - "map2d": { - "base_station_show": true, - "aircraft_show": true, - "constant_screen_size": true, - "color": "#d1a54c", - "track_point_color": "#ffff00", - "base_station_color": "#1677ff", - "aircraft_pixel_size": 50, - "base_station_pixel_size": 100, - "aircraft_scale": 2.0, - "base_station_scale": 0.44, - "show_icao": true, - "show_call_sign": true, - "show_fly_status": true, - "track_point_pixel_size": 8 - }, - "map3d": { - "base_station_show": true, - "aircraft_show": true, - "constant_screen_size": true, - "color": "#d1a54c", - "track_point_color": "#ffff00", - "base_station_color": "#1677ff", - "aircraft_pixel_size": 50, - "base_station_pixel_size": 100, - "aircraft_scale": 2.0, - "base_station_scale": 0.44, - "show_icao": true, - "show_call_sign": true, - "show_fly_status": true, - "track_point_pixel_size": 8 - } - }, - "lat": 37.0, - "lon": 121.0, - "alt": 1000.0, - "ignore_msg_time": true, - "update_form_gps": false, - "keep_mode": true, - "file_path": "D:\\ae\\proj\\projects\\ECAP_Server\\data\\BIN_Blank_Text\\ADS-B_195_0205.txt", - "data_type": "BIN_Blank_Text", - "play_mode": "loop" - } - ] - }, - "data_topology_view": { - "initialized": false, - "zoom": 1.0, - "pan_x": 0.0, - "pan_y": 0.0, - "node_positions": {} - } - }, - "log": { - "open_mode": "Delete", - "piece_num": 10, - "size_MB": 10 - }, - "console": { - "record_playback": false, - "mode_s_console": false - }, - "external_database": { - "ecap_sqlite_path": "@/../data/sqlite/ecap.sqlite", - "list": [ - { - "name": "tar1090_db_aircraft", - "download_url": "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", - "description": "wiedehopf/tar1090-db 发布的轻量 ICAO24 飞机静态库,提供注册号、机型、年份和运营方备注。", - "update_interval_seconds": 604800, - "last_updated_at": 1780388281 - }, - { - "name": "wiedehopf_tar1090_db_aircraft", - "download_url": "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", - "description": "wiedehopf/tar1090-db 项目发布的飞机静态数据库镜像,供 tar1090 本地识别飞机。", - "update_interval_seconds": 604800, - "last_updated_at": 1780381804 - }, - { - "name": "mictronics_aircraft_database", - "download_url": "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", - "description": "Mictronics 社区飞机数据库的 tar1090 汇总镜像,可按 ICAO24 查询注册号、机型和运营方。", - "update_interval_seconds": 604800, - "last_updated_at": 1780381804 - }, - { - "name": "opensky_aircraft_database", - "download_url": "https://opensky-network.org/datasets/metadata/aircraftDatabase.csv", - "description": "OpenSky Network 飞机元数据 CSV,包含制造商、型号、注册号和运营方等字段。", - "update_interval_seconds": 604800, - "last_updated_at": 1780381804 - }, - { - "name": "faa_aircraft_registry", - "download_url": "https://registry.faa.gov/database/ReleasableAircraft.zip", - "description": "FAA 官方可公开下载的美国飞机注册库,MASTER.txt 包含 Mode-S Hex 注册信息。", - "update_interval_seconds": 86400, - "last_updated_at": 1780381804 - }, - { - "name": "icao_doc_8643_aircraft_type_designators", - "download_url": "", - "description": "ICAO Doc 8643 机型代码表,用于将 A320、B738 等 designator 映射为制造商、型号和类别。", - "update_interval_seconds": 2419200, - "last_updated_at": 1780381804 - }, - { - "name": "vrs_routes", - "download_url": "https://vrs-standing-data.adsb.lol/routes.csv", - "description": "VRS 航线表,以 callsign 查询机场代码序列,用于推断起飞机场、经停机场和目的机场。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "vrs_airports", - "download_url": "https://vrs-standing-data.adsb.lol/airports.csv", - "description": "VRS 机场字典,提供机场代码、名称、国家、经纬度和高度。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "adsblol_vrs_standing_data_routes", - "download_url": "https://vrs-standing-data.adsb.lol/routes.csv", - "description": "ADSB.lol 发布的 VRS standing-data 航线镜像,以 callsign 查询机场代码序列。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "vradarserver_standing_data_routes", - "download_url": "https://vrs-standing-data.adsb.lol/routes.csv", - "description": "Virtual Radar Server standing-data 的航线适配表;当前在线更新使用 ADSB.lol 公共镜像。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "opensky_flightdata_api_cache", - "download_url": "", - "description": "OpenSky FlightData API 查询缓存,按 ICAO24 和时间范围保存历史航班起降机场结果。", - "update_interval_seconds": 0, - "last_updated_at": 1780381804 - } - ] - }, - "cesium_graphics": { - "debug_show_frames_per_second": true, - "target_frame_rate": 30, - "use_browser_recommended_resolution": true, - "resolution_scale": 1.0, - "msaa_samples": 1, - "fxaa": true, - "shadows": true, - "enable_lighting": true, - "solar_lighting": true, - "solar_light_intensity": 1.5, - "maximum_screen_space_error": 4, - "terrain_enabled_in_3d": true, - "terrain_exaggeration": 5.0, - "terrain_limit_maximum_level": true, - "terrain_maximum_level": 15, - "terrain_cache_tiles": 128, - "terrain_occlusion_enabled": false, - "surface_navigation_reference_visible": true, - "view_axes_visible": true, - "performance_panel_x": 12.0, - "performance_panel_y": 92.0, - "view_axes_panel_x": 3.0, - "view_axes_panel_y": 337.0, - "view_axes_panel_size": 184.0, - "occlusion_sample_spacing_meters": 250.0, - "occlusion_clearance_margin_meters": 10.0 - } -} diff --git a/config/data_progress_config.json b/config/data_progress_config.json deleted file mode 100644 index e84b68b..0000000 --- a/config/data_progress_config.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "library_path": "@/dll_source.dll", - "center_freq": 200000, - "band_width": 6000, - "sample_rate": 60000, - "fft_point_number": 2048, - "fft_period_ms": 50, - "fft_win_type": "blkmc" -} \ No newline at end of file diff --git a/config/linux/config.json b/config/linux/config.json deleted file mode 100644 index 1b5e401..0000000 --- a/config/linux/config.json +++ /dev/null @@ -1,709 +0,0 @@ -{ - "version": "v1.0.5", - "dsp": { - "library_path": "@/lib9002/lib9002.so", - "center_freq": 16000000, - "band_width": 6000, - "sample_rate": 60000, - "fft_point_number": 2048, - "fft_period_ms": 50, - "fft_win_type": "blkmc", - "frame_rate": 60, - "debug": false - }, - "drogon": { - "app": { - "threads_num": 0, - "client_max_body_size": "1000M", - "client_max_memory_body_size": "1000M" - } - }, - "http_monitor": { - "access_log": false, - "slow_request_threshold_ms": 3000, - "slow_scope_threshold_ms": 1000 - }, - "mlat": { - "merge": false - }, - "web_server": { - "webapp": "@/wwwroot", - "listen_port": 9081 - }, - "map_resources": { - "current_imagery_key": "mixed_imagery", - "tile_sources": [ - { - "key": "mixed_imagery", - "name": "本地混合图", - "tile_type": "imagery", - "request_method": "GET", - "resource": { - "file_format": "mbtiles", - "directories": [], - "files": [ - "/home/heco/tiles/混合图-世界-0-8.mbtiles", - "/home/heco/tiles/混合图-中国-9-10.mbtiles", - "/home/heco/tiles/混合图-中国-11.mbtiles" - ], - "path_layout": "z/x/y", - "y_axis": "tms", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 11 - } - }, - { - "key": "height_terrain", - "name": "本地高程", - "tile_type": "terrain", - "request_method": "GET", - "resource": { - "file_format": "mbtiles", - "directories": [], - "files": [ - "/home/heco/tiles/高程-世界-0-8.mbtiles", - "/home/heco/tiles/高程-中国-9-10.mbtiles", - "/home/heco/tiles/高程-中国-11.mbtiles" - ], - "path_layout": "z/x/y", - "y_axis": "tms", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 11, - "encoding": "terrarium" - } - }, - { - "key": "osm_online", - "name": "OpenStreetMap在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://tile.openstreetmap.org/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 19 - } - }, - { - "key": "osm_hot_online", - "name": "OpenStreetMap HOT在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 19 - } - }, - { - "key": "cyclosm_online", - "name": "CyclOSM在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_light_online", - "name": "Carto Light在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_dark_online", - "name": "Carto Dark在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_voyager_online", - "name": "Carto Voyager在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "carto_dark_nolabels_online", - "name": "Carto Dark无标注在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 20 - } - }, - { - "key": "opentopomap_online", - "name": "OpenTopoMap在线", - "tile_type": "imagery", - "request_method": "GET", - "url": "https://a.tile.opentopomap.org/{z}/{x}/{y}.png", - "resource": { - "file_format": "online", - "directories": [], - "files": [], - "path_layout": "z/x/y", - "y_axis": "xyz", - "projection": "web_mercator", - "extension": ".png", - "tile_size": 256, - "minimum_level": 0, - "maximum_level": 17 - } - } - ] - }, - "map_view": { - "scene_mode": "3d", - "map2d": { - "current_imagery_key": "mixed_imagery", - "tile_zoom_mode": "native", - "tile_display_maximum_level": 8 - }, - "map3d": { - "current_imagery_key": "mixed_imagery", - "tile_zoom_mode": "native", - "tile_display_maximum_level": 19 - }, - "camera": { - "longitude": 122.014707, - "latitude": 35.714108, - "height": 241660.03182, - "heading": 347.582854, - "pitch": -54.917211, - "roll": 359.999884 - }, - "base_station_fly_to_height_offset_meters": 8000.0 - }, - "map_models": { - "aircraft_model": { - "url": "/ui/model/aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "aircraft_models": { - "glider": { - "url": "/ui/model/aircraft-glider.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_4": { - "url": "/ui/model/aircraft-ground-obstruction-4.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_5": { - "url": "/ui/model/aircraft-ground-obstruction-5.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_6": { - "url": "/ui/model/aircraft-ground-obstruction-6.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ground_obstruction_7": { - "url": "/ui/model/aircraft-ground-obstruction-7.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "heavy_aircraft": { - "url": "/ui/model/aircraft-heavy-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "high_performance_aircraft": { - "url": "/ui/model/aircraft-high-performance-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "high_vortex_aircraft": { - "url": "/ui/model/aircraft-high-vortex-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "light_aircraft": { - "url": "/ui/model/aircraft-light-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "lighter_than_air": { - "url": "/ui/model/aircraft-lighter-than-air.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "medium_1_aircraft": { - "url": "/ui/model/aircraft-medium-1-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "medium_2_aircraft": { - "url": "/ui/model/aircraft-medium-2-aircraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "no_category_information": { - "url": "/ui/model/aircraft-no-category-information.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "parachutist": { - "url": "/ui/model/aircraft-parachutist.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "reserved_3_5": { - "url": "/ui/model/aircraft-reserved-3-5.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "rotorcraft": { - "url": "/ui/model/aircraft-rotorcraft.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "space_transatmospheric_vehicle": { - "url": "/ui/model/aircraft-space-transatmospheric-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "surface_emergency_vehicle": { - "url": "/ui/model/aircraft-surface-emergency-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "surface_service_vehicle": { - "url": "/ui/model/aircraft-surface-service-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "ultralight_hangglider_paraglider": { - "url": "/ui/model/aircraft-ultralight-hangglider-paraglider.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "unmanned_aerial_vehicle": { - "url": "/ui/model/aircraft-unmanned-aerial-vehicle.glb", - "built_in_size": 50.0, - "heading_offset_degrees": -90.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - } - }, - "base_station_model": { - "url": "/ui/model/base-station.glb", - "built_in_size": 16.635522, - "heading_offset_degrees": 0.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - }, - "device_model": { - "url": "/ui/model/device.glb", - "built_in_size": 80.0, - "heading_offset_degrees": 0.0, - "pitch_offset_degrees": 0.0, - "roll_offset_degrees": 0.0 - } - }, - "mode_acs": { - "timeout_seconds": 160, - "max_speed_m_s": 1000.0, - "air_pos_timeout": 8.0, - "surface_pos_timeout": 32.0, - "wait_process_msg": true, - "time_space_filter": true, - "speed_filter": true, - "max_track_point_size": 20000, - "mode_s_max_num": 700000, - "mode_other_max_num": 10000, - "report_data_feed_msg_mum": 10000, - "default_min_aircraft_list_num": 10, - "aircraft_change_list_min_position_points": 2, - "aircraft_change_list_adsb_range_filter": true, - "aircraft_change_list_adsb_range_factor": 1.2, - "adsb_theoretical_target_altitude_meters": 10000.0, - "monitor_msg_live": false, - "data_feed": { - "packet_byte_size": 0, - "list": [ - { - "type": "Data_Feed_TCP_Server", - "key": "Port_10003", - "enable": true, - "source_key": "lzy_dll", - "output_format": { - "type": "BIN", - "use_status": true, - "mode_s_output_type": "ALL_Mode_S", - "use_mode_ac": true, - "sbs_only_pos": true - }, - "port": 10003, - "connect_user_buffer_size": 409600, - "connect_system_buffer_size": 409600 - }, - { - "type": "Data_Feed_UDP_Server", - "key": "22333", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "BIN", - "use_status": false, - "mode_s_output_type": "ALL_Mode_S", - "use_mode_ac": false, - "sbs_only_pos": false - }, - "port": 50001 - }, - { - "type": "Data_Feed_UDP_Client", - "key": "Port_10004", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "AVR", - "use_status": false, - "mode_s_output_type": "DF_11_17_18", - "use_mode_ac": false, - "sbs_only_pos": true - }, - "port": 30004, - "url": "192.168.1.75" - }, - { - "type": "Data_Feed_TCP_Client", - "key": "Port_10005", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "BIN", - "use_status": true, - "mode_s_output_type": "NO_POS_Mode_S", - "use_mode_ac": true, - "sbs_only_pos": true - }, - "url": "192.168.1.167", - "port": 10005 - }, - { - "type": "Data_Feed_TCP_Server", - "key": "Port_30003", - "enable": false, - "source_key": "lzy_dll", - "output_format": { - "type": "SBS", - "use_status": false, - "mode_s_output_type": "ALL_Mode_S", - "use_mode_ac": true, - "sbs_only_pos": true - }, - "port": 30003, - "connect_user_buffer_size": 0, - "connect_system_buffer_size": 0 - } - ] - }, - "data_source": { - "list": [ - { - "type": "Dll_Data_Source", - "key": "lzy_dll", - "enable": true, - "base_station_has_valid_position": true, - "map_display": { - "map2d": { - "base_station_show": true, - "aircraft_show": true, - "constant_screen_size": true, - "color": "#454641", - "track_point_color": "#ffff00", - "base_station_color": "#1677ff", - "aircraft_pixel_size": 34, - "base_station_pixel_size": 30, - "aircraft_scale": 2.0, - "base_station_scale": 0.44, - "show_icao": true, - "show_call_sign": false, - "show_fly_status": false, - "track_point_pixel_size": 8 - }, - "map3d": { - "base_station_show": true, - "aircraft_show": true, - "constant_screen_size": true, - "color": "#454641", - "track_point_color": "#ffff00", - "base_station_color": "#1677ff", - "aircraft_pixel_size": 50, - "base_station_pixel_size": 100, - "aircraft_scale": 1.0, - "base_station_scale": 0.44, - "show_icao": true, - "show_call_sign": false, - "show_fly_status": false, - "track_point_pixel_size": 8 - } - }, - "lat": 37.433547, - "lon": 121.40873, - "alt": 2300.0, - "ignore_msg_time": true, - "update_form_gps": false, - "keep_mode": true, - "library_path": "@/lib9002/lib9002.so", - "function_name": "adsb_read", - "data_type": "BIN_Blank_Text", - "buffer_size": 200000 - } - ] - }, - "data_topology_view": { - "initialized": false, - "zoom": 1.0, - "pan_x": 0.0, - "pan_y": 0.0, - "node_positions": {} - } - }, - "log": { - "open_mode": "Delete", - "piece_num": 10, - "size_MB": 10 - }, - "console": { - "record_playback": false, - "mode_s_console": false - }, - "external_database": { - "ecap_sqlite_path": "@/../ecap.sqlite", - "list": [ - { - "name": "tar1090_db_aircraft", - "download_url": "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", - "description": "wiedehopf/tar1090-db 发布的轻量 ICAO24 飞机静态库,提供注册号、机型、年份和运营方备注。", - "update_interval_seconds": 604800, - "last_updated_at": 1780388281 - }, - { - "name": "wiedehopf_tar1090_db_aircraft", - "download_url": "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", - "description": "wiedehopf/tar1090-db 项目发布的飞机静态数据库镜像,供 tar1090 本地识别飞机。", - "update_interval_seconds": 604800, - "last_updated_at": 1780381804 - }, - { - "name": "mictronics_aircraft_database", - "download_url": "https://raw.githubusercontent.com/wiedehopf/tar1090-db/refs/heads/csv/aircraft.csv.gz", - "description": "Mictronics 社区飞机数据库的 tar1090 汇总镜像,可按 ICAO24 查询注册号、机型和运营方。", - "update_interval_seconds": 604800, - "last_updated_at": 1780381804 - }, - { - "name": "opensky_aircraft_database", - "download_url": "https://opensky-network.org/datasets/metadata/aircraftDatabase.csv", - "description": "OpenSky Network 飞机元数据 CSV,包含制造商、型号、注册号和运营方等字段。", - "update_interval_seconds": 604800, - "last_updated_at": 1780381804 - }, - { - "name": "faa_aircraft_registry", - "download_url": "https://registry.faa.gov/database/ReleasableAircraft.zip", - "description": "FAA 官方可公开下载的美国飞机注册库,MASTER.txt 包含 Mode-S Hex 注册信息。", - "update_interval_seconds": 86400, - "last_updated_at": 1780381804 - }, - { - "name": "icao_doc_8643_aircraft_type_designators", - "download_url": "", - "description": "ICAO Doc 8643 机型代码表,用于将 A320、B738 等 designator 映射为制造商、型号和类别。", - "update_interval_seconds": 2419200, - "last_updated_at": 1780381804 - }, - { - "name": "vrs_routes", - "download_url": "https://vrs-standing-data.adsb.lol/routes.csv", - "description": "VRS 航线表,以 callsign 查询机场代码序列,用于推断起飞机场、经停机场和目的机场。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "vrs_airports", - "download_url": "https://vrs-standing-data.adsb.lol/airports.csv", - "description": "VRS 机场字典,提供机场代码、名称、国家、经纬度和高度。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "adsblol_vrs_standing_data_routes", - "download_url": "https://vrs-standing-data.adsb.lol/routes.csv", - "description": "ADSB.lol 发布的 VRS standing-data 航线镜像,以 callsign 查询机场代码序列。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "vradarserver_standing_data_routes", - "download_url": "https://vrs-standing-data.adsb.lol/routes.csv", - "description": "Virtual Radar Server standing-data 的航线适配表;当前在线更新使用 ADSB.lol 公共镜像。", - "update_interval_seconds": 3600, - "last_updated_at": 1780381804 - }, - { - "name": "opensky_flightdata_api_cache", - "download_url": "", - "description": "OpenSky FlightData API 查询缓存,按 ICAO24 和时间范围保存历史航班起降机场结果。", - "update_interval_seconds": 0, - "last_updated_at": 1780381804 - } - ] - }, - "cesium_graphics": { - "debug_show_frames_per_second": true, - "target_frame_rate": 30, - "use_browser_recommended_resolution": true, - "resolution_scale": 1.0, - "msaa_samples": 1, - "fxaa": true, - "shadows": true, - "enable_lighting": true, - "solar_lighting": true, - "solar_light_intensity": 1.5, - "maximum_screen_space_error": 4, - "terrain_enabled_in_3d": true, - "terrain_exaggeration": 5.0, - "terrain_limit_maximum_level": true, - "terrain_maximum_level": 15, - "terrain_cache_tiles": 128, - "terrain_occlusion_enabled": false, - "surface_navigation_reference_visible": true, - "view_axes_visible": true, - "performance_panel_x": 12.0, - "performance_panel_y": 92.0, - "view_axes_panel_x": 3.0, - "view_axes_panel_y": 337.0, - "view_axes_panel_size": 184.0, - "occlusion_sample_spacing_meters": 250.0, - "occlusion_clearance_margin_meters": 10.0 - } -} diff --git a/main.cmake b/main.cmake index 83ba518..345662e 100644 --- a/main.cmake +++ b/main.cmake @@ -12,17 +12,7 @@ find_package(Drogon) find_package(SQLiteCpp CONFIG REQUIRED) set(Core Psc_Core_Static) set(md "${CMAKE_CURRENT_LIST_DIR}/module") -if (WIN32) - set(cfg_dir ${CMAKE_CURRENT_LIST_DIR}/config) -else () - set(cfg_dir ${CMAKE_CURRENT_LIST_DIR}/config) -endif () set(data_dir ${CMAKE_CURRENT_LIST_DIR}/data) -file(READ "${cfg_dir}/config.json" ecap_default_config_hex HEX) -string(REGEX REPLACE "([0-9A-Fa-f][0-9A-Fa-f])" "0x\\1,\n" ecap_default_config_bytes "${ecap_default_config_hex}") -set(ecap_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated") -file(MAKE_DIRECTORY "${ecap_generated_dir}") -configure_file("${md}/Local_Server/server/Config_Default.h.in" "${ecap_generated_dir}/Config_Default.h" @ONLY) append_glob_source(dll_source_srcs "${md}/dll_source") add_library(dll_source SHARED ${dll_source_srcs}) add_executable(data_process "${dll_source_srcs}") @@ -30,7 +20,7 @@ target_include_directories(dll_source PUBLIC "${md}") target_link_libraries(dll_source PUBLIC ${Core}) target_link_libraries(data_process PUBLIC ${Core}) _attach_post_build_file(dll_source - ${cfg_dir}/data_progress_config.json + ${data_dir}/data_progress_config.json ${data_dir}/BIN_Blank_Text/ADS-B_195_0205.txt # "${CMAKE_CURRENT_LIST_DIR}/data/BIN_Blank_Text/ADS-B_195_0205.txt" ) @@ -41,7 +31,6 @@ target_link_libraries(mlat_source PUBLIC ${Core}) append_glob_source(ecap_server_srcs "${md}/Local_Server") add_executable(ecap_server "${md}/Local_Server_main.cpp" ${ecap_server_srcs}) target_include_directories(ecap_server PUBLIC "${md}") -target_include_directories(ecap_server PRIVATE "${ecap_generated_dir}") target_include_directories(ecap_server PRIVATE "${CMAKE_CURRENT_LIST_DIR}/third_party/Adminive/backend/library/include" "${CMAKE_CURRENT_LIST_DIR}/third_party/Adminive/backend/service/include" diff --git a/module/Local_Server/DSP/DSP_Config.h b/module/Local_Server/DSP/DSP_Config.h index c8b861e..10bde1f 100644 --- a/module/Local_Server/DSP/DSP_Config.h +++ b/module/Local_Server/DSP/DSP_Config.h @@ -28,9 +28,9 @@ public: Get_J(sample_rate); Get_J(fft_point_number); } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { - Base_DSP::from_base_json(that_json, not_exist_use_default_value); - DSP_Config_Data::from_base_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) { + Base_DSP::from_base_json(that_json); + DSP_Config_Data::from_base_json(that_json); } Psc::JSON to_base_json() const { return Base_DSP::to_base_json() += DSP_Config_Data::to_base_json(); diff --git a/module/Local_Server/Data_Feed/Data_Feed.h b/module/Local_Server/Data_Feed/Data_Feed.h index c2a5e99..f847621 100644 --- a/module/Local_Server/Data_Feed/Data_Feed.h +++ b/module/Local_Server/Data_Feed/Data_Feed.h @@ -55,11 +55,11 @@ public: ret.append(Psc::JSON("output_format", output_format.read([](const auto& value) { return value.to_base_json(); }))); return ret; } - virtual void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { - With_Loop_Coro::from_base_json(that_json, not_exist_use_default_value); - source_key = that_json->get("source_key") == nullptr ? std::string{} : that_json->get_string("source_key"); + virtual void from_json(const Psc::JSON* that_json) { + With_Loop_Coro::from_base_json(that_json); + source_key = that_json->get_string("source_key"); output_format.write([&](auto& value) { - value.from_base_json(that_json->get("output_format"), not_exist_use_default_value); + value.from_base_json(that_json->get("output_format")); }); } virtual Psc::JSON get_custom_state_json() { @@ -148,10 +148,10 @@ public: co_await svr.write_to_all_clients_coro(data); co_return; } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Feed::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } Psc::JSON to_json() override { @@ -236,10 +236,10 @@ public: co_await cli.connect_coro(); co_return; } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Feed::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } Psc::JSON to_json() override { @@ -295,10 +295,10 @@ public: } return ret; } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Feed::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } Psc::JSON to_json() override { @@ -346,10 +346,10 @@ public: co_return; } Psc::asio_socket::UDP_Client_Coro cli; - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Feed::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Feed::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } Psc::JSON to_json() override { @@ -408,16 +408,20 @@ public: Psc::String_Pool pool_ = Psc::String_Pool(1600, 8 * 1024); // 8192 * 1600 12.5 MB Ordered_Map> map; Data_feed_Config() = default; - void init(const Psc::JSON* that_json, bool not_exist_use_default_value) { + void init(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_feed"); auto connect = that_json->get("list"); + if (connect == nullptr || connect->valueType != Psc::Array) + throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "data_feed.list"); for (auto& it : connect->children) { auto type = it.get_string("type"); std::shared_ptr t = create_data_feed_from_type(type); - t->from_json(&it, not_exist_use_default_value); + t->from_json(&it); map.push_back(t); } settings.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } Psc::JSON list() const { diff --git a/module/Local_Server/Data_Source/Data_Source.cpp b/module/Local_Server/Data_Source/Data_Source.cpp index 8132c9e..b1ccebe 100644 --- a/module/Local_Server/Data_Source/Data_Source.cpp +++ b/module/Local_Server/Data_Source/Data_Source.cpp @@ -3,10 +3,10 @@ #include #include "../server/Global.h" #include "Database.h" -std::shared_ptr create_from_json(const JSON* that_json, bool not_exist_use_default_value) { +std::shared_ptr create_from_json(const JSON* that_json) { std::string type = that_json->get_string("type"); std::shared_ptr ret = create_data_source_from_type(type); - ret->from_json(that_json, not_exist_use_default_value); + ret->from_json(that_json); return ret; } std::shared_ptr Data_Source::that() { diff --git a/module/Local_Server/Data_Source/Data_Source.h b/module/Local_Server/Data_Source/Data_Source.h index 94d5cbc..a59344b 100644 --- a/module/Local_Server/Data_Source/Data_Source.h +++ b/module/Local_Server/Data_Source/Data_Source.h @@ -5,7 +5,7 @@ namespace Psc { class SM_RingBuffer; } class Data_Source; -std::shared_ptr create_from_json(const Psc::JSON* that_json, bool not_exist_use_default_value); +std::shared_ptr create_from_json(const Psc::JSON* that_json); class Input_Format { public: Input_Format() { @@ -82,11 +82,11 @@ public: ret.append({"map3d", map3d.to_base_json()}); return ret; } - void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { + void from_base_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), "map_display"); - map2d.from_base_json(that_json->get("map2d"), not_exist_use_default_value); - map3d.from_base_json(that_json->get("map3d"), not_exist_use_default_value); + map2d.from_base_json(that_json->get("map2d")); + map3d.from_base_json(that_json->get("map3d")); } }; class Data_Source_Data { @@ -104,9 +104,9 @@ public: Ret_J(base_station_has_valid_position) ret.append({"map_display", map_display.to_base_json()}); Ret_J(lat) Ret_J(lon) Ret_J(alt) Ret_J(ignore_msg_time) Ret_J(update_form_gps) Ret_J(keep_mode) return ret; } - void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { + void from_base_json(const Psc::JSON* that_json) { Get_J(base_station_has_valid_position) - map_display.from_base_json(that_json->get("map_display"), not_exist_use_default_value); + map_display.from_base_json(that_json->get("map_display")); Get_J(lat) Get_J(lon) Get_J(alt) Get_J(ignore_msg_time) Get_J(update_form_gps) Get_J(keep_mode) } }; @@ -187,10 +187,10 @@ public: virtual Psc::JSON to_json() { return With_Loop_Coro::to_base_json() += settings.read([](const auto& value) { return value.to_base_json(); }); } - virtual void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { - With_Loop_Coro::from_base_json(that_json, not_exist_use_default_value); + virtual void from_json(const Psc::JSON* that_json) { + With_Loop_Coro::from_base_json(that_json); settings.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } std::string buffer; @@ -248,10 +248,10 @@ public: Psc::JSON to_json() override { return Data_Source::to_json() += specific.read([](const auto& value) { return value.to_base_json(); }); } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Source::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } asio::awaitable read_coro() override { @@ -322,10 +322,10 @@ public: Psc::JSON to_json() override { return Data_Source::to_json() += specific.read([](const auto& value) { return value.to_base_json(); }); } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Source::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } std::unique_ptr serial{}; @@ -416,10 +416,10 @@ public: asio::awaitable _close() override; asio::awaitable _open() override; std::vector readBinaryFileAsString(std::string_view filepath, size_t part_size); - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Source::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } Psc::JSON to_json() override { @@ -470,10 +470,10 @@ public: } ~Dll_Data_Source() override = default; std::vector buffer; - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Source::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); const auto buffer_size = specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); return value.buffer_size; }); buffer.resize(buffer_size); @@ -548,10 +548,10 @@ public: ret.append({"shared_memory_open", shared_memory_open.load()}); return ret; } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) override { - Data_Source::from_json(that_json, not_exist_use_default_value); + void from_json(const Psc::JSON* that_json) override { + Data_Source::from_json(that_json); specific.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } Psc::JSON to_json() override { @@ -586,10 +586,14 @@ inline std::shared_ptr create_data_source_from_type(std::string_vie struct Data_Source_Config { Ordered_Map> map; Data_Source_Config() = default; - void init(const Psc::JSON* that_json, bool not_exist_use_default_value) { + void init(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_source"); auto list = that_json->get("list"); + if (list == nullptr || list->valueType != Psc::Array) + throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "data_source.list"); for (auto& it : list->children) { - auto ds = create_from_json(&it, not_exist_use_default_value); + auto ds = create_from_json(&it); map.push_back(ds); } } diff --git a/module/Local_Server/External_Database/External_Database.cpp b/module/Local_Server/External_Database/External_Database.cpp index 90e4822..70c2f99 100644 --- a/module/Local_Server/External_Database/External_Database.cpp +++ b/module/Local_Server/External_Database/External_Database.cpp @@ -258,24 +258,20 @@ External_Resources_Manager::External_Resources_Manager() register_external_resource(make_opensky_flightdata_api_resource()); } -void External_Resources_Manager::from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) -{ - if (!that_json) - return; +void External_Resources_Manager::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), "external_database"); const auto list = that_json->get("list"); - if (!list) - return; + if (list == nullptr || list->valueType != Psc::Array) + throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "external_database.list"); std::lock_guard lock(mtx_); - for (const auto& config : list->children) - { - const auto name = config.try_get_string("name"); - if (!name) - continue; - for (const auto& resource : resources_) - { - if (resource->name != *name) + for (const auto& config : list->children) { + External_Resources_Data parsed; + parsed.from_base_json(&config); + for (const auto& resource : resources_) { + if (resource->name != parsed.name) continue; - resource->init(&config); + static_cast(*resource) = std::move(parsed); break; } } diff --git a/module/Local_Server/External_Database/global.h b/module/Local_Server/External_Database/global.h index 77cc92f..0fa51c4 100644 --- a/module/Local_Server/External_Database/global.h +++ b/module/Local_Server/External_Database/global.h @@ -57,7 +57,7 @@ public: [[nodiscard]] std::optional query_one(SQLite::Database& db, const std::vector& primary_key_values) const; void init(const Psc::JSON* that_json) { - External_Resources_Data::from_base_json(that_json, false); + External_Resources_Data::from_base_json(that_json); } [[nodiscard]] Psc::JSON to_json() const { return External_Resources_Data::to_base_json(); @@ -78,7 +78,7 @@ public: using Row_Callback = std::function)>; using Row_Map_Callback = std::function; External_Resources_Manager(); - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value); + void from_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; void server(Global* g); void ensure_sqlite_db_loaded(std::string_view path); diff --git a/module/Local_Server/server/Adminive_Config.cpp b/module/Local_Server/server/Adminive_Config.cpp index 4784d08..25ea5fe 100644 --- a/module/Local_Server/server/Adminive_Config.cpp +++ b/module/Local_Server/server/Adminive_Config.cpp @@ -262,22 +262,20 @@ adminive::Resource_Transaction data_feed_settings_transac adminive::Resource_Transaction map_view_transaction(Global* global) { adminive::Resource_Transaction transaction; transaction.prepare = [global](const Map_View_Config& value, const adminive::Request_Context&) { - if(!Map_View_Config::is_scene_mode(value.scene_mode)) - throw adminive::Field_Validation_Error("scene_mode", "场景模式必须为 2d 或 3d"); global->map_resources_config.read([&](const auto& resources) { - if(!resources.is_imagery_key(value.map2d.current_imagery_key)) + if (!resources.is_imagery_key(value.map2d.current_imagery_key)) throw adminive::Field_Validation_Error("map2d.current_imagery_key", "影像源不存在"); - if(!resources.is_terrain_key(value.map2d.current_terrain_key)) + if (!resources.is_terrain_key(value.map2d.current_terrain_key)) throw adminive::Field_Validation_Error("map2d.current_terrain_key", "地形源不存在"); - if(!resources.is_imagery_key(value.map3d.current_imagery_key)) + if (!resources.is_imagery_key(value.map3d.current_imagery_key)) throw adminive::Field_Validation_Error("map3d.current_imagery_key", "影像源不存在"); - if(!resources.is_terrain_key(value.map3d.current_terrain_key)) + if (!resources.is_terrain_key(value.map3d.current_terrain_key)) throw adminive::Field_Validation_Error("map3d.current_terrain_key", "地形源不存在"); }); }; const auto persist = [global](const Map_View_Config& value, const adminive::Request_Context&) { global->map_resources_config.write([&](auto& resources) { - resources.current_imagery_key = value.scene_mode == "2d" ? value.map2d.current_imagery_key : value.map3d.current_imagery_key; + resources.current_imagery_key = value.scene_mode == Map_Scene_Mode::map_2d ? value.map2d.current_imagery_key : value.map3d.current_imagery_key; }); Config::save(Config_Section::map_view, value.to_base_json()); Config::save(Config_Section::map_resources); @@ -771,7 +769,7 @@ std::vector external_resource_rows(Global* global) { rows.reserve(list->children.size()); for(const auto& item : list->children) { External_Resources_Data value; - value.from_base_json(&item, false); + value.from_base_json(&item); External_Resource_Row row; row.name = value.name; row.description = value.description; diff --git a/module/Local_Server/server/Config.cpp b/module/Local_Server/server/Config.cpp index d1aec4b..f80c9a1 100644 --- a/module/Local_Server/server/Config.cpp +++ b/module/Local_Server/server/Config.cpp @@ -1,5 +1,4 @@ #include "Config.h" -#include "Config_Default.h" #include #include #include @@ -12,6 +11,255 @@ #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 files, + std::optional 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 make_default_dll_source() { + auto source = std::make_shared(); + 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 make_default_file_source() { + auto source = std::make_shared(); + 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 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(); + 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(); + 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(); + 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(); + 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; @@ -71,24 +319,32 @@ void merge_json_object(Psc::JSON& target, const Psc::JSON& value) { *iterator = child; } } -Psc::JSON read_config_section(Config_Section section, const Psc::JSON& defaults) { - const auto path = config_section_path(section); - if (!std::filesystem::exists(path)) { - const auto name = config_section_name(section); - const auto value = defaults.get(name); - if (value == nullptr) { - throw std::runtime_error("default config section does not exist: " + std::string(name)); - } - write_config_section(section, *value); - return *value; +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; + std::terminate(); +} +Psc::JSON read_config_section(Config_Section section) { + try { + return read_existing_config_section_unlocked(section); } - std::ifstream input(path, std::ios::binary); - if (!input) { - throw std::runtime_error("cannot open config section: " + path.string()); + catch (const std::exception& error) { + config_load_failed(section, error.what()); + } +} +template +void assign_config_section(Config_Section section, Function&& function) { + try { + function(); + } + catch (const std::exception& error) { + config_load_failed(section, error.what()); } - std::ostringstream buffer; - buffer << input.rdbuf(); - return Psc::parse_json(buffer.str()); } Psc::JSON config_section_value(Global& global, Config_Section section) { switch (section) { @@ -180,28 +436,22 @@ void migrate_legacy_source_feed_relations(const Psc::JSON* mode_acs, Data_Source } void Data_Topology_View_Config::from_json(const Psc::JSON* that_json) { if (that_json == nullptr || that_json->valueType != Psc::Object) - return; - if (const auto* value = that_json->get("initialized"); value != nullptr && value->valueType == Psc::Bool) - initialized = value->bool_val(); - if (const auto value = that_json->try_get_number("layout_revision"); value.has_value()) - layout_revision = value.value(); - if (const auto value = that_json->try_get_number("zoom"); value.has_value() && std::isfinite(value.value()) && value.value() > 0.0) - zoom = value.value(); - if (const auto value = that_json->try_get_number("pan_x"); value.has_value() && std::isfinite(value.value())) - pan_x = value.value(); - if (const auto value = that_json->try_get_number("pan_y"); value.has_value() && std::isfinite(value.value())) - pan_y = value.value(); + 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) - return; + throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "node_positions"); node_positions.clear(); for (const auto& item : positions->children) { if (item.valueType != Psc::Object) - continue; + throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), item.key); const auto x = item.try_get_number("x"); const auto y = item.try_get_number("y"); - if (x.has_value() && y.has_value() && std::isfinite(x.value()) && std::isfinite(y.value())) - node_positions.emplace(item.key, Data_Topology_Node_Position{x.value(), y.value()}); + if (!x.has_value() || !y.has_value() || !std::isfinite(x.value()) || !std::isfinite(y.value())) + throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), item.key); + node_positions.emplace(item.key, Data_Topology_Node_Position{x.value(), y.value()}); } } Psc::JSON Data_Topology_View_Config::to_json() const { @@ -218,49 +468,89 @@ Psc::JSON Mode_ACS_Config::to_base_json() const { 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, bool not_exist_use_default_value) { +void Mode_ACS_Config::from_json(const Psc::JSON* that_json) { settings.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); SSR::Monitor_Mode_ACS_Message_Num = value.monitor_msg_live; }); - data_source_config.init(that_json->get("data_source"), 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")); + data_feed_config.init(that_json->get("data_feed")); migrate_legacy_source_feed_relations(that_json, data_source_config, data_feed_config); data_topology_view.write([&](auto& value) { value.from_json(that_json->get("data_topology_view")); }); } -Psc::JSON Config::load() { +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 = Psc::parse_json(std::string_view(reinterpret_cast(ecap_default_config_json), sizeof(ecap_default_config_json))); + const auto defaults = default_config(); + for (std::size_t index = 0; index < static_cast(Config_Section::count); ++index) { + const auto section = static_cast(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 默认配置缺少该分片"); + try { + write_config_section(section, *value); + } + catch (const std::exception& error) { + config_load_failed(section, error.what()); + } + std::cout << "生成默认配置文件: 【" << config_section_path(section).string() << "】" << std::endl; + } +} +Psc::JSON Config::load() { + create_missing_config_files(); auto result = Psc::JSON::object(); for (std::size_t index = 0; index < static_cast(Config_Section::count); ++index) { const auto section = static_cast(index); - result.append({std::string(config_section_name(section)), read_config_section(section, defaults)}); + result.append({std::string(config_section_name(section)), read_config_section(section)}); } std::cout << get_current_date_string() << " 启动加载配置目录: 【" << config_directory().string() << "】" << std::endl; return result; } +void Config::from_log_json(const Psc::JSON* that_json) { + assign_config_section(Config_Section::log, [&] { log_config.from_base_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::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::map_models, [&] { + map_model_config.write([&](auto& value) { value.from_base_json(that_json->get("map_models")); }); + }); + assign_config_section(Config_Section::mode_acs, [&] { mode_acs.from_json(that_json->get("mode_acs")); }); + 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")); + }); +} Psc::JSON Web_Server_Config::to_base_json() const { return Psc::JSON::object({{"webapp", webapp}, {"listen_port", listen_port}}); } -void Web_Server_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { +void Web_Server_Config::from_base_json(const Psc::JSON* that_json) { std::error_code error; auto result = Psc::assign_field_ec(webapp, that_json, "webapp", error); - if(!not_exist_use_default_value) - Psc::check_json_assign_field(result, error, that_json, "webapp"); - if(that_json != nullptr && that_json->get("listen_port") != nullptr) { - error.clear(); - result = Psc::assign_field_ec(listen_port, that_json, "listen_port", error); - Psc::check_json_assign_field(result, error, that_json, "listen_port"); - } + Psc::check_json_assign_field(result, error, that_json, "webapp"); + error.clear(); + result = Psc::assign_field_ec(listen_port, that_json, "listen_port", error); + Psc::check_json_assign_field(result, error, that_json, "listen_port"); } -static std::vector read_optional_string_array(const Psc::JSON* json, std::string_view key) { +static std::vector read_string_array(const Psc::JSON* json, std::string_view key) { auto field = json->get(key); - if (field == nullptr) { - return {}; - } - if (field->valueType != Psc::Array) { + if (field == nullptr || field->valueType != Psc::Array) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); } std::vector ret; @@ -309,24 +599,20 @@ static std::map make_default_aircraft_models } return ret; } -static std::map -read_optional_model_object_field(const Psc::JSON* json, std::string_view key, - std::map fallback, - bool not_exist_use_default_value) { +static std::map read_model_object_field(const Psc::JSON* json, std::string_view key) { auto field = json->get(key); - if (field == nullptr) { - return fallback; - } - if (field->valueType != Psc::Object) { + if (field == nullptr || field->valueType != Psc::Object) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); } + std::map result; for (const auto& child : field->children) { if (child.valueType != Psc::Object) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); } - fallback[child.key].from_base_json(&child, not_exist_use_default_value); + auto& item = result[child.key]; + item.from_base_json(&child); } - return fallback; + return result; } static Psc::JSON write_model_object(std::string_view key, const std::map& values) { auto object = Psc::JSON::object(); @@ -345,52 +631,47 @@ static std::string read_optional_string_field(const Psc::JSON* json, std::string } return field->val; } -static std::string read_optional_string_field(const Psc::JSON* json, std::string_view key, std::string_view fallback) { +static std::string read_string_field(const Psc::JSON* json, std::string_view key) { auto field = json->get(key); - if (field == nullptr) { - return std::string(fallback); - } - if (field->valueType != Psc::String) { + if (field == nullptr || field->valueType != Psc::String) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); } return field->val; } -static std::uint32_t read_optional_uint32_field(const Psc::JSON* json, std::string_view key, std::uint32_t fallback) { +static std::uint32_t read_uint32_field(const Psc::JSON* json, std::string_view key) { auto field = json->get(key); - if (field == nullptr) { - return fallback; - } - if (field->valueType != Psc::Number) { + if (field == nullptr || field->valueType != Psc::Number) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); } return field->number_val(); } -static double read_optional_double_field(const Psc::JSON* json, std::string_view key, double fallback) { +static double read_double_field(const Psc::JSON* json, std::string_view key) { auto field = json->get(key); - if (field == nullptr) { - return fallback; - } - if (field->valueType != Psc::Number) { + if (field == nullptr || field->valueType != Psc::Number) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); } return field->number_val(); } -void Map_Tile_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { +void Map_Tile_Config::from_base_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), "map tile config"); } - Map_Tile_Config_Data::from_base_json(that_json, not_exist_use_default_value); - directories = read_optional_string_array(that_json, "directories"); - files = read_optional_string_array(that_json, "files"); - encoding = read_optional_string_field(that_json, "encoding"); + Map_Tile_Config_Data::from_base_json(that_json); + directories = read_string_array(that_json, "directories"); + files = read_string_array(that_json, "files"); + encoding.reset(); + if (that_json->get("encoding") != nullptr) { + std::error_code error; + const auto result = Psc::assign_field_ec(encoding, that_json, "encoding", error); + Psc::check_json_assign_field(result, error, that_json, "encoding"); + } } Psc::JSON Map_Tile_Config::to_base_json() const { auto ret = Map_Tile_Config_Data::to_base_json(); ret.append(write_string_array("directories", directories)); ret.append(write_string_array("files", files)); - if (!encoding.empty()) { - ret.append({"encoding", encoding}); - } + if (encoding.has_value()) + ret.append({"encoding", encoding.value()}); return ret; } Psc::JSON Map_Tile_Config::to_public_json(std::string_view url) const { @@ -401,18 +682,17 @@ Psc::JSON Map_Tile_Config::to_public_json(std::string_view url) const { ret.append({"tile_size", tile_size}); ret.append({"projection", Psc::to_string(projection)}); ret.append({"y_axis", Psc::to_string(y_axis)}); - if (!encoding.empty()) { - ret.append({"encoding", encoding}); - } + if (encoding.has_value()) + ret.append({"encoding", encoding.value()}); return ret; } -void Map_Tile_Source_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { +void Map_Tile_Source_Config::from_base_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), "map tile source config"); } - Map_Tile_Source_Config_Data::from_base_json(that_json, not_exist_use_default_value); + Map_Tile_Source_Config_Data::from_base_json(that_json); url = read_optional_string_field(that_json, "url"); - resource.from_base_json(that_json->get("resource"), not_exist_use_default_value); + resource.from_base_json(that_json->get("resource")); } Psc::JSON Map_Tile_Source_Config::to_base_json() const { auto ret = Map_Tile_Source_Config_Data::to_base_json(); @@ -431,20 +711,16 @@ Psc::JSON Map_Tile_Source_Config::to_public_json(std::string_view local_url) con ret.append({"resource", resource.to_public_json(local() ? local_url : url)}); return ret; } -static std::vector read_optional_tile_source_array(const Psc::JSON* json, std::string_view key, - bool not_exist_use_default_value) { +static std::vector read_tile_source_array(const Psc::JSON* json, std::string_view key) { auto field = json->get(key); - if (field == nullptr) { - return {}; - } - if (field->valueType != Psc::Array) { + if (field == nullptr || field->valueType != Psc::Array) { throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), std::string(key)); } std::vector ret; ret.reserve(field->children.size()); for (const auto& child : field->children) { Map_Tile_Source_Config item; - item.from_base_json(&child, not_exist_use_default_value); + item.from_base_json(&child); ret.push_back(std::move(item)); } return ret; @@ -456,15 +732,12 @@ static Psc::JSON write_tile_source_array(std::string_view key, const std::vector } return Psc::JSON(key, array); } -void Map_Resources_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { +void Map_Resources_Config::from_base_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), "map_resources"); } - current_imagery_key = read_optional_string_field(that_json, "current_imagery_key"); - if (current_imagery_key.empty()) { - current_imagery_key = "imagery"; - } - tile_sources = read_optional_tile_source_array(that_json, "tile_sources", not_exist_use_default_value); + current_imagery_key = read_string_field(that_json, "current_imagery_key"); + tile_sources = read_tile_source_array(that_json, "tile_sources"); if (!is_imagery_key(current_imagery_key)) { auto source = std::ranges::find_if( tile_sources, [](const Map_Tile_Source_Config& item) { return item.tile_type == Map_Tile_Type::imagery; }); @@ -518,22 +791,14 @@ bool Map_Resources_Config::is_terrain_key(std::string_view key) const { return source.tile_type == Map_Tile_Type::terrain && source.key == key; }); } -bool Map_View_Config::is_scene_mode(std::string_view mode) { - return mode == "2d" || mode == "2.5d" || mode == "3d"; -} -void Map_Tile_View_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { - if (that_json == nullptr) { - return; - } - if (that_json->valueType != Psc::Object) { +void Map_Tile_View_Config::from_base_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), "map_tile_view"); } - current_imagery_key = read_optional_string_field(that_json, "current_imagery_key", current_imagery_key); - current_terrain_key = read_optional_string_field(that_json, "current_terrain_key", current_terrain_key); - tile_zoom_mode = Psc::to_enum( - read_optional_string_field(that_json, "tile_zoom_mode", Psc::to_string(tile_zoom_mode))); - tile_display_maximum_level = std::clamp( - read_optional_uint32_field(that_json, "tile_display_maximum_level", tile_display_maximum_level), 0u, 24u); + current_imagery_key = read_string_field(that_json, "current_imagery_key"); + current_terrain_key = read_string_field(that_json, "current_terrain_key"); + tile_zoom_mode = Psc::to_enum(read_string_field(that_json, "tile_zoom_mode")); + tile_display_maximum_level = std::clamp(read_uint32_field(that_json, "tile_display_maximum_level"), 0u, 24u); } Psc::JSON Map_Tile_View_Config::to_base_json() const { auto ret = Psc::JSON::object(); @@ -543,23 +808,17 @@ Psc::JSON Map_Tile_View_Config::to_base_json() const { ret.append({"tile_display_maximum_level", tile_display_maximum_level}); return ret; } -void Map_View_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { - if (that_json == nullptr) { - return; - } - if (that_json->valueType != Psc::Object) { +void Map_View_Config::from_base_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), "map_view"); } - auto next_scene_mode = read_optional_string_field(that_json, "scene_mode", scene_mode); - if (!is_scene_mode(next_scene_mode)) { - throw Psc::json_assign_error(std::make_error_code(std::errc::invalid_argument), "scene_mode"); - } - scene_mode = next_scene_mode; - map2d.from_base_json(that_json->get("map2d"), not_exist_use_default_value); - map3d.from_base_json(that_json->get("map3d"), not_exist_use_default_value); - camera.from_base_json(that_json->get("camera"), not_exist_use_default_value); - base_station_fly_to_height_offset_meters = - std::max(100.0, read_optional_double_field(that_json, "base_station_fly_to_height_offset_meters", base_station_fly_to_height_offset_meters)); + std::error_code error; + const auto result = Psc::assign_field_ec(scene_mode, that_json, "scene_mode", error); + Psc::check_json_assign_field(result, error, that_json, "scene_mode"); + 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")); } Psc::JSON Map_View_Config::to_base_json() const { auto ret = Psc::JSON::object(); @@ -570,13 +829,11 @@ Psc::JSON Map_View_Config::to_base_json() const { ret.append({"base_station_fly_to_height_offset_meters", base_station_fly_to_height_offset_meters}); return ret; } -void Cesium_Graphics_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { - if (that_json == nullptr) - return; - if (that_json->valueType != Psc::Object) +void Cesium_Graphics_Config::from_base_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), "cesium_graphics"); settings.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); value.target_frame_rate = std::clamp(value.target_frame_rate, 1u, 120u); value.resolution_scale = std::clamp(value.resolution_scale, 0.2, 1.5); value.msaa_samples = std::clamp(value.msaa_samples, 1u, 8u); @@ -602,15 +859,15 @@ Map_Model_Item_Config::Map_Model_Item_Config(std::string url, double built_in_si url(std::move(url)), built_in_size(built_in_size), heading_offset_degrees(heading), pitch_offset_degrees(pitch), roll_offset_degrees(roll) { } -void Map_Model_Item_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { +void Map_Model_Item_Config::from_base_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), "map_model_item"); } - url = read_optional_string_field(that_json, "url", url); - built_in_size = read_optional_double_field(that_json, "built_in_size", built_in_size); - heading_offset_degrees = read_optional_double_field(that_json, "heading_offset_degrees", heading_offset_degrees); - pitch_offset_degrees = read_optional_double_field(that_json, "pitch_offset_degrees", pitch_offset_degrees); - roll_offset_degrees = read_optional_double_field(that_json, "roll_offset_degrees", roll_offset_degrees); + url = read_string_field(that_json, "url"); + built_in_size = read_double_field(that_json, "built_in_size"); + heading_offset_degrees = read_double_field(that_json, "heading_offset_degrees"); + pitch_offset_degrees = read_double_field(that_json, "pitch_offset_degrees"); + roll_offset_degrees = read_double_field(that_json, "roll_offset_degrees"); } Psc::JSON Map_Model_Item_Config::to_base_json() const { auto ret = Psc::JSON::object(); @@ -623,18 +880,14 @@ Psc::JSON Map_Model_Item_Config::to_base_json() const { } Map_Model_Config::Map_Model_Config() : aircraft_models(make_default_aircraft_models()) { } -void Map_Model_Config::from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { - if (that_json == nullptr) { - return; - } - if (that_json->valueType != Psc::Object) { +void Map_Model_Config::from_base_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), "map_models"); } - aircraft_model.from_base_json(that_json->get("aircraft_model"), not_exist_use_default_value); - aircraft_models = read_optional_model_object_field(that_json, "aircraft_models", make_default_aircraft_models(), - not_exist_use_default_value); - base_station_model.from_base_json(that_json->get("base_station_model"), not_exist_use_default_value); - device_model.from_base_json(that_json->get("device_model"), not_exist_use_default_value); + aircraft_model.from_base_json(that_json->get("aircraft_model")); + aircraft_models = read_model_object_field(that_json, "aircraft_models"); + base_station_model.from_base_json(that_json->get("base_station_model")); + device_model.from_base_json(that_json->get("device_model")); } Psc::JSON Map_Model_Config::to_base_json() const { auto ret = Psc::JSON::object(); diff --git a/module/Local_Server/server/Config.h b/module/Local_Server/server/Config.h index e8f97ec..df97a90 100644 --- a/module/Local_Server/server/Config.h +++ b/module/Local_Server/server/Config.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "../DSP/export.h" #include "../Data_Feed/export.h" @@ -164,7 +165,7 @@ struct Mode_ACS_Config { std::cout << " ~Mode_S_Config()" << std::endl; } [[nodiscard]] Psc::JSON to_base_json() const; - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value); + void from_json(const Psc::JSON* that_json); void server(Global* g); }; struct Web_Server_Config { @@ -174,17 +175,39 @@ struct Web_Server_Config { std::string webapp; std::uint16_t listen_port = 9081; [[nodiscard]] Psc::JSON to_base_json() const; - void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); + void from_base_json(const Psc::JSON* that_json); }; enum class Map_Tile_File_Format { directory, mbtiles, online }; +enum class Map_Tile_Path_Layout { z_x_y, z_y_x }; 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 }; +enum class Map_Tile_Encoding { terrarium }; +enum class Map_Scene_Mode { map_2d, map_2_5d, map_3d }; +namespace magic_enum::customize { +template <> +constexpr customize_t enum_name(Map_Tile_Path_Layout value) noexcept { + switch (value) { + case Map_Tile_Path_Layout::z_x_y: return "z/x/y"; + case Map_Tile_Path_Layout::z_y_x: return "z/y/x"; + } + return invalid_tag; +} +template <> +constexpr customize_t enum_name(Map_Scene_Mode value) noexcept { + switch (value) { + case Map_Scene_Mode::map_2d: return "2d"; + case Map_Scene_Mode::map_2_5d: return "2.5d"; + case Map_Scene_Mode::map_3d: return "3d"; + } + return invalid_tag; +} +} struct Map_Tile_Config_Data { Map_Tile_File_Format file_format = Map_Tile_File_Format::directory; - std::string path_layout; + Map_Tile_Path_Layout path_layout = Map_Tile_Path_Layout::z_x_y; Map_Tile_Y_Axis y_axis = Map_Tile_Y_Axis::xyz; Map_Tile_Projection projection = Map_Tile_Projection::web_mercator; std::string extension; @@ -196,7 +219,7 @@ struct Map_Tile_Config_Data { struct Map_Tile_Config : Map_Tile_Config_Data { std::vector directories; std::vector files; - std::string encoding; + std::optional encoding; [[nodiscard]] std::vector get_true_directories() const { std::vector ret; ret.reserve(directories.size()); @@ -213,7 +236,7 @@ struct Map_Tile_Config : Map_Tile_Config_Data { } return ret; } - void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); + void from_base_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; [[nodiscard]] Psc::JSON to_public_json(std::string_view url) const; }; @@ -230,14 +253,14 @@ struct Map_Tile_Source_Config : Map_Tile_Source_Config_Data { [[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); + void from_base_json(const Psc::JSON* that_json); [[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); + void from_base_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; [[nodiscard]] Psc::JSON to_public_json() const; [[nodiscard]] bool is_imagery_key(std::string_view key) const; @@ -283,7 +306,7 @@ struct Map_Tile_View_Config { 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); + void from_base_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; }; namespace adminive { @@ -300,14 +323,13 @@ struct Type_Descriptor { }; } struct Map_View_Config { - std::string scene_mode = "3d"; + Map_Scene_Mode scene_mode = Map_Scene_Mode::map_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); + void from_base_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; - [[nodiscard]] static bool is_scene_mode(std::string_view mode); }; namespace adminive { template <> @@ -315,7 +337,7 @@ struct Type_Descriptor { static auto get() { using T = Map_View_Config; return object("map_view_config", "地图视图配置", - ADMINIVE_FIELD_LABEL(T, scene_mode, "场景模式").editable().required().text_input(), + ADMINIVE_FIELD_LABEL(T, scene_mode, "场景模式").editable().required().select_input(), ADMINIVE_FIELD_LABEL(T, map2d, "2D 地图").editable(), ADMINIVE_FIELD_LABEL(T, map3d, "3D 地图").editable(), ADMINIVE_FIELD_LABEL(T, camera, "相机").editable(), @@ -413,7 +435,7 @@ struct Type_Descriptor { } struct Cesium_Graphics_Config { adminive::Managed_Value settings; - void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value); + void from_base_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; }; struct Map_Model_Item_Config { @@ -425,7 +447,7 @@ struct Map_Model_Item_Config { 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); + void from_base_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; }; namespace adminive { @@ -448,7 +470,7 @@ struct Map_Model_Config { 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); + void from_base_json(const Psc::JSON* that_json); [[nodiscard]] Psc::JSON to_base_json() const; }; namespace adminive { @@ -482,27 +504,10 @@ public: Http_Monitor_Config http_monitor_config; std::string version; External_Resources_Manager external_resources_manager; + static void create_missing_config_files(); static Psc::JSON load(); - 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.write([&](auto& value) { - value.from_base_json(that_json->get("map_resources"), not_exist_use_default_value); - }); - map_view_config.write([&](auto& value) { - value.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.write([&](auto& value) { - value.from_base_json(that_json->get("map_models"), 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); - } + void from_log_json(const Psc::JSON* that_json); + void from_base_json(Psc::JSON* that_json); Psc::JSON toJson() { auto ret = Psc::JSON::object({ {"version", version}, diff --git a/module/Local_Server/server/Config_Default.h.in b/module/Local_Server/server/Config_Default.h.in deleted file mode 100644 index e9ea5a7..0000000 --- a/module/Local_Server/server/Config_Default.h.in +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once -inline constexpr unsigned char ecap_default_config_json[] = { -@ecap_default_config_bytes@}; diff --git a/module/Local_Server/server/Global.cpp b/module/Local_Server/server/Global.cpp index 0be45ad..067b4bd 100644 --- a/module/Local_Server/server/Global.cpp +++ b/module/Local_Server/server/Global.cpp @@ -54,7 +54,7 @@ void Global::handle_old_logs() { } Global::Global() { auto j = load(); - log_config.from_base_json(j.get("log"), false); + from_log_json(j.get("log")); handle_old_logs(); Base_Logger_Manager::instance()->set_thread_num(1).set_flush_seconds(3).init(); int piece_num = log_config.piece_num; @@ -75,7 +75,7 @@ Global::Global() { log_info.content; debug_logger_info_manager.push_info(msg); }); - from_base_json(&j, false); + from_base_json(&j); #ifdef Cache_Some_Mode_S auto old_parse_ok_json = SSR::parse_ok_json; SSR::parse_ok_json = [old_parse_ok_json](Aircraft_Info* aircraft_info, SSR::P_S mode_s_msg, Psc::JSON json) { diff --git a/module/Local_Server/server/MLAT.h b/module/Local_Server/server/MLAT.h index 1690d93..767423f 100644 --- a/module/Local_Server/server/MLAT.h +++ b/module/Local_Server/server/MLAT.h @@ -29,9 +29,9 @@ public: }); } - void from_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { + void from_json(const Psc::JSON* that_json) { settings.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } }; diff --git a/module/Local_Server/server/With_Loop_Coro.h b/module/Local_Server/server/With_Loop_Coro.h index 86ae57b..97a7fba 100644 --- a/module/Local_Server/server/With_Loop_Coro.h +++ b/module/Local_Server/server/With_Loop_Coro.h @@ -59,10 +59,10 @@ public: ret.append({"key", key}); return ret; } - void from_base_json(const Psc::JSON* that_json, bool not_exist_use_default_value) { + void from_base_json(const Psc::JSON* that_json) { Get_J(type) Get_J(key) config.write([&](auto& value) { - value.from_base_json(that_json, not_exist_use_default_value); + value.from_base_json(that_json); }); } asio::awaitable tick(); diff --git a/module/Local_Server/server/tiles.cpp b/module/Local_Server/server/tiles.cpp index e7b59d5..b38c95e 100644 --- a/module/Local_Server/server/tiles.cpp +++ b/module/Local_Server/server/tiles.cpp @@ -185,9 +185,6 @@ class Tile_Path_Resolver { public: explicit Tile_Path_Resolver(const Map_Tile_Config& config) : config_(config), directories_(config.get_true_directories()) { - if (config_.path_layout != "z/x/y" && config_.path_layout != "z/y/x") { - throw std::invalid_argument("invalid tile path_layout: " + config_.path_layout); - } if (config_.extension.empty() || config_.extension.front() != '.') { throw std::invalid_argument("invalid tile extension: " + config_.extension); } @@ -210,7 +207,7 @@ private: auto z = std::to_string(request.z); auto x = std::to_string(request.x); auto y = std::to_string(request.y) + config_.extension; - if (config_.path_layout == "z/x/y") { + if (config_.path_layout == Map_Tile_Path_Layout::z_x_y) { return std::filesystem::path(z) / x / y; } return std::filesystem::path(z) / std::to_string(request.y) / (std::to_string(request.x) + config_.extension); @@ -526,7 +523,7 @@ void register_map_graphics_handler() { return; } try { - global->cesium_graphics_config.from_base_json(&parsed.value(), false); + global->cesium_graphics_config.from_base_json(&parsed.value()); Global::save(Config_Section::cesium_graphics); } catch (const std::exception& error) { @@ -675,7 +672,7 @@ void handle_map_model_config_update(const drogon::HttpRequestPtr& req, Global* g throw std::invalid_argument("invalid map_models"); } global->map_model_config.write([&](auto& config) { - config.from_base_json(&parsed.value(), false); + config.from_base_json(&parsed.value()); }); Global::save(Config_Section::map_models); } @@ -740,7 +737,7 @@ void register_map_view_handler() { auto next_view = global->map_view_config.read([](const auto& config) { return config; }); - next_view.from_base_json(&parsed.value(), false); + next_view.from_base_json(&parsed.value()); global->map_resources_config.read([&](const auto& config) { if (!config.is_imagery_key(next_view.map2d.current_imagery_key) || !config.is_imagery_key(next_view.map3d.current_imagery_key)) { diff --git a/module/dll_source/Dll_Global.cpp b/module/dll_source/Dll_Global.cpp index b93eb70..8e19613 100644 --- a/module/dll_source/Dll_Global.cpp +++ b/module/dll_source/Dll_Global.cpp @@ -106,7 +106,7 @@ Dll_Global::Dll_Global() { std::cout << "Dll_Global 配置文件加载失败!" << std::endl; Psc::fail_fast(); } - from_base_json(&config.value(), false); + from_base_json(&config.value()); psm = new std::uint8_t[65536 * 2]; } Dll_Global::~Dll_Global() {