diff --git a/plugins/feature/vorlocalizer/CMakeLists.txt b/plugins/feature/vorlocalizer/CMakeLists.txt
index ddf07bb7a..aaf5267bd 100644
--- a/plugins/feature/vorlocalizer/CMakeLists.txt
+++ b/plugins/feature/vorlocalizer/CMakeLists.txt
@@ -34,7 +34,6 @@ if(NOT SERVER_MODE)
set(vor_HEADERS
${vor_HEADERS}
vorlocalizergui.h
- navaid.h
)
set(TARGET_NAME vorlocalizer)
diff --git a/plugins/feature/vorlocalizer/navaid.h b/plugins/feature/vorlocalizer/navaid.h
deleted file mode 100644
index 1ac7419f6..000000000
--- a/plugins/feature/vorlocalizer/navaid.h
+++ /dev/null
@@ -1,368 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////////
-// Copyright (C) 2020 Jon Beniston, M7RCE //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation as version 3 of the License, or //
-// (at your option) any later version. //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License V3 for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with this program. If not, see . //
-///////////////////////////////////////////////////////////////////////////////////
-
-#ifndef INCLUDE_NAVAID_H
-#define INCLUDE_NAVAID_H
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include "util/units.h"
-#include "util/csv.h"
-
-#define OURAIRPORTS_NAVAIDS_URL "https://ourairports.com/data/navaids.csv"
-#define OPENAIP_NAVAIDS_URL "https://www.openaip.net/customer_export_akfshb9237tgwiuvb4tgiwbf/%1_nav.aip"
-
-struct NavAid {
-
- int m_id;
- QString m_ident; // 2 or 3 character ident
- QString m_type; // VOR, VOR-DME or VORTAC
- QString m_name;
- float m_latitude;
- float m_longitude;
- float m_elevation;
- int m_frequencykHz;
- QString m_channel;
- int m_range; // Nautical miles
- float m_magneticDeclination;
- bool m_alignedTrueNorth; // Is the VOR aligned to true North, rather than magnetic (may be the case at high latitudes)
-
- static QString trimQuotes(const QString s)
- {
- if (s.startsWith('\"') && s.endsWith('\"'))
- return s.mid(1, s.size() - 2);
- else
- return s;
- }
-
- int getRangeMetres()
- {
- return Units::nauticalMilesToIntegerMetres((float)m_range);
- }
-
- // OpenAIP XML file
- static void readNavAidsXML(QHash *navAidInfo, const QString &filename)
- {
- QFile file(filename);
- if (file.open(QIODevice::ReadOnly | QIODevice::Text))
- {
- QXmlStreamReader xmlReader(&file);
-
- while(!xmlReader.atEnd() && !xmlReader.hasError())
- {
- if (xmlReader.readNextStartElement())
- {
- if (xmlReader.name() == "NAVAID")
- {
- QStringRef typeRef = xmlReader.attributes().value("TYPE");
- if ((typeRef == QLatin1String("VOR"))
- || (typeRef== QLatin1String("VOR-DME"))
- || (typeRef == QLatin1String("VORTAC")))
- {
- QString type = typeRef.toString();
- int identifier = 0;
- QString name;
- QString id;
- float lat = 0.0f;
- float lon = 0.0f;
- float elevation = 0.0f;
- int frequency = 0;
- QString channel;
- int range = 25;
- float declination = 0.0f;
- bool alignedTrueNorth = false;
- while(xmlReader.readNextStartElement())
- {
- if (xmlReader.name() == QLatin1String("IDENTIFIER"))
- identifier = xmlReader.readElementText().toInt();
- else if (xmlReader.name() == QLatin1String("NAME"))
- name = xmlReader.readElementText();
- else if (xmlReader.name() == QLatin1String("ID"))
- id = xmlReader.readElementText();
- else if (xmlReader.name() == QLatin1String("GEOLOCATION"))
- {
- while(xmlReader.readNextStartElement())
- {
- if (xmlReader.name() == QLatin1String("LAT"))
- lat = xmlReader.readElementText().toFloat();
- else if (xmlReader.name() == QLatin1String("LON"))
- lon = xmlReader.readElementText().toFloat();
- else if (xmlReader.name() == QLatin1String("ELEV"))
- elevation = xmlReader.readElementText().toFloat();
- else
- xmlReader.skipCurrentElement();
- }
- }
- else if (xmlReader.name() == QLatin1String("RADIO"))
- {
- while(xmlReader.readNextStartElement())
- {
- if (xmlReader.name() == QLatin1String("FREQUENCY"))
- frequency = (int)(xmlReader.readElementText().toFloat() * 1000);
- else if (xmlReader.name() == QLatin1String("CHANNEL"))
- channel = xmlReader.readElementText();
- else
- xmlReader.skipCurrentElement();
- }
- }
- else if (xmlReader.name() == QLatin1String("PARAMS"))
- {
- while(xmlReader.readNextStartElement())
- {
- if (xmlReader.name() == QLatin1String("RANGE"))
- range = xmlReader.readElementText().toInt();
- else if (xmlReader.name() == QLatin1String("DECLINATION"))
- declination = xmlReader.readElementText().toFloat();
- else if (xmlReader.name() == QLatin1String("ALIGNEDTOTRUENORTH"))
- alignedTrueNorth = xmlReader.readElementText() == "TRUE";
- else
- xmlReader.skipCurrentElement();
- }
- }
- else
- xmlReader.skipCurrentElement();
- }
- NavAid *vor = new NavAid();
- vor->m_id = identifier;
- vor->m_ident = id;
- // Check idents conform to our filtering rules
- if (vor->m_ident.size() < 2)
- qDebug() << "Warning: VOR Ident less than 2 characters: " << vor->m_ident;
- else if (vor->m_ident.size() > 3)
- qDebug() << "Warning: VOR Ident greater than 3 characters: " << vor->m_ident;
- vor->m_type = type;
- vor->m_name = name;
- vor->m_frequencykHz = frequency;
- vor->m_channel = channel;
- vor->m_latitude = lat;
- vor->m_longitude = lon;
- vor->m_elevation = elevation;
- vor->m_range = range;
- vor->m_magneticDeclination = declination;
- vor->m_alignedTrueNorth = alignedTrueNorth;
- navAidInfo->insert(identifier, vor);
- }
- }
- }
- }
-
- file.close();
- }
- else
- qDebug() << "NavAid::readNavAidsXML: Could not open " << filename << " for reading.";
- }
-
- // Read OurAirport's NavAids CSV file
- // See comments for readOSNDB
- static QHash *readNavAidsDB(const QString &filename)
- {
- int cnt = 0;
- QHash *navAidInfo = nullptr;
-
- // Column numbers used for the data as of 2020/10/28
- int idCol = 0;
- int identCol = 2;
- int typeCol = 4;
- int nameCol = 3;
- int frequencyCol = 5;
- int latitudeCol = 6;
- int longitudeCol = 7;
- int elevationCol = 8;
- int powerCol = 18;
-
- qDebug() << "NavAid::readNavAidsDB: " << filename;
-
- FILE *file;
- QByteArray utfFilename = filename.toUtf8();
- QLocale cLocale(QLocale::C);
- if ((file = fopen(utfFilename.constData(), "r")) != NULL)
- {
- char row[2048];
-
- if (fgets(row, sizeof(row), file))
- {
- navAidInfo = new QHash();
- navAidInfo->reserve(15000);
-
- // Read header
- int idx = 0;
- char *p = strtok(row, ",");
- while (p != NULL)
- {
- if (!strcmp(p, "id"))
- idCol = idx;
- else if (!strcmp(p, "ident"))
- identCol = idx;
- else if (!strcmp(p, "type"))
- typeCol = idx;
- else if (!strcmp(p, "name"))
- nameCol = idx;
- else if (!strcmp(p, "frequency_khz"))
- frequencyCol = idx;
- else if (!strcmp(p, "latitude_deg"))
- latitudeCol = idx;
- else if (!strcmp(p, "longitude_deg"))
- longitudeCol = idx;
- else if (!strcmp(p, "elevation_ft"))
- elevationCol = idx;
- else if (!strcmp(p, "power"))
- powerCol = idx;
- p = strtok(NULL, ",");
- idx++;
- }
- // Read data
- while (fgets(row, sizeof(row), file))
- {
- int id = 0;
- char *idString = NULL;
- char *ident = NULL;
- size_t identLen = 0;
- char *type = NULL;
- size_t typeLen = 0;
- char *name = NULL;
- size_t nameLen = 0;
- char *frequencyString = NULL;
- int frequency;
- float latitude = 0.0f;
- char *latitudeString = NULL;
- size_t latitudeLen = 0;
- float longitude = 0.0f;
- char *longitudeString = NULL;
- size_t longitudeLen = 0;
- float elevation = 0.0f;
- char *elevationString = NULL;
- size_t elevationLen = 0;
- char *power = NULL;
- size_t powerLen = 0;
-
- char *q = row;
- idx = 0;
- while ((p = csvNext(&q)) != nullptr)
- {
- // Read strings, stripping quotes
- if (idx == idCol)
- {
- idString = p;
- idString[strlen(idString)] = '\0';
- id = strtol(idString, NULL, 10);
- }
- else if ((idx == identCol) && (p[0] == '\"'))
- {
- ident = p+1;
- identLen = strlen(ident)-1;
- ident[identLen] = '\0';
- }
- else if ((idx == typeCol) && (p[0] == '\"'))
- {
- type = p+1;
- typeLen = strlen(type)-1;
- type[typeLen] = '\0';
- }
- else if ((idx == nameCol) && (p[0] == '\"'))
- {
- name = p+1;
- nameLen = strlen(name)-1;
- name[nameLen] = '\0';
- }
- if (idx == frequencyCol)
- {
- frequencyString = p;
- frequencyString[strlen(frequencyString)] = '\0';
- frequency = strtol(frequencyString, NULL, 10);
- }
- else if (idx == latitudeCol)
- {
- latitudeString = p;
- latitudeLen = strlen(latitudeString)-1;
- latitudeString[latitudeLen] = '\0';
- latitude = cLocale.toFloat(latitudeString);
- }
- else if (idx == longitudeCol)
- {
- longitudeString = p;
- longitudeLen = strlen(longitudeString)-1;
- longitudeString[longitudeLen] = '\0';
- longitude = cLocale.toFloat(longitudeString);
- }
- else if (idx == elevationCol)
- {
- elevationString = p;
- elevationLen = strlen(elevationString)-1;
- elevationString[elevationLen] = '\0';
- elevation = cLocale.toFloat(elevationString);
- }
- else if ((idx == powerCol) && (p[0] == '\"'))
- {
- power = p+1;
- powerLen = strlen(power)-1;
- power[powerLen] = '\0';
- }
- idx++;
- }
-
- // For now, we only want VORs
- if (type && !strncmp(type, "VOR", 3))
- {
- NavAid *vor = new NavAid();
- vor->m_id = id;
- vor->m_ident = QString(ident);
- // Check idents conform to our filtering rules
- if (vor->m_ident.size() < 2)
- qDebug() << "Warning: VOR Ident less than 2 characters: " << vor->m_ident;
- else if (vor->m_ident.size() > 3)
- qDebug() << "Warning: VOR Ident greater than 3 characters: " << vor->m_ident;
- vor->m_type = QString(type);
- vor->m_name = QString(name);
- vor->m_frequencykHz = frequency;
- vor->m_latitude = latitude;
- vor->m_longitude = longitude;
- vor->m_elevation = elevation;
- if (power && !strcmp(power, "HIGH"))
- vor->m_range = 100;
- else if (power && !strcmp(power, "MEDIUM"))
- vor->m_range = 40;
- else
- vor->m_range = 25;
- vor->m_magneticDeclination = 0.0f;
- vor->m_alignedTrueNorth = false;
- navAidInfo->insert(id, vor);
- cnt++;
- }
- }
- }
- fclose(file);
- }
- else
- qDebug() << "NavAid::readNavAidsDB: Failed to open " << filename;
-
- qDebug() << "NavAid::readNavAidsDB: Read " << cnt << " VORs";
-
- return navAidInfo;
- }
-
-};
-
-#endif // INCLUDE_NAVAID_H
diff --git a/plugins/feature/vorlocalizer/vorlocalizergui.cpp b/plugins/feature/vorlocalizer/vorlocalizergui.cpp
index 2e4c0b965..a00085a19 100644
--- a/plugins/feature/vorlocalizer/vorlocalizergui.cpp
+++ b/plugins/feature/vorlocalizer/vorlocalizergui.cpp
@@ -47,258 +47,6 @@
#include "vorlocalizersettings.h"
#include "vorlocalizergui.h"
-static const char *countryCodes[] = {
- "ad",
- "ae",
- "af",
- "ag",
- "ai",
- "al",
- "am",
- "an",
- "ao",
- "aq",
- "ar",
- "as",
- "at",
- "au",
- "aw",
- "ax",
- "az",
- "ba",
- "bb",
- "bd",
- "be",
- "bf",
- "bg",
- "bh",
- "bi",
- "bj",
- "bl",
- "bm",
- "bn",
- "bo",
- "bq",
- "br",
- "bs",
- "bt",
- "bv",
- "bw",
- "by",
- "bz",
- "ca",
- "cc",
- "cd",
- "cf",
- "cg",
- "ch",
- "ci",
- "ck",
- "cl",
- "cm",
- "cn",
- "co",
- "cr",
- "cu",
- "cv",
- "cw",
- "cx",
- "cy",
- "cz",
- "de",
- "dj",
- "dk",
- "dm",
- "do",
- "dz",
- "ec",
- "ee",
- "eg",
- "eh",
- "er",
- "es",
- "et",
- "fi",
- "fj",
- "fk",
- "fm",
- "fo",
- "fr",
- "ga",
- "gb",
- "ge",
- "gf",
- "gg",
- "gh",
- "gi",
- "gl",
- "gm",
- "gn",
- "gp",
- "gq",
- "gr",
- "gs",
- "gt",
- "gu",
- "gw",
- "gy",
- "hk",
- "hm",
- "hn",
- "hr",
- "hu",
- "id",
- "ie",
- "il",
- "im",
- "in",
- "io",
- "iq",
- "ir",
- "is",
- "it",
- "je",
- "jm",
- "jo",
- "jp",
- "ke",
- "kg",
- "kh",
- "ki",
- "km",
- "kn",
- "kp",
- "kr",
- "kw",
- "ky",
- "kz",
- "la",
- "lb",
- "lc",
- "li",
- "lk",
- "lr",
- "ls",
- "lt",
- "lu",
- "lv",
- "ly",
- "ma",
- "mc",
- "md",
- "me",
- "mf",
- "mg",
- "mh",
- "mk",
- "ml",
- "mm",
- "mn",
- "mo",
- "mp",
- "mq",
- "mr",
- "ms",
- "mt",
- "mu",
- "mv",
- "mw",
- "mx",
- "my",
- "mz",
- "na",
- "nc",
- "ne",
- "nf",
- "ng",
- "ni",
- "nl",
- "no",
- "np",
- "nr",
- "nu",
- "nz",
- "om",
- "pa",
- "pe",
- "pf",
- "pg",
- "ph",
- "pk",
- "pl",
- "pm",
- "pn",
- "pr",
- "ps",
- "pt",
- "pw",
- "py",
- "qa",
- "re",
- "ro",
- "rs",
- "ru",
- "rw",
- "sa",
- "sb",
- "sc",
- "sd",
- "se",
- "sg",
- "sh",
- "si",
- "sj",
- "sk",
- "sl",
- "sm",
- "sn",
- "so",
- "sr",
- "ss",
- "st",
- "sv",
- "sx",
- "sy",
- "sz",
- "tc",
- "td",
- "tf",
- "tg",
- "th",
- "tj",
- "tk",
- "tl",
- "tm",
- "tn",
- "to",
- "tr",
- "tt",
- "tv",
- "tw",
- "tz",
- "ua",
- "ug",
- "um",
- "us",
- "uy",
- "uz",
- "va",
- "vc",
- "ve",
- "vg",
- "vi",
- "vn",
- "vu",
- "wf",
- "ws",
- "ye",
- "yt",
- "za",
- "zm",
- "zw",
- nullptr
-};
-
// Lats and longs in decimal degrees. Distance in metres. Bearing in degrees.
// https://www.movable-type.co.uk/scripts/latlong.html
static void calcRadialEndPoint(float startLatitude, float startLongitude, float distance, float bearing, float &endLatitude, float &endLongitude)
@@ -702,7 +450,7 @@ void VORLocalizerGUI::selectVOR(VORGUI *vorGUI, bool selected)
// Add to settings to create corresponding demodulator
m_settings.m_subChannelSettings.insert(navId, VORLocalizerSubChannelSettings{
navId,
- vorGUI->m_navAid->m_frequencykHz * 1000,
+ (int)(vorGUI->m_navAid->m_frequencykHz * 1000),
false
});
@@ -725,23 +473,21 @@ void VORLocalizerGUI::selectVOR(VORGUI *vorGUI, bool selected)
void VORLocalizerGUI::updateVORs()
{
m_vorModel.removeAllVORs();
- QHash::iterator i = m_vors->begin();
AzEl azEl = m_azEl;
- while (i != m_vors->end())
+ for (auto vor : m_vors)
{
- NavAid *vor = i.value();
+ if (vor->m_type.contains("VOR")) // Exclude DMEs
+ {
+ // Calculate distance to VOR from My Position
+ azEl.setTarget(vor->m_latitude, vor->m_longitude, Units::feetToMetres(vor->m_elevation));
+ azEl.calculate();
- // Calculate distance to VOR from My Position
- azEl.setTarget(vor->m_latitude, vor->m_longitude, Units::feetToMetres(vor->m_elevation));
- azEl.calculate();
-
- // Only display VOR if in range
- if (azEl.getDistance() <= 200000) {
- m_vorModel.addVOR(vor);
+ // Only display VOR if in range
+ if (azEl.getDistance() <= 200000) {
+ m_vorModel.addVOR(vor);
+ }
}
-
- ++i;
}
}
@@ -807,41 +553,47 @@ bool VORLocalizerGUI::handleMessage(const Message& message)
int subChannelId = report.getSubChannelId();
VORGUI *vorGUI = m_selectedVORs.value(subChannelId);
+ if (vorGUI)
+ {
+ // Display radial and signal magnitudes in table
- // Display radial and signal magnitudes in table
+ Real varMagDB = std::round(20.0*std::log10(report.getVarMag()));
+ Real refMagDB = std::round(20.0*std::log10(report.getRefMag()));
- Real varMagDB = std::round(20.0*std::log10(report.getVarMag()));
- Real refMagDB = std::round(20.0*std::log10(report.getRefMag()));
+ bool validRadial = report.getValidRadial();
+ vorGUI->m_radialItem->setData(Qt::DisplayRole, std::round(report.getRadial()));
+ vorGUI->m_navIdItem->setData(Qt::DisplayRole, subChannelId);
- bool validRadial = report.getValidRadial();
- vorGUI->m_radialItem->setData(Qt::DisplayRole, std::round(report.getRadial()));
- vorGUI->m_navIdItem->setData(Qt::DisplayRole, subChannelId);
+ if (validRadial) {
+ vorGUI->m_radialItem->setForeground(QBrush(Qt::white));
+ } else {
+ vorGUI->m_radialItem->setForeground(QBrush(Qt::red));
+ }
- if (validRadial) {
- vorGUI->m_radialItem->setForeground(QBrush(Qt::white));
- } else {
- vorGUI->m_radialItem->setForeground(QBrush(Qt::red));
+ vorGUI->m_refMagItem->setData(Qt::DisplayRole, refMagDB);
+
+ if (report.getValidRefMag()) {
+ vorGUI->m_refMagItem->setForeground(QBrush(Qt::white));
+ } else {
+ vorGUI->m_refMagItem->setForeground(QBrush(Qt::red));
+ }
+
+ vorGUI->m_varMagItem->setData(Qt::DisplayRole, varMagDB);
+
+ if (report.getValidVarMag()) {
+ vorGUI->m_varMagItem->setForeground(QBrush(Qt::white));
+ } else {
+ vorGUI->m_varMagItem->setForeground(QBrush(Qt::red));
+ }
+
+ // Update radial on map
+ m_vorModel.setRadial(subChannelId, validRadial, report.getRadial());
}
-
- vorGUI->m_refMagItem->setData(Qt::DisplayRole, refMagDB);
-
- if (report.getValidRefMag()) {
- vorGUI->m_refMagItem->setForeground(QBrush(Qt::white));
- } else {
- vorGUI->m_refMagItem->setForeground(QBrush(Qt::red));
+ else
+ {
+ qDebug() << "VORLocalizerGUI::handleMessage: Got MsgReportRadial for non-existant subChannelId " << subChannelId;
}
- vorGUI->m_varMagItem->setData(Qt::DisplayRole, varMagDB);
-
- if (report.getValidVarMag()) {
- vorGUI->m_varMagItem->setForeground(QBrush(Qt::white));
- } else {
- vorGUI->m_varMagItem->setForeground(QBrush(Qt::red));
- }
-
- // Update radial on map
- m_vorModel.setRadial(subChannelId, validRadial, report.getRadial());
-
return true;
}
else if (VORLocalizerReport::MsgReportIdent::match(message))
@@ -850,38 +602,45 @@ bool VORLocalizerGUI::handleMessage(const Message& message)
int subChannelId = report.getSubChannelId();
VORGUI *vorGUI = m_selectedVORs.value(subChannelId);
-
- QString ident = report.getIdent();
- // Convert Morse to a string
- QString identString = Morse::toString(ident);
- // Idents should only be two or three characters, so filter anything else
- // other than TEST which indicates a VOR is under maintainance (may also be TST)
- if (((identString.size() >= 2) && (identString.size() <= 3)) || (identString == "TEST"))
+ if (vorGUI)
{
- vorGUI->m_rxIdentItem->setText(identString);
- vorGUI->m_rxMorseItem->setText(Morse::toSpacedUnicode(ident));
- if (vorGUI->m_navAid->m_ident == identString)
+ QString ident = report.getIdent();
+ // Convert Morse to a string
+ QString identString = Morse::toString(ident);
+ // Idents should only be two or three characters, so filter anything else
+ // other than TEST which indicates a VOR is under maintainance (may also be TST)
+ if (((identString.size() >= 2) && (identString.size() <= 3)) || (identString == "TEST"))
{
- // Set colour to green if matching expected ident
- vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::green));
- vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::green));
+ vorGUI->m_rxIdentItem->setText(identString);
+ vorGUI->m_rxMorseItem->setText(Morse::toSpacedUnicode(ident));
+
+ if (vorGUI->m_navAid->m_ident == identString)
+ {
+ // Set colour to green if matching expected ident
+ vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::green));
+ vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::green));
+ }
+ else
+ {
+ // Set colour to green if not matching expected ident
+ vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::red));
+ vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::red));
+ }
}
else
{
- // Set colour to green if not matching expected ident
- vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::red));
- vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::red));
+ // Set yellow to indicate we've filtered something (unless red)
+ if (vorGUI->m_rxIdentItem->foreground().color() != Qt::red)
+ {
+ vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::yellow));
+ vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::yellow));
+ }
}
}
else
{
- // Set yellow to indicate we've filtered something (unless red)
- if (vorGUI->m_rxIdentItem->foreground().color() != Qt::red)
- {
- vorGUI->m_rxIdentItem->setForeground(QBrush(Qt::yellow));
- vorGUI->m_rxMorseItem->setForeground(QBrush(Qt::yellow));
- }
+ qDebug() << "VORLocalizerGUI::handleMessage: Got MsgReportIdent for non-existant subChannelId " << subChannelId;
}
return true;
@@ -938,142 +697,6 @@ void VORLocalizerGUI::handleInputMessages()
}
}
-qint64 VORLocalizerGUI::fileAgeInDays(QString filename)
-{
- QFile file(filename);
-
- if (file.exists())
- {
- QDateTime modified = file.fileTime(QFileDevice::FileModificationTime);
-
- if (modified.isValid()) {
- return modified.daysTo(QDateTime::currentDateTime());
- } else {
- return -1;
- }
- }
-
- return -1;
-}
-
-bool VORLocalizerGUI::confirmDownload(QString filename)
-{
- qint64 age = fileAgeInDays(filename);
-
- if ((age == -1) || (age > 100))
- {
- return true;
- }
- else
- {
- QMessageBox::StandardButton reply;
-
- if (age == 0) {
- reply = QMessageBox::question(this, "Confirm download", "This file was last downloaded today. Are you sure you wish to redownload it?", QMessageBox::Yes|QMessageBox::No);
- } else if (age == 1) {
- reply = QMessageBox::question(this, "Confirm download", "This file was last downloaded yesterday. Are you sure you wish to redownload it?", QMessageBox::Yes|QMessageBox::No);
- } else {
- reply = QMessageBox::question(this, "Confirm download", QString("This file was last downloaded %1 days ago. Are you sure you wish to redownload this file?").arg(age), QMessageBox::Yes|QMessageBox::No);
- }
-
- return reply == QMessageBox::Yes;
- }
-}
-
-QString VORLocalizerGUI::getDataDir()
-{
- // Get directory to store app data in
- QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
- // First dir is writable
- return locations[0];
-}
-
-QString VORLocalizerGUI::getOpenAIPVORDBFilename(int i)
-{
- if (countryCodes[i] != nullptr) {
- return getDataDir() + "/" + countryCodes[i] + "_nav.aip";
- } else {
- return "";
- }
-}
-
-QString VORLocalizerGUI::getOpenAIPVORDBURL(int i)
-{
- if (countryCodes[i] != nullptr) {
- return QString(OPENAIP_NAVAIDS_URL).arg(countryCodes[i]);
- } else {
- return "";
- }
-}
-
-QString VORLocalizerGUI::getVORDBFilename()
-{
- return getDataDir() + "/vorDatabase.csv";
-}
-
-void VORLocalizerGUI::updateDownloadProgress(qint64 bytesRead, qint64 totalBytes)
-{
- if (m_progressDialog)
- {
- m_progressDialog->setMaximum(totalBytes);
- m_progressDialog->setValue(bytesRead);
- }
-}
-
-void VORLocalizerGUI::downloadFinished(const QString& filename, bool success)
-{
- bool closeDialog = true;
- if (success)
- {
- if (filename == getVORDBFilename())
- {
- m_vors = NavAid::readNavAidsDB(filename);
-
- if (m_vors != nullptr) {
- updateVORs();
- }
- }
- else if (filename == getOpenAIPVORDBFilename(m_countryIndex))
- {
- m_countryIndex++;
-
- if (countryCodes[m_countryIndex] != nullptr)
- {
- QString vorDBFile = getOpenAIPVORDBFilename(m_countryIndex);
- QString urlString = getOpenAIPVORDBURL(m_countryIndex);
- QUrl dbURL(urlString);
- m_progressDialog->setLabelText(QString("Downloading %1.").arg(urlString));
- m_progressDialog->setValue(m_countryIndex);
- m_dlm.download(dbURL, vorDBFile);
- closeDialog = false;
- }
- else
- {
- readNavAids();
-
- if (m_vors) {
- updateVORs();
- }
- }
- }
- else
- {
- qDebug() << "VORLocalizerGUI::downloadFinished: Unexpected filename: " << filename;
- }
- }
- else
- {
- qDebug() << "VORLocalizerGUI::downloadFinished: Failed: " << filename;
- QMessageBox::warning(this, "Download failed", QString("Failed to download %1").arg(filename));
- }
- if (closeDialog && m_progressDialog)
- {
- m_progressDialog->close();
- delete m_progressDialog;
- m_progressDialog = nullptr;
- }
-}
-
void VORLocalizerGUI::on_startStop_toggled(bool checked)
{
if (m_doApplySettings)
@@ -1083,59 +706,56 @@ void VORLocalizerGUI::on_startStop_toggled(bool checked)
}
}
-void VORLocalizerGUI::on_getOurAirportsVORDB_clicked()
-{
- // Don't try to download while already in progress
- if (m_progressDialog == nullptr)
- {
- QString vorDBFile = getVORDBFilename();
-
- if (confirmDownload(vorDBFile))
- {
- // Download OurAirports navaid database to disk
- QUrl dbURL(QString(OURAIRPORTS_NAVAIDS_URL));
- m_progressDialog = new QProgressDialog(this);
- m_progressDialog->setCancelButton(nullptr);
- m_progressDialog->setMinimumDuration(500);
- m_progressDialog->setLabelText(QString("Downloading %1.").arg(OURAIRPORTS_NAVAIDS_URL));
- QNetworkReply *reply = m_dlm.download(dbURL, vorDBFile);
- connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDownloadProgress(qint64,qint64)));
- }
- }
-}
-
void VORLocalizerGUI::on_getOpenAIPVORDB_clicked()
{
// Don't try to download while already in progress
if (!m_progressDialog)
{
- m_countryIndex = 0;
- QString vorDBFile = getOpenAIPVORDBFilename(m_countryIndex);
+ m_progressDialog = new QProgressDialog(this);
+ m_progressDialog->setMaximum(OpenAIP::m_countryCodes.size());
+ m_progressDialog->setCancelButton(nullptr);
- if (confirmDownload(vorDBFile))
- {
- // Download OpenAIP XML to disk
- QString urlString = getOpenAIPVORDBURL(m_countryIndex);
- QUrl dbURL(urlString);
- m_progressDialog = new QProgressDialog(this);
- m_progressDialog->setCancelButton(nullptr);
- m_progressDialog->setMinimumDuration(500);
- m_progressDialog->setMaximum(sizeof(countryCodes)/sizeof(countryCodes[0]));
- m_progressDialog->setValue(0);
- m_progressDialog->setLabelText(QString("Downloading %1.").arg(urlString));
- m_dlm.download(dbURL, vorDBFile);
- }
+ m_openAIP.downloadNavAids();
}
}
void VORLocalizerGUI::readNavAids()
{
- m_vors = new QHash();
+ m_vors = OpenAIP::readNavAids();
+ updateVORs();
+}
- for (int countryIndex = 0; countryCodes[countryIndex] != nullptr; countryIndex++)
+void VORLocalizerGUI::downloadingURL(const QString& url)
+{
+ if (m_progressDialog)
{
- QString vorDBFile = getOpenAIPVORDBFilename(countryIndex);
- NavAid::readNavAidsXML(m_vors, vorDBFile);
+ m_progressDialog->setLabelText(QString("Downloading %1.").arg(url));
+ m_progressDialog->setValue(m_progressDialog->value() + 1);
+ }
+}
+
+void VORLocalizerGUI::downloadError(const QString& error)
+{
+ QMessageBox::critical(this, "VOR Localizer", error);
+ if (m_progressDialog)
+ {
+ m_progressDialog->close();
+ delete m_progressDialog;
+ m_progressDialog = nullptr;
+ }
+}
+
+void VORLocalizerGUI::downloadNavAidsFinished()
+{
+ if (m_progressDialog) {
+ m_progressDialog->setLabelText("Reading NAVAIDs.");
+ }
+ readNavAids();
+ if (m_progressDialog)
+ {
+ m_progressDialog->close();
+ delete m_progressDialog;
+ m_progressDialog = nullptr;
}
}
@@ -1231,7 +851,6 @@ VORLocalizerGUI::VORLocalizerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISe
m_tickCount(0),
m_progressDialog(nullptr),
m_vorModel(this),
- m_vors(nullptr),
m_lastFeatureState(0),
m_rrSecondsCount(0)
{
@@ -1250,7 +869,9 @@ VORLocalizerGUI::VORLocalizerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISe
m_muteIcon.addPixmap(QPixmap("://sound_on.png"), QIcon::Normal, QIcon::Off);
connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &)));
- connect(&m_dlm, &HttpDownloadManager::downloadComplete, this, &VORLocalizerGUI::downloadFinished);
+ connect(&m_openAIP, &OpenAIP::downloadingURL, this, &VORLocalizerGUI::downloadingURL);
+ connect(&m_openAIP, &OpenAIP::downloadError, this, &VORLocalizerGUI::downloadError);
+ connect(&m_openAIP, &OpenAIP::downloadNavAidsFinished, this, &VORLocalizerGUI::downloadNavAidsFinished);
m_vorLocalizer = reinterpret_cast(feature);
m_vorLocalizer->setMessageQueueToGUI(getInputMessageQueue());
@@ -1293,22 +914,8 @@ VORLocalizerGUI::VORLocalizerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISe
}
// Read in VOR information if it exists
- bool useOurAirports = false;
-
- if (useOurAirports)
- {
- m_vors = NavAid::readNavAidsDB(getVORDBFilename());
- ui->getOpenAIPVORDB->setVisible(false);
- }
- else
- {
- readNavAids();
- ui->getOurAirportsVORDB->setVisible(false);
- }
-
- if (m_vors) {
- updateVORs();
- }
+ readNavAids();
+ ui->getOurAirportsVORDB->setVisible(false);
// Resize the table using dummy data
resizeTable();
@@ -1346,6 +953,7 @@ VORLocalizerGUI::VORLocalizerGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISe
VORLocalizerGUI::~VORLocalizerGUI()
{
delete ui;
+ qDeleteAll(m_vors);
}
void VORLocalizerGUI::blockApplySettings(bool block)
@@ -1459,7 +1067,6 @@ void VORLocalizerGUI::tick()
void VORLocalizerGUI::makeUIConnections()
{
QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &VORLocalizerGUI::on_startStop_toggled);
- QObject::connect(ui->getOurAirportsVORDB, &QPushButton::clicked, this, &VORLocalizerGUI::on_getOurAirportsVORDB_clicked);
QObject::connect(ui->getOpenAIPVORDB, &QPushButton::clicked, this, &VORLocalizerGUI::on_getOpenAIPVORDB_clicked);
QObject::connect(ui->magDecAdjust, &ButtonSwitch::toggled, this, &VORLocalizerGUI::on_magDecAdjust_toggled);
QObject::connect(ui->rrTime, &QDial::valueChanged, this, &VORLocalizerGUI::on_rrTime_valueChanged);
diff --git a/plugins/feature/vorlocalizer/vorlocalizergui.h b/plugins/feature/vorlocalizer/vorlocalizergui.h
index 0f741c952..51639ad92 100644
--- a/plugins/feature/vorlocalizer/vorlocalizergui.h
+++ b/plugins/feature/vorlocalizer/vorlocalizergui.h
@@ -37,10 +37,10 @@
#include "util/messagequeue.h"
#include "util/httpdownloadmanager.h"
#include "util/azel.h"
+#include "util/openaip.h"
#include "settings/rollupstate.h"
#include "vorlocalizersettings.h"
-#include "navaid.h"
class PluginAPI;
class FeatureUISet;
@@ -239,9 +239,10 @@ private:
QMenu *menu; // Column select context menu
HttpDownloadManager m_dlm;
QProgressDialog *m_progressDialog;
+ OpenAIP m_openAIP;
int m_countryIndex;
VORModel m_vorModel;
- QHash *m_vors;
+ QList m_vors;
QHash m_selectedVORs;
AzEl m_azEl; // Position of station
QIcon m_muteIcon;
@@ -264,19 +265,11 @@ private:
void calculateFreqOffset(VORGUI *vorGUI);
void calculateFreqOffsets();
void updateVORs();
- QString getOpenAIPVORDBURL(int i);
- QString getOpenAIPVORDBFilename(int i);
- QString getVORDBFilename();
void readNavAids();
- // Move to util
- QString getDataDir();
- qint64 fileAgeInDays(QString filename);
- bool confirmDownload(QString filename);
void updateChannelList();
private slots:
void on_startStop_toggled(bool checked);
- void on_getOurAirportsVORDB_clicked();
void on_getOpenAIPVORDB_clicked();
void on_magDecAdjust_toggled(bool checked);
void on_rrTime_valueChanged(int value);
@@ -288,11 +281,12 @@ private slots:
void columnSelectMenuChecked(bool checked = false);
void onWidgetRolled(QWidget* widget, bool rollDown);
void onMenuDialogCalled(const QPoint& p);
- void updateDownloadProgress(qint64 bytesRead, qint64 totalBytes);
- void downloadFinished(const QString& filename, bool success);
void handleInputMessages();
void updateStatus();
void tick();
+ void downloadingURL(const QString& url);
+ void downloadError(const QString& error);
+ void downloadNavAidsFinished();
};
#endif // INCLUDE_VORLOCALIZERGUI_H
diff --git a/sdrbase/util/openaip.h b/sdrbase/util/openaip.h
index 12434ba82..2c358a22c 100644
--- a/sdrbase/util/openaip.h
+++ b/sdrbase/util/openaip.h
@@ -50,7 +50,6 @@ struct SDRBASE_API Airspace {
};
QString m_category; // A-G, GLIDING, DANGER, PROHIBITED, TMZ
- int m_id;
QString m_country; // GB
QString m_name; // BIGGIN HILL ATZ 129.405 - TODO: Extract frequency so we can tune to it
AltLimit m_top; // Top of airspace
@@ -139,11 +138,7 @@ struct SDRBASE_API Airspace {
while(xmlReader.readNextStartElement())
{
- if (xmlReader.name() == QLatin1String("ID"))
- {
- airspace->m_id = xmlReader.readElementText().toInt();
- }
- else if (xmlReader.name() == QLatin1String("COUNTRY"))
+ if (xmlReader.name() == QLatin1String("COUNTRY"))
{
airspace->m_country = xmlReader.readElementText();
}
@@ -237,7 +232,7 @@ struct SDRBASE_API Airspace {
};
struct SDRBASE_API NavAid {
-
+ int m_id; // Unique ID needed by VOR feature - Don't use value from database as that's 96-bit
QString m_ident; // 2 or 3 character ident
QString m_type; // NDB, VOR, VOR-DME or VORTAC
QString m_name;
@@ -258,6 +253,7 @@ struct SDRBASE_API NavAid {
// OpenAIP XML file
static QList readXML(const QString &filename)
{
+ int uniqueId = 1;
QList navAidInfo;
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
@@ -352,6 +348,7 @@ struct SDRBASE_API NavAid {
}
}
NavAid *navAid = new NavAid();
+ navAid->m_id = uniqueId++;
navAid->m_ident = id;
// Check idents conform to our filtering rules
if (navAid->m_ident.size() < 2) {