diff --git a/src/PlugIn.cpp b/src/PlugIn.cpp index ce7d8b1..2b04d44 100644 --- a/src/PlugIn.cpp +++ b/src/PlugIn.cpp @@ -19,12 +19,17 @@ #include #include +#pragma warning(push, 0) +#include +#pragma warning(pop) +#include #include #include #include #include #include +#include #include "com/ZmqContext.h" #include "PlugIn.h" @@ -241,6 +246,76 @@ aman::Aircraft* PlugIn::generateAircraftMessage(const EuroScopePlugIn::CRadarTar return retval; } +void PlugIn::distanceToPredictedIaf(const EuroScopePlugIn::CRadarTarget& radarTarget, const EuroScopePlugIn::CFlightPlan& flightPlan, + const EuroScopePlugIn::CPosition& iafPosition, aman::AircraftReport* report) { + std::string_view direct(flightPlan.GetControllerAssignedData().GetDirectToPointName()); + + if (0 != direct.length()) { + GeoCoordinate directCoordinate; + + /* find the coordinate of the direct waypoint */ + for (int i = 0; i < flightPlan.GetExtractedRoute().GetPointsNumber(); ++i) { + if (flightPlan.GetExtractedRoute().GetPointName(i) == direct) { + directCoordinate = GeoCoordinate(static_cast(flightPlan.GetExtractedRoute().GetPointPosition(i).m_Longitude) * degree, + static_cast(flightPlan.GetExtractedRoute().GetPointPosition(i).m_Latitude) * degree); + break; + } + } + + if (0_m != directCoordinate.distanceTo(GeoCoordinate())) { + const GeographicLib::Gnomonic projection(GeographicLib::Geodesic::WGS84()); + Eigen::Vector2f currentCartesian, iafCartesian, directCartesian; + + /* convert to Cartesian with IAF as the reference */ + projection.Forward(static_cast(iafPosition.m_Latitude), static_cast(iafPosition.m_Longitude), + static_cast(radarTarget.GetPosition().GetPosition().m_Latitude), + static_cast(radarTarget.GetPosition().GetPosition().m_Longitude), + currentCartesian[0], currentCartesian[1]); + projection.Forward(static_cast(iafPosition.m_Latitude), static_cast(iafPosition.m_Longitude), + directCoordinate.latitude().convert(degree), + directCoordinate.longitude().convert(degree), + directCartesian[0], directCartesian[1]); + projection.Forward(static_cast(iafPosition.m_Latitude), static_cast(iafPosition.m_Longitude), + static_cast(iafPosition.m_Latitude), static_cast(iafPosition.m_Longitude), + iafCartesian[0], iafCartesian[1]); + + /* project IAF on line between current position and direct */ + const auto direction = (directCartesian - currentCartesian).normalized(); + Eigen::ParametrizedLine line(currentCartesian, direction); + const auto projectCartesian = line.projection(iafCartesian); + + const auto distanceStart = (currentCartesian - projectCartesian).squaredNorm(); + const auto distanceEnd = (directCartesian - projectCartesian).squaredNorm(); + const auto distanceDirect = (currentCartesian - directCartesian).squaredNorm(); + + /* projection of IAF in front of aircraft and not behind direct */ + if (distanceStart <= distanceDirect && distanceEnd <= distanceDirect) { + EuroScopePlugIn::CPosition projected; + float lat = 0.0f, lon = 0.0f; + + projection.Reverse(static_cast(iafPosition.m_Latitude), static_cast(iafPosition.m_Longitude), + projectCartesian[0], projectCartesian[1], lat, lon); + projected.m_Latitude = lat; + projected.m_Longitude = lon; + + const auto distanceToProjected = radarTarget.GetPosition().GetPosition().DistanceTo(projected); + report->set_distancetoiaf(static_cast(std::round(distanceToProjected))); + } + else { + report->set_distancetoiaf(0); + } + } + /* did not find the coordinate -> fallback */ + else { + report->set_distancetoiaf(0); + } + } + /* in heading mode and passed IAF */ + else { + report->set_distancetoiaf(0); + } +} + void PlugIn::generateAircraftReportMessage(EuroScopePlugIn::CRadarTarget& radarTarget, aman::AircraftReport* report) { const auto flightPlan = radarTarget.GetCorrelatedFlightPlan(); diff --git a/src/PlugIn.h b/src/PlugIn.h index 46dc828..9995e1d 100644 --- a/src/PlugIn.h +++ b/src/PlugIn.h @@ -55,6 +55,8 @@ namespace aman { void updateInbound(EuroScopePlugIn::CRadarTarget& radarTarget); void updateInbound(EuroScopePlugIn::CFlightPlan& plan); void updateSequence(std::shared_ptr& sequence); + static void distanceToPredictedIaf(const EuroScopePlugIn::CRadarTarget& radarTarget, const EuroScopePlugIn::CFlightPlan& flightPlan, + const EuroScopePlugIn::CPosition& iafPosition, aman::AircraftReport* report); Communication m_configuration; std::shared_ptr m_screen;