Sfoglia il codice sorgente

use the server's IAFs to check if we have a new inbound and over which IAF

Sven Czarnian 2 anni fa
parent
commit
1873c68ab0
2 ha cambiato i file con 113 aggiunte e 38 eliminazioni
  1. 95 26
      src/PlugIn.cpp
  2. 18 12
      src/PlugIn.h

+ 95 - 26
src/PlugIn.cpp

@@ -58,6 +58,7 @@ PlugIn::PlugIn() :
         m_screen(),
         m_updateQueueLock(),
         m_updateQueue(),
+        m_initialApproachFixes(),
         m_inboundsQueueLock(),
         m_inbounds(),
         m_forcedToBackendCallsigns(),
@@ -111,6 +112,77 @@ PlugIn::~PlugIn() {
     google::protobuf::ShutdownProtobufLibrary();
 }
 
+void PlugIn::receiveConfiguration(const std::string& airport) {
+    /* set up the URL */
+    std::string url;
+    if (true == this->m_configuration.httpsProtocol)
+        url += "https://";
+    else
+        url += "http://";
+    url += this->m_configuration.address + ":" + std::to_string(this->m_configuration.portRestAPI) + "/aman/configuration/" + airport;
+
+    CURL* curl = curl_easy_init();
+    CURLcode result;
+
+    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
+    curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, static_cast<long>(CURL_HTTP_VERSION_1_1));
+    curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
+    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 0L);
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, receiveCurl);
+    curl_easy_setopt(curl, CURLOPT_TIMEOUT, 2L);
+
+    struct curl_slist* headers = nullptr;
+    headers = curl_slist_append(headers, "Accept: */*");
+    headers = curl_slist_append(headers, "Content-Type: application/json");
+    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+
+    __receivedAmanData.clear();
+
+    result = curl_easy_perform(curl);
+
+    if (CURLE_OK != result) {
+        MessageBoxA(nullptr, "Unable to receive backend information", "AMAN-Error", MB_OK);
+        return;
+    }
+
+    /* validate the json data */
+    Json::Value root;
+    Json::CharReaderBuilder builder;
+    std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
+    if (false == reader->parse(__receivedAmanData.c_str(), __receivedAmanData.c_str() + __receivedAmanData.length(), &root, nullptr)) {
+        MessageBoxA(nullptr, "Received invalid backend data", "AMAN-Error", MB_OK);
+        return;
+    }
+
+    for (auto it = root.begin(); root.end() != it; ++it) {
+        if ("iafs" == it.key().asString() && true == it->isArray()) {
+            auto iafArray = *it;
+            this->m_initialApproachFixes.insert({ airport, {} });
+
+            this->m_initialApproachFixes[airport].reserve(iafArray.size());
+            for (Json::Value::ArrayIndex i = 0; i < iafArray.size(); ++i) {
+                if (true == iafArray[i].isObject()) {
+                    Angle latitude, longitude;
+                    std::string name;
+
+                    for (auto cit = iafArray[i].begin(); iafArray[i].end() != cit; ++cit) {
+                        if ("name" == cit.key().asString())
+                            name = cit->asString();
+                        else if ("lat" == cit.key().asString())
+                            latitude = cit->asFloat() * degree;
+                        else if ("lon" == cit.key().asString())
+                            longitude = cit->asFloat() * degree;
+                    }
+
+                    this->m_initialApproachFixes[airport].push_back({ name, GeoCoordinate(longitude, latitude) });
+                }
+            }
+        }
+    }
+}
+
 void PlugIn::validateBackendData() {
     if (false == this->m_configuration.valid) {
         this->m_compatible = false;
@@ -191,8 +263,13 @@ void PlugIn::validateBackendData() {
 
     std::lock_guard guard(this->m_updateQueueLock);
     this->m_updateQueue.clear();
-    for (const auto& airport : std::as_const(airports))
+    this->m_initialApproachFixes.clear();
+
+    for (const auto& airport : std::as_const(airports)) {
         this->m_updateQueue.insert({ airport, {} });
+        this->receiveConfiguration(airport);
+    }
+
     this->m_compatible = true;
 
     this->DisplayUserMessage(PLUGIN_NAME, "INFO", "Reloaded AMAN-configuration", true, true, false, false, false);
@@ -338,7 +415,7 @@ void PlugIn::generateAircraftReportMessage(EuroScopePlugIn::CRadarTarget& radarT
         return;
 
     /* filter invalid destinations */
-    const auto destination = std::string_view(flightPlan.GetFlightPlanData().GetDestination());
+    const auto destination = std::string(flightPlan.GetFlightPlanData().GetDestination());
     if (4 != destination.length())
         return;
 
@@ -387,36 +464,28 @@ void PlugIn::generateAircraftReportMessage(EuroScopePlugIn::CRadarTarget& radarT
     EuroScopePlugIn::CPosition iafPosition;
     std::string iafName;
 
-    for (auto element = this->SectorFileElementSelectFirst(EuroScopePlugIn::SECTOR_ELEMENT_STAR);
-         true == element.IsValid();
-         element = this->SectorFileElementSelectNext(element, EuroScopePlugIn::SECTOR_ELEMENT_STAR))
-    {
-        auto split = String::splitString(element.GetName(), " ");
-
-        /* find the correct star */
-        if (0 != split.size() && destination == gsl::at(split, 0)) {
-            /* get the IAF */
-            EuroScopePlugIn::CPosition position;
-            if (true == element.GetPosition(&position, 0)) {
-                /* match the waypoints to get the name*/
-                for (int i = 0; i < flightPlan.GetExtractedRoute().GetPointsNumber(); ++i) {
-                    if (1.0f >= flightPlan.GetExtractedRoute().GetPointPosition(i).DistanceTo(position)) {
-                        iafPosition = flightPlan.GetExtractedRoute().GetPointPosition(i);
-                        iafName = flightPlan.GetExtractedRoute().GetPointName(i);
-                        report->set_initialapproachfix(iafName);
-                        iafRouteIndex = i;
-                        break;
-                    }
+    auto iafIt = this->m_initialApproachFixes.find(destination);
+    if (this->m_initialApproachFixes.cend() != iafIt) {
+        for (const auto& iaf : std::as_const(iafIt->second)) {
+            for (int i = 0; i < flightPlan.GetExtractedRoute().GetPointsNumber(); ++i) {
+                if (flightPlan.GetExtractedRoute().GetPointName(i) == iaf.name) {
+                    iafName = iaf.name;
+                    break;
                 }
             }
-        }
 
-        if (0 != iafName.length())
-            break;
+            if (0 == iafName.length()) {
+                if (flightPlan.GetControllerAssignedData().GetDirectToPointName() == iaf.name)
+                    iafName = iaf.name;
+            }
+
+            if (0 != iafName.length())
+                break;
+        }
     }
 
     if (0 != iafName.length()) {
-        const std::string_view direct(flightPlan.GetControllerAssignedData().GetDirectToPointName());
+        std::string_view direct(flightPlan.GetControllerAssignedData().GetDirectToPointName());
         bool directBehindIAF = false;
 
         if (0 != direct.length()) {

+ 18 - 12
src/PlugIn.h

@@ -47,6 +47,10 @@ namespace aman {
             std::vector<std::string> arrivalRunways;
             std::list<std::string>   inboundUpdates;
         };
+        struct InitialApproachFix {
+            std::string   name;
+            GeoCoordinate coordinate;
+        };
 
         enum class TagItemElement {
             EstimatedTimeOfArrival = 0,
@@ -56,6 +60,7 @@ namespace aman {
         };
 
         void validateBackendData();
+        void receiveConfiguration(const std::string& airport);
         aman::Aircraft* generateAircraftMessage(const EuroScopePlugIn::CRadarTarget& target) const;
         void generateAircraftReportMessage(EuroScopePlugIn::CRadarTarget& radarTarget, aman::AircraftReport* report);
         void addUpdateQueue(EuroScopePlugIn::CRadarTarget& radarTarget);
@@ -64,18 +69,19 @@ namespace aman {
         static void distanceToPredictedIaf(const EuroScopePlugIn::CRadarTarget& radarTarget, const EuroScopePlugIn::CFlightPlan& flightPlan,
                                            const EuroScopePlugIn::CPosition& iafPosition, aman::AircraftReport* report);
 
-        Communication                      m_configuration;
-        std::shared_ptr<RadarScreen>       m_screen;
-        std::mutex                         m_updateQueueLock;
-        std::map<std::string, AirportData> m_updateQueue;
-        std::mutex                         m_inboundsQueueLock;
-        std::map<std::string, Inbound>     m_inbounds;
-        std::map<std::string, std::string> m_selectedRunway;
-        std::list<std::string>             m_forcedToBackendCallsigns;
-        bool                               m_compatible;
-        bool                               m_connectedToNetwork;
-        bool                               m_sweatboxValid;
-        bool                               m_playbackValid;
+        Communication                                          m_configuration;
+        std::shared_ptr<RadarScreen>                           m_screen;
+        std::mutex                                             m_updateQueueLock;
+        std::map<std::string, AirportData>                     m_updateQueue;
+        std::map<std::string, std::vector<InitialApproachFix>> m_initialApproachFixes;
+        std::mutex                                             m_inboundsQueueLock;
+        std::map<std::string, Inbound>                         m_inbounds;
+        std::map<std::string, std::string>                     m_selectedRunway;
+        std::list<std::string>                                 m_forcedToBackendCallsigns;
+        bool                                                   m_compatible;
+        bool                                                   m_connectedToNetwork;
+        bool                                                   m_sweatboxValid;
+        bool                                                   m_playbackValid;
 
     public:
         /**