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

This commit is contained in:
Sven Czarnian
2021-12-26 10:43:15 +01:00
parent 0a586f88c3
commit 1873c68ab0
2 changed files with 113 additions and 38 deletions

View File

@@ -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()) {

View File

@@ -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:
/**