From e26f7eb52f993aedfeae5df2f1306ee2cd31d8c4 Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Thu, 27 Aug 2026 16:57:16 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Local_Server/Aircraft/aircraftlist_json.h | 146 +++++++++++------- module/Local_Server/Data_Source/Data_Source.h | 4 +- .../Local_Server/server/Adminive_Config.cpp | 4 +- 3 files changed, 96 insertions(+), 58 deletions(-) diff --git a/module/Local_Server/Aircraft/aircraftlist_json.h b/module/Local_Server/Aircraft/aircraftlist_json.h index 9a95aab..25edb72 100644 --- a/module/Local_Server/Aircraft/aircraftlist_json.h +++ b/module/Local_Server/Aircraft/aircraftlist_json.h @@ -6,7 +6,8 @@ #include // https://wiki.jetvision.de/wiki/Radarcape:Software_Features#Aircraft_List_JSON_Service -struct Aircraft_List_JSON_Service_O { +struct Aircraft_List_JSON_Service_O +{ size_t times; //自定义添加出现的次数 用于显示的优先级 time_t uti{}; // Time of last message: Seconds since UNIX epoch std::uint32_t ns{}; // Time of last message: Nanoseconds since Second epoch @@ -14,7 +15,7 @@ struct Aircraft_List_JSON_Service_O { std::string hex; // ICAO Mode-S or c, in Hex format RET fli; // Flight Identification RET ava; // Flight data: available flight data sources - std::string src; // Flight data: Source + std::string src; // Flight data: Source std::string cla; // Subclass of ADS-B data RET lat; // Flight data: Latitude (-90 to 90º) RET lon; // Flight data: Longitude (-180 to 180º) @@ -29,26 +30,27 @@ struct Aircraft_List_JSON_Service_O { RET opr; // Operator DB RET typ; // Type DB RET reg; // Registration DB - RET squ; // Mode-A (Squawk) - RET cou; // Country - RET dis; // Distance (km or NM depending on configuration) - RET tru; // Trust count Number of Mode-S frames successfully decoded from this A/C. Statistically it's possible that for a very low count the A/C does not actually exist - int dbm{}; // Approximate signal level in dBm; - RET lla; // int Age of last Position (s) - RET tmp; // Temperature (ºC) - RET wsp ; // Wind Speed (kt) - RET wdi; // Wind from Direction (0-360º) - RET mop; // ADS-B MOPS version; - RET spi; // SPI (Squawk ident); - RET alr; // Alert status + RET squ; // Mode-A (Squawk) + RET cou; // Country + RET dis; // Distance (km or NM depending on configuration) + RET tru; + // Trust count Number of Mode-S frames successfully decoded from this A/C. Statistically it's possible that for a very low count the A/C does not actually exist + int dbm{}; // Approximate signal level in dBm; + RET lla; // int Age of last Position (s) + RET tmp; // Temperature (ºC) + RET wsp; // Wind Speed (kt) + RET wdi; // Wind from Direction (0-360º) + RET mop; // ADS-B MOPS version; + RET spi; // SPI (Squawk ident); + RET alr; // Alert status RET ias; // IAS RET tas; // TAS - RET hdgm; // Magnetic Heading - RET hdgt; // True Heading - RET qnhs; // Selected QNH - RET alts; // Selected QNH - RET hdgs; // Selected Heading - RET altg; // GNSS elipsoidal altitude (ft) + RET hdgm; // Magnetic Heading + RET hdgt; // True Heading + RET qnhs; // Selected QNH + RET alts; // Selected QNH + RET hdgs; // Selected Heading + RET altg; // GNSS elipsoidal altitude (ft) RET pic; // Asterix PIC RET tcm; // ACAS/TCAS status RET ape; // Autopilot engaged @@ -57,31 +59,40 @@ struct Aircraft_List_JSON_Service_O { RET nacp; // ADS-B SDA RET pest; // Number of position estimations per second RET nocl; // Number of sensors providing data aircraft - RET tq; // Time quality of this entry - - static Psc::JSON build_view_model() { + RET tq; // Time quality of this entry + // RET vortex_type; // 飞机类型 + static Psc::JSON build_view_model() + { auto columns = Psc::JSON::array(); const auto add_column = [&columns](const char* key, const char* label, const char* type, const char* default_sort_order = nullptr, const char* fixed = nullptr, - const std::uint32_t width = 110) { + const std::uint32_t width = 110) + { auto column = Psc::JSON::object(); column.append({"key", key}); column.append({"label", label}); column.append({"type", type}); column.append({"width", width}); column.append({"sortable", std::string(type) != "index"}); - if (std::string(type) == "number") { + if (std::string(type) == "number") + { column.append({"filter", "range"}); - } else if (std::string(type) == "text") { + } + else if (std::string(type) == "text") + { column.append({"filter", "text"}); - } else if (std::string(type) == "boolean") { + } + else if (std::string(type) == "boolean") + { column.append({"filter", "boolean"}); } - if (default_sort_order != nullptr) { + if (default_sort_order != nullptr) + { column.append({"defaultSortOrder", default_sort_order}); } - if (fixed != nullptr) { + if (fixed != nullptr) + { column.append({"fixed", fixed}); } columns.append(std::move(column)); @@ -146,6 +157,7 @@ struct Aircraft_List_JSON_Service_O { add_column("pest", "位置估算次数每秒", "number"); add_column("nocl", "提供数据的接收机数", "number"); add_column("tq", "时间质量", "text"); + // add_column("vortex_type", "涡流类型", "text"); auto model = Psc::JSON::object(); model.append({"columns", std::move(columns)}); @@ -154,13 +166,16 @@ struct Aircraft_List_JSON_Service_O { static constexpr std::uint32_t view_model_schema_version = 1; - static const std::string& view_model_schema_hash() { - static const std::string hash = [] { + static const std::string& view_model_schema_hash() + { + static const std::string hash = [] + { auto model = build_view_model(); model.append({"schema_version", view_model_schema_version}); const auto serialized = model.to_json_string(); std::uint64_t value = 14695981039346656037ull; - for(const unsigned char byte : serialized) { + for (const unsigned char byte : serialized) + { value ^= byte; value *= 1099511628211ull; } @@ -171,8 +186,10 @@ struct Aircraft_List_JSON_Service_O { return hash; } - static const Psc::JSON& view_model() { - static const Psc::JSON model = [] { + static const Psc::JSON& view_model() + { + static const Psc::JSON model = [] + { auto value = build_view_model(); value.append({"schema_version", view_model_schema_version}); value.append({"schema_hash", view_model_schema_hash()}); @@ -181,7 +198,8 @@ struct Aircraft_List_JSON_Service_O { return model; } - Psc::JSON toJson() { + Psc::JSON toJson() + { auto ret = Psc::JSON::object(); ADD_Json(times); ADD_Json(uti); @@ -234,12 +252,14 @@ struct Aircraft_List_JSON_Service_O { ADD_Json_RET(pest); ADD_Json_RET(nocl); ADD_Json_RET(tq); + // ADD_Json_RET(vortex_type); return ret; } // https://wiki.jetvision.de/wiki/Radarcape:Software_Features#Aircraft_List_JSON_Service - static Aircraft_List_JSON_Service_O to_That(DataBase* db, Aircraft* info) { + static Aircraft_List_JSON_Service_O to_That(DataBase* db, Aircraft* info) + { Aircraft_List_JSON_Service_O ret; // 航线查询结果保存在 Aircraft 中,仅在首次加载或 callsign 变化时重新读取数据库。 ret.times = info->times; @@ -257,7 +277,8 @@ struct Aircraft_List_JSON_Service_O { // ret.cla ret.cla = "暂不支持"; RET pos = info->air_pos_track_list.last(); - if(pos.has_value()) { + if (pos.has_value()) + { ret.lat = pos.value().lat; ret.lon = pos.value().lon; } @@ -268,20 +289,25 @@ struct Aircraft_List_JSON_Service_O { // 飞机在地面还是空中 G for on ground, A for airborne (if TIS-B then lowercase g or a) ret.gda = info->is_on_ground() ? "G" : "A"; auto vt = info->vortex_type(); - if (vt.has_value()) { + if (vt.has_value()) + { ret.cat = Vortex_Type_to_radarcape_code(vt.value()); } // =============== 来自DB 航班数据库 ================ auto route_info = info->external_database_row("vrs_routes"); - if (!route_info) { + if (!route_info) + { route_info = info->external_database_row("adsblol_vrs_standing_data_routes"); } - if (!route_info) { + if (!route_info) + { route_info = info->external_database_row("vradarserver_standing_data_routes"); } - if (route_info) { + if (route_info) + { const auto airport_codes = route_info->get("AirportCodes"); - if (airport_codes && !airport_codes->empty()) { + if (airport_codes && !airport_codes->empty()) + { const auto first_separator = airport_codes->find('-'); const auto last_separator = airport_codes->rfind('-'); ret.org = airport_codes->substr(0, first_separator); @@ -293,15 +319,18 @@ struct Aircraft_List_JSON_Service_O { //ret.opr const auto opensky_info = info->external_database_row("opensky_aircraft_database"); - if (opensky_info) { + if (opensky_info) + { ret.opr = opensky_info->get("operator"); } //ret.typ - if (opensky_info) { + if (opensky_info) + { ret.typ = opensky_info->get("typecode"); } //ret.reg - if (opensky_info) { + if (opensky_info) + { ret.reg = opensky_info->get("registration"); } // =============================== @@ -312,12 +341,14 @@ struct Aircraft_List_JSON_Service_O { // cou Country Country according to Mode-S allocation block if decodable, mostly unusable/invalid for FLARM A/C //ret.cou const auto faa_info = info->external_database_row("faa_aircraft_registry"); - if (faa_info) { + if (faa_info) + { ret.cou = faa_info->get("country"); } // dis Distance (km or NM depending on configuration) To the Receiver GNSS location auto p = db->base_station.get_pos(); - if (p.has_value() && pos.has_value()) { + if (p.has_value() && pos.has_value()) + { ret.dis = SSR::CPR::haversine(pos.value(), p.value()); } ret.tru = info->times; @@ -336,14 +367,17 @@ struct Aircraft_List_JSON_Service_O { //ret.alr ret.alr = info->alart(); auto air_speed = info->get_airspeed(); - if (air_speed.has_value()) { + if (air_speed.has_value()) + { auto& t = air_speed.value(); auto type = t.get_airspeed_type(); - if (type == SSR::Airspeed_type::Indicated_airspeed_IAS) { + if (type == SSR::Airspeed_type::Indicated_airspeed_IAS) + { ret.ias = air_speed.value().get_speed(); } - if (type == SSR::Airspeed_type::True_airspeed_TAS) { - ret.tas= air_speed.value().get_speed(); + if (type == SSR::Airspeed_type::True_airspeed_TAS) + { + ret.tas = air_speed.value().get_speed(); } ret.hdgm = air_speed.value().get_magnetic_heading(); ret.hdgt = "暂不支持"; @@ -355,12 +389,14 @@ struct Aircraft_List_JSON_Service_O { //ret.hdgs Selected Heading ret.hdgs = info->select_heading(); auto it = info->get_speed_base(); - if (it.has_value()) { + if (it.has_value()) + { auto i = it.value(); i.get_GNSS_barometric_altitudes_difference(); auto diff = i.get_GNSS_barometric_altitudes_difference(); - if (diff.has_value() && ret.alt.has_value()) { - ret.altg = diff.value() + ret.alt.value(); + if (diff.has_value() && ret.alt.has_value()) + { + ret.altg = diff.value() + ret.alt.value(); } } //ret.pic @@ -381,7 +417,7 @@ struct Aircraft_List_JSON_Service_O { // tq Time quality of this entry Sensor 0: GNSS 1: Sensor NTP 2: Server NTP //ret.tq ret.tq = "暂不支持"; + // ret.vortex_type = info->vortex_type(); return ret; } }; - diff --git a/module/Local_Server/Data_Source/Data_Source.h b/module/Local_Server/Data_Source/Data_Source.h index a59344b..7e4f813 100644 --- a/module/Local_Server/Data_Source/Data_Source.h +++ b/module/Local_Server/Data_Source/Data_Source.h @@ -70,6 +70,7 @@ public: bool show_icao = true; bool show_call_sign = false; bool show_fly_status = false; + bool show_heading = false; PSC_USE_JSON }; class Data_Source_Map_Display_Config { @@ -129,7 +130,8 @@ struct Type_Descriptor { ADMINIVE_FIELD_LABEL(T, base_station_scale, "基站显示大小").creatable().editable().number_input(), ADMINIVE_FIELD_LABEL(T, show_icao, "显示 ICAO").creatable().editable().boolean_input(), ADMINIVE_FIELD_LABEL(T, show_call_sign, "显示呼号").creatable().editable().boolean_input(), - ADMINIVE_FIELD_LABEL(T, show_fly_status, "显示飞行状态").creatable().editable().boolean_input()); + ADMINIVE_FIELD_LABEL(T, show_fly_status, "显示飞行状态").creatable().editable().boolean_input(), + ADMINIVE_FIELD_LABEL(T, show_heading, "显示飞机角度").creatable().editable().boolean_input()); } }; template <> diff --git a/module/Local_Server/server/Adminive_Config.cpp b/module/Local_Server/server/Adminive_Config.cpp index 25ea5fe..e489481 100644 --- a/module/Local_Server/server/Adminive_Config.cpp +++ b/module/Local_Server/server/Adminive_Config.cpp @@ -900,7 +900,7 @@ Json data_source_descriptor() { {"modes", Json::array({"map2d"})}, {"object_path", "map_display.map2d"}, {"layout", Json::array({ - Json{{"kind", "cards"}, {"fields", Json::array({"aircraft_show", "base_station_show", "show_icao", "show_call_sign", "show_fly_status"})}}, + Json{{"kind", "cards"}, {"fields", Json::array({"aircraft_show", "base_station_show", "show_icao", "show_call_sign", "show_fly_status", "show_heading"})}}, Json{{"kind", "vertical"}, {"fields", Json::array({"aircraft_pixel_size", "base_station_pixel_size", "track_point_pixel_size", "color", "track_point_color", "base_station_color"})}} })} }, @@ -909,7 +909,7 @@ Json data_source_descriptor() { {"modes", Json::array({"map3d"})}, {"object_path", "map_display.map3d"}, {"layout", Json::array({ - Json{{"kind", "cards"}, {"fields", Json::array({"aircraft_show", "base_station_show", "constant_screen_size", "show_icao", "show_call_sign", "show_fly_status"})}}, + Json{{"kind", "cards"}, {"fields", Json::array({"aircraft_show", "base_station_show", "constant_screen_size", "show_icao", "show_call_sign", "show_fly_status", "show_heading"})}}, Json{{"kind", "vertical"}, {"fields", Json::array({"aircraft_scale", "base_station_scale", "track_point_pixel_size", "color", "track_point_color", "base_station_color"})}} })} }