#include "../Aircraft/Flight_VTO.h" #include #include namespace { double to_radians(double degrees) { return degrees * 3.14159265358979323846 / 180.0; } double track_heading_from_points(const SSR::Position_Info& first, const SSR::Position_Info& second) { auto lat1 = to_radians(first.lat); auto lat2 = to_radians(second.lat); auto dlon = to_radians(second.lon - first.lon); auto y = std::sin(dlon) * std::cos(lat2); auto x = std::cos(lat1) * std::sin(lat2) - std::sin(lat1) * std::cos(lat2) * std::cos(dlon); auto angle = std::atan2(y, x) * 180.0 / 3.14159265358979323846; return angle < 0 ? angle + 360.0 : angle; } double ground_distance_meters(const SSR::Position_Info& first, const SSR::Position_Info& second) { auto dlat = to_radians(second.lat - first.lat); auto dlon = to_radians(second.lon - first.lon); auto lat1 = to_radians(first.lat); auto lat2 = to_radians(second.lat); auto a = std::sin(dlat / 2) * std::sin(dlat / 2) + std::cos(lat1) * std::cos(lat2) * std::sin(dlon / 2) * std::sin(dlon / 2); auto safe_a = std::min(1.0, std::max(0.0, a)); return 6371000.0 * 2 * std::atan2(std::sqrt(safe_a), std::sqrt(1 - safe_a)); } double track_pitch_from_points(const SSR::Position_Info& first, const SSR::Position_Info& second) { auto distance = ground_distance_meters(first, second); return std::atan2(second.alt - first.alt, distance) * 180.0 / 3.14159265358979323846; } Flight_Track_Orientation track_orientation_from_points(const SSR::Position_Info& first, const SSR::Position_Info& second) { return {track_heading_from_points(first, second), track_pitch_from_points(first, second), 0.0}; } } Psc::JSON Flight_Track_Orientation::to_json() const { auto ret = Psc::JSON::object(); ret.append({"heading", heading}); ret.append({"pitch", pitch}); ret.append({"roll", roll}); return ret; } Psc::JSON Flight_VTO::to_json() { return to_json(true); } Psc::JSON Flight_VTO::to_base_info_json() { return to_json(false); } Psc::JSON Flight_VTO::to_json(bool include_runtime_fields) { auto ret = Psc::JSON::object(); ADD_Json(icao); ADD_Json(mlat); ret.children.emplace_back("time_stamp", time_to_string(time_stamp)); if (pos.has_value()) { ret.children.emplace_back("latitude", pos.value().lat); ret.children.emplace_back("longitude", pos.value().lon); } else { ret.children.emplace_back("latitude", nullptr); ret.children.emplace_back("longitude", nullptr); } ADD_Json_RET(track); if (include_runtime_fields) { if (track_orientation.has_value()) { ret.append({"track_orientation", track_orientation.value().to_json()}); } else { ret.append({"track_orientation", nullptr}); } } ADD_Json_RET(speed); ADD_Json_RET(altitude); ADD_Json_RET(vert_speed); ADD_Json_RET(call_sign); ADD_Json_RET(squawk); if (include_runtime_fields) { if (vortex_type.has_value()) { auto value = vortex_type.value(); ret.append({"vortex_type", static_cast(value)}); ret.append({"vortex_type_key", std::string(SSR::Vortex_Type_to_key(value))}); ret.append({"vortex_type_label", std::string(SSR::Vortex_Type_to_label(value))}); } else { ret.append({"vortex_type", nullptr}); ret.append({"vortex_type_key", nullptr}); ret.append({"vortex_type_label", nullptr}); } } return ret; } std::string Flight_VTO::time_to_string(time_t time_stamp) { const std::tm* utc_time = std::gmtime(&time_stamp); char buffer[80]; std::strftime(buffer, sizeof(buffer), "%H:%M:%S", utc_time); return {buffer}; } Flight_VTO Flight_VTO::to_VTO(SSR::Aircraft_Info* info) { Flight_VTO vto; vto.icao = info->icao; vto.mlat = info->mlat; vto.time_stamp = info->timestamp; vto.speed = info->speed(); // 这个地 是相对于地的意思 vto.track = info->surface_magnetic_heading(); auto last_two = info->air_pos_track_list.last_two(); if (last_two.has_value()) { auto orientation = track_orientation_from_points(last_two->first, last_two->second); vto.track = orientation.heading; vto.track_orientation = orientation; } // vto.pos = info->pos(); auto opt = info->air_pos_track_list.last(); vto.pos = opt; if (opt.has_value()) { SSR::Position_Info& a = opt.value(); vto.altitude = a.alt; } // auto val = info->surface_pos_track_list.last(); // vto.pos = val; // if (val.has_value()) { // vto.altitude = val.value().alt; // std::cout << "222222" << std::endl; // } vto.vert_speed = info->vertical_rate(); vto.call_sign = info->bds20_call_sign(); vto.squawk = info->squawk(); vto.vortex_type = info->vortex_type(); return vto; }