340 lines
14 KiB
C++
340 lines
14 KiB
C++
#pragma once
|
||
|
||
#include "../Data_Source/Database.h"
|
||
|
||
// https://wiki.jetvision.de/wiki/Radarcape:Software_Features#Aircraft_List_JSON_Service
|
||
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
|
||
std::uint32_t day_second{}; // Time of last message: Nanoseconds since Second epoch
|
||
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 cla; // Subclass of ADS-B data
|
||
RET<double> lat; // Flight data: Latitude (-90 to 90º)
|
||
RET<double> lon; // Flight data: Longitude (-180 to 180º)
|
||
RET<double> alt; // Flight data: Barometric uncalibrated altitude (ft)
|
||
RET<double> spd; // Flight data: Ground Speed (kt)
|
||
RET<double> trk; // Flight data: True track (0-360º)
|
||
RET<double> vrt; // Flight data: Vertical Rate (ft/min)
|
||
std::string gda; // Airborne/Ground
|
||
std::string cat; // Aircraft category
|
||
RET<std::string> org; // Origin DB 起点机场
|
||
RET<std::string> dst; // Destination DB 目标机场
|
||
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<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<std::string> pic; // Asterix PIC
|
||
RET<std::string> tcm; // ACAS/TCAS status
|
||
RET<std::string> ape; // Autopilot engaged
|
||
RET<int> sil; // ADS-B SIL
|
||
RET<std::string> sda; // ADS-B SDA
|
||
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 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) {
|
||
auto column = Psc::JSON::object();
|
||
column.append({"key", key});
|
||
column.append({"label", label});
|
||
column.append({"type", type});
|
||
if (default_sort_order != nullptr) {
|
||
column.append({"defaultSortOrder", default_sort_order});
|
||
}
|
||
columns.append(std::move(column));
|
||
};
|
||
|
||
add_column("index", "序号", "index");
|
||
auto time_column = Psc::JSON::object();
|
||
time_column.append({"key", "time"});
|
||
time_column.append({"label", "时间"});
|
||
time_column.append({"type", "timestamp"});
|
||
time_column.append({"secondsKey", "uti"});
|
||
time_column.append({"nanosecondsKey", "ns"});
|
||
columns.append(std::move(time_column));
|
||
|
||
add_column("times", "<mode_s>消息数", "number");
|
||
add_column("hex", "识别码<ICAO>", "text");
|
||
add_column("fli", "航班编号", "text");
|
||
add_column("ava", "数据来源标识", "text");
|
||
add_column("src", "首选数据源", "text");
|
||
add_column("cla", "ADS-B数据子类", "text");
|
||
add_column("lat", "纬度", "number");
|
||
add_column("lon", "经度", "number", "descend");
|
||
add_column("alt", "高度(米)", "number");
|
||
add_column("spd", "地速(节)", "number");
|
||
add_column("trk", "航向(真)", "number");
|
||
add_column("vrt", "垂直速度(<ft/min>)", "number");
|
||
add_column("gda", "空中/地面状态", "text");
|
||
add_column("cat", "机型分类", "text");
|
||
add_column("org", "起飞机场", "text");
|
||
add_column("dst", "目的机场", "text");
|
||
add_column("opr", "航空公司", "text");
|
||
add_column("typ", "机型", "text");
|
||
add_column("reg", "注册号", "text");
|
||
add_column("squ", "应答机编码", "text");
|
||
add_column("cou", "国家", "text");
|
||
add_column("dis", "接收器距离", "number");
|
||
add_column("tru", "信任值", "number");
|
||
add_column("dbm", "信号强度(<dBm>)", "number");
|
||
add_column("lla", "位置数据延迟(秒)", "number");
|
||
add_column("tmp", "温度(℃)", "number");
|
||
add_column("wsp", "风速(节)", "number");
|
||
add_column("wdi", "风向(°)", "number");
|
||
add_column("mop", "ADS-B协议版本", "number");
|
||
add_column("spi", "识别应答(<SPI>)", "text");
|
||
add_column("alr", "告警状态", "boolean");
|
||
add_column("ias", "指示空速(<IAS>)", "number");
|
||
add_column("tas", "真空速(<TAS>)", "number");
|
||
add_column("hdgm", "磁航向", "number");
|
||
add_column("hdgt", "真航向", "text");
|
||
add_column("qnhs", "气压设定(<QNH>)", "text");
|
||
add_column("alts", "选择高度", "text");
|
||
add_column("hdgs", "选择航向", "number");
|
||
add_column("altg", "GNSS椭球高度(英尺)", "number");
|
||
add_column("pic", "<Asterix PIC>", "text");
|
||
add_column("tcm", "防撞系统状态", "text");
|
||
add_column("ape", "自动驾驶启用", "text");
|
||
add_column("sil", "系统完整性等级(<SIL>)", "number");
|
||
add_column("sda", "系统设计保证(<SDA>)", "text");
|
||
add_column("nacp", "位置精度(<NACp>)", "number");
|
||
add_column("pest", "位置估算次数每秒", "number");
|
||
add_column("nocl", "提供数据的接收机数", "number");
|
||
add_column("tq", "时间质量", "text");
|
||
|
||
auto model = Psc::JSON::object();
|
||
model.append({"columns", std::move(columns)});
|
||
return model;
|
||
}
|
||
|
||
Psc::JSON toJson() {
|
||
auto ret = Psc::JSON::object();
|
||
ADD_Json(times);
|
||
ADD_Json(uti);
|
||
ADD_Json(ns);
|
||
ADD_Json(day_second);
|
||
ADD_Json(hex);
|
||
ADD_Json_RET(fli);
|
||
ADD_Json_RET(ava);
|
||
ADD_Json(src);
|
||
ADD_Json(cla);
|
||
ADD_Json_RET(lat);
|
||
ADD_Json_RET(lon);
|
||
ADD_Json_RET(alt);
|
||
ADD_Json_RET(spd);
|
||
ADD_Json_RET(trk);
|
||
ADD_Json_RET(vrt);
|
||
ADD_Json(gda);
|
||
ADD_Json(cat);
|
||
ADD_Json_RET(org);
|
||
ADD_Json_RET(dst);
|
||
ADD_Json_RET(opr);
|
||
ADD_Json_RET(typ);
|
||
ADD_Json_RET(reg);
|
||
ADD_Json_RET(squ);
|
||
ADD_Json_RET(cou);
|
||
ADD_Json_RET(dis);
|
||
ADD_Json(tru);
|
||
ADD_Json(dbm);
|
||
ADD_Json_RET(lla);
|
||
ADD_Json_RET(tmp);
|
||
ADD_Json_RET(wsp);
|
||
ADD_Json_RET(wdi);
|
||
ADD_Json_RET(mop);
|
||
ADD_Json_RET(spi);
|
||
ADD_Json_RET(alr);
|
||
ADD_Json_RET(ias);
|
||
ADD_Json_RET(tas);
|
||
ADD_Json_RET(hdgm);
|
||
ADD_Json_RET(hdgt);
|
||
ADD_Json_RET(qnhs);
|
||
ADD_Json_RET(alts);
|
||
ADD_Json_RET(hdgs);
|
||
ADD_Json_RET(altg);
|
||
ADD_Json_RET(pic);
|
||
ADD_Json_RET(tcm);
|
||
ADD_Json_RET(ape);
|
||
ADD_Json_RET(sil);
|
||
ADD_Json_RET(sda);
|
||
ADD_Json_RET(nacp);
|
||
ADD_Json_RET(pest);
|
||
ADD_Json_RET(nocl);
|
||
ADD_Json_RET(tq);
|
||
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) {
|
||
Aircraft_List_JSON_Service_O ret;
|
||
// 航线查询结果保存在 Aircraft 中,仅在首次加载或 callsign 变化时重新读取数据库。
|
||
ret.times = info->times;
|
||
ret.uti = info->timestamp;
|
||
ret.ns = info->mlat_timestamp.nanosec;
|
||
ret.day_second = info->mlat_timestamp.daysec;
|
||
ret.hex = info->icao; // TODO not c
|
||
// fli Flight Identification Mode-S From ADS-B or BDS2,0 as specified on ICAO Annex 10, Volume IV, Table 3-9; "?" when A/C reports loss of interface
|
||
ret.fli = info->bds20_call_sign();
|
||
// ava ava Flight data: available flight data sources One letter per available flight data sources. A=ADSB, M=Jetvision MLAT, F=FlightAware MLAT, O=OGN, L=FLARM
|
||
// ret.ava
|
||
ret.ava = "暂不支持";
|
||
// ret.src
|
||
ret.src = "暂不支持";
|
||
// ret.cla
|
||
ret.cla = "暂不支持";
|
||
RET<SSR::CPR::Position> pos = info->air_pos_track_list.last();
|
||
if(pos.has_value()) {
|
||
ret.lat = pos.value().lat;
|
||
ret.lon = pos.value().lon;
|
||
}
|
||
ret.alt = info->altitude_meter();
|
||
ret.spd = info->speed();
|
||
ret.trk = info->air_magnetic_heading();
|
||
ret.vrt = info->vertical_rate();
|
||
// 飞机在地面还是空中 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()) {
|
||
ret.cat = Vortex_Type_to_radarcape_code(vt.value());
|
||
}
|
||
// =============== 来自DB 航班数据库 ================
|
||
auto route_info = info->external_database_row("vrs_routes");
|
||
if (!route_info) {
|
||
route_info = info->external_database_row("adsblol_vrs_standing_data_routes");
|
||
}
|
||
if (!route_info) {
|
||
route_info = info->external_database_row("vradarserver_standing_data_routes");
|
||
}
|
||
if (route_info) {
|
||
const auto airport_codes = route_info->get("AirportCodes");
|
||
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);
|
||
ret.dst = last_separator == std::string::npos
|
||
? *airport_codes
|
||
: airport_codes->substr(last_separator + 1);
|
||
}
|
||
}
|
||
//ret.opr
|
||
const auto opensky_info =
|
||
info->external_database_row("opensky_aircraft_database");
|
||
if (opensky_info) {
|
||
ret.opr = opensky_info->get("operator");
|
||
}
|
||
//ret.typ
|
||
if (opensky_info) {
|
||
ret.typ = opensky_info->get("typecode");
|
||
}
|
||
//ret.reg
|
||
if (opensky_info) {
|
||
ret.reg = opensky_info->get("registration");
|
||
}
|
||
// ===============================
|
||
// squ Mode-A (Squawk) Mode-S While this is a Mode-A code,
|
||
// it can only be correlated in Mode-S targets. Mode-A or Mode-A/C targets are not
|
||
// displayed in decoded formats since they cannot be correlated with a <hex> value
|
||
ret.squ = info->squawk();
|
||
// 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) {
|
||
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()) {
|
||
ret.dis = SSR::CPR::haversine(pos.value(), p.value());
|
||
}
|
||
ret.tru = info->times;
|
||
ret.dbm = info->signal_level;
|
||
//ret.lla
|
||
ret.lla = std::time(nullptr) - info->timestamp;
|
||
//ret.tmp
|
||
ret.tmp = info->temperature();
|
||
//ret.wsp
|
||
ret.wsp = info->wind_speed();
|
||
//ret.wdi
|
||
ret.wdi = info->wind_direction();
|
||
ret.mop = info->ADS_B_Ver();
|
||
//ret.spi
|
||
ret.spi = info->squawk();
|
||
//ret.alr
|
||
ret.alr = info->alart();
|
||
auto air_speed = info->get_airspeed();
|
||
if (air_speed.has_value()) {
|
||
auto& t = air_speed.value();
|
||
auto type = t.get_airspeed_type();
|
||
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();
|
||
}
|
||
ret.hdgm = air_speed.value().get_magnetic_heading();
|
||
ret.hdgt = "暂不支持";
|
||
}
|
||
//ret.qnhs Selected QNH
|
||
ret.qnhs = "暂不支持";
|
||
//ret.alts Selected Altitude
|
||
ret.alts = "暂不支持";
|
||
//ret.hdgs Selected Heading
|
||
ret.hdgs = info->select_heading();
|
||
auto it = info->get_speed_base();
|
||
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();
|
||
}
|
||
}
|
||
//ret.pic
|
||
ret.pic = "暂不支持";
|
||
//ret.tcm
|
||
ret.tcm = "暂不支持";
|
||
// ape Autopilot engaged 2 Mode-S
|
||
//ret.ape
|
||
ret.ape = "暂不支持";
|
||
ret.sil = info->SIL();
|
||
//ret.sda
|
||
ret.sda = "暂不支持";
|
||
ret.nacp = info->NACp();
|
||
// pest Number of position estimations per second MLAT
|
||
ret.pest = info->get_pest();
|
||
// nocl Number of sensors providing data aircraft MLAT
|
||
ret.nocl = 1;
|
||
// tq Time quality of this entry Sensor 0: GNSS 1: Sensor NTP 2: Server NTP
|
||
//ret.tq
|
||
ret.tq = "暂不支持";
|
||
return ret;
|
||
}
|
||
};
|
||
|