项目更新

This commit is contained in:
2026-08-27 16:57:16 +08:00
parent 7aca9a9394
commit e26f7eb52f
3 changed files with 96 additions and 58 deletions
@@ -6,7 +6,8 @@
#include <sstream>
// 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<std::string> fli; // Flight Identification
RET<std::string> 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<double> lat; // Flight data: Latitude (-90 to 90º)
RET<double> lon; // Flight data: Longitude (-180 to 180º)
@@ -29,26 +30,27 @@ struct Aircraft_List_JSON_Service_O {
RET<std::string> opr; // Operator DB
RET<std::string> typ; // Type DB
RET<std::string> reg; // Registration DB
RET<std::string> squ; // Mode-A (Squawk)
RET<std::string> cou; // Country
RET<double> dis; // Distance (km or NM depending on configuration)
RET<size_t> 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<time_t> lla; // int Age of last Position (s)
RET<int> tmp; // Temperature (ºC)
RET<int> wsp ; // Wind Speed (kt)
RET<double> wdi; // Wind from Direction (0-360º)
RET<int> mop; // ADS-B MOPS version;
RET<std::string> spi; // SPI (Squawk ident);
RET<bool> alr; // Alert status
RET<std::string> squ; // Mode-A (Squawk)
RET<std::string> cou; // Country
RET<double> dis; // Distance (km or NM depending on configuration)
RET<size_t> 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<time_t> lla; // int Age of last Position (s)
RET<int> tmp; // Temperature (ºC)
RET<int> wsp; // Wind Speed (kt)
RET<double> wdi; // Wind from Direction (0-360º)
RET<int> mop; // ADS-B MOPS version;
RET<std::string> spi; // SPI (Squawk ident);
RET<bool> alr; // Alert status
RET<double> ias; // IAS
RET<double> tas; // TAS
RET<double> hdgm; // Magnetic Heading
RET<std::string> hdgt; // True Heading
RET<std::string> qnhs; // Selected QNH
RET<std::string> alts; // Selected QNH
RET<double> hdgs; // Selected Heading
RET<double> altg; // GNSS elipsoidal altitude (ft)
RET<double> hdgm; // Magnetic Heading
RET<std::string> hdgt; // True Heading
RET<std::string> qnhs; // Selected QNH
RET<std::string> alts; // Selected QNH
RET<double> hdgs; // Selected Heading
RET<double> altg; // GNSS elipsoidal altitude (ft)
RET<std::string> pic; // Asterix PIC
RET<std::string> tcm; // ACAS/TCAS status
RET<std::string> ape; // Autopilot engaged
@@ -57,31 +59,40 @@ struct Aircraft_List_JSON_Service_O {
RET<int> nacp; // ADS-B SDA
RET<int> pest; // Number of position estimations per second
RET<size_t> nocl; // Number of sensors providing data aircraft
RET<std::string> tq; // Time quality of this entry
static Psc::JSON build_view_model() {
RET<std::string> tq; // Time quality of this entry
// RET<SSR::Vortex_Type> 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<SSR::CPR::Position> 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 <hex> 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;
}
};
@@ -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<Data_Source_Map_Display_Data> {
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 <>
@@ -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"})}}
})}
}