diff --git a/doc/img/Map_plugin_radiotime_dialog.png b/doc/img/Map_plugin_radiotime_dialog.png
new file mode 100644
index 000000000..b2f7a11f3
Binary files /dev/null and b/doc/img/Map_plugin_radiotime_dialog.png differ
diff --git a/plugins/feature/map/CMakeLists.txt b/plugins/feature/map/CMakeLists.txt
index 21528646a..536ba6e22 100644
--- a/plugins/feature/map/CMakeLists.txt
+++ b/plugins/feature/map/CMakeLists.txt
@@ -33,6 +33,8 @@ if(NOT SERVER_MODE)
mapsettingsdialog.ui
mapbeacondialog.cpp
mapbeacondialog.ui
+ mapradiotimedialog.cpp
+ mapradiotimedialog.ui
map.qrc
icons.qrc
)
@@ -43,6 +45,7 @@ if(NOT SERVER_MODE)
mapmaidenheaddialog.h
mapsettingsdialog.h
mapbeacondialog.h
+ mapradiotimedialog.h
)
set(TARGET_NAME map)
diff --git a/plugins/feature/map/icons.qrc b/plugins/feature/map/icons.qrc
index f462b389c..ba855ff49 100644
--- a/plugins/feature/map/icons.qrc
+++ b/plugins/feature/map/icons.qrc
@@ -1,5 +1,6 @@
icons/groundtracks.png
+ icons/clock.png
diff --git a/plugins/feature/map/icons/clock.png b/plugins/feature/map/icons/clock.png
new file mode 100644
index 000000000..a6dbea210
Binary files /dev/null and b/plugins/feature/map/icons/clock.png differ
diff --git a/plugins/feature/map/map.qrc b/plugins/feature/map/map.qrc
index 0310f0732..9f6072bb1 100644
--- a/plugins/feature/map/map.qrc
+++ b/plugins/feature/map/map.qrc
@@ -3,5 +3,6 @@
map/map.qml
map/map_5_12.qml
map/antenna.png
+ map/antennatime.png
diff --git a/plugins/feature/map/map/antennatime.png b/plugins/feature/map/map/antennatime.png
new file mode 100644
index 000000000..61b29c8ae
Binary files /dev/null and b/plugins/feature/map/map/antennatime.png differ
diff --git a/plugins/feature/map/mapgui.cpp b/plugins/feature/map/mapgui.cpp
index 5b8866570..c3cce4ed8 100644
--- a/plugins/feature/map/mapgui.cpp
+++ b/plugins/feature/map/mapgui.cpp
@@ -679,7 +679,8 @@ MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
m_doApplySettings(true),
m_mapModel(this),
m_beacons(nullptr),
- m_beaconDialog(this)
+ m_beaconDialog(this),
+ m_radioTimeDialog(this)
{
ui->setupUi(this);
@@ -738,6 +739,8 @@ MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
QList *beacons = Beacon::readIARUCSV(MapGUI::getBeaconFilename());
if (beacons != nullptr)
setBeacons(beacons);
+
+ addRadioTimeTransmitters();
}
MapGUI::~MapGUI()
@@ -770,6 +773,37 @@ void MapGUI::setBeacons(QList *beacons)
}
}
+const QList MapGUI::m_radioTimeTransmitters = {
+ {"MSF", 60000, 54.9075f, -3.27333f, 17},
+ {"DCF77", 77500, 50.01611111f, 9.00805556f, 50},
+ {"TDF", 162000, 47.1694f, 2.2044f, 800},
+ {"WWVB", 60000, 40.67805556f, -105.04666667f, 70},
+ {"JJY", 60000, 33.465f, 130.175555f, 50}
+};
+
+void MapGUI::addRadioTimeTransmitters()
+{
+ for (int i = 0; i < m_radioTimeTransmitters.size(); i++)
+ {
+ SWGSDRangel::SWGMapItem timeMapItem;
+ // Need to suffix frequency, as there are multiple becaons with same callsign at different locations
+ QString name = QString("%1").arg(m_radioTimeTransmitters[i].m_callsign);
+ timeMapItem.setName(new QString(name));
+ timeMapItem.setLatitude(m_radioTimeTransmitters[i].m_latitude);
+ timeMapItem.setLongitude(m_radioTimeTransmitters[i].m_longitude);
+ timeMapItem.setAltitude(0.0);
+ timeMapItem.setImage(new QString("antennatime.png"));
+ timeMapItem.setImageRotation(0);
+ timeMapItem.setImageMinZoom(8);
+ QString text = QString("Radio Time Transmitter\nCallsign: %1\nFrequency: %2 kHz\nPower: %3 kW")
+ .arg(m_radioTimeTransmitters[i].m_callsign)
+ .arg(m_radioTimeTransmitters[i].m_frequency/1000.0)
+ .arg(m_radioTimeTransmitters[i].m_power);
+ timeMapItem.setText(new QString(text));
+ m_mapModel.update(m_map, &timeMapItem, MapSettings::SOURCE_RADIO_TIME);
+ }
+}
+
void MapGUI::blockApplySettings(bool block)
{
m_doApplySettings = !block;
@@ -1033,6 +1067,12 @@ void MapGUI::on_beacons_clicked()
m_beaconDialog.show();
}
+void MapGUI::on_radiotime_clicked()
+{
+ m_radioTimeDialog.updateTable();
+ m_radioTimeDialog.show();
+}
+
quint32 MapGUI::getSourceMask(const PipeEndPoint *sourcePipe)
{
for (int i = 0; i < m_availablePipes.size(); i++)
diff --git a/plugins/feature/map/mapgui.h b/plugins/feature/map/mapgui.h
index 8bc3474e5..8b2c02005 100644
--- a/plugins/feature/map/mapgui.h
+++ b/plugins/feature/map/mapgui.h
@@ -31,6 +31,7 @@
#include "mapsettings.h"
#include "SWGMapItem.h"
#include "mapbeacondialog.h"
+#include "mapradiotimedialog.h"
class PluginAPI;
class FeatureUISet;
@@ -45,6 +46,14 @@ class MapModel;
class QQuickItem;
struct Beacon;
+struct RadioTimeTransmitter {
+ QString m_callsign;
+ int m_frequency; // In Hz
+ float m_latitude; // In degrees
+ float m_longitude; // In degrees
+ int m_power; // In kW
+};
+
// Information required about each item displayed on the map
class MapItem {
@@ -471,6 +480,8 @@ public:
static QString getBeaconFilename();
QList *getBeacons() { return m_beacons; }
void setBeacons(QList *beacons);
+ QList getRadioTimeTransmitters() { return m_radioTimeTransmitters; }
+ void addRadioTimeTransmitters();
void find(const QString& target);
private:
@@ -487,6 +498,7 @@ private:
AzEl m_azEl; // Position of station
QList *m_beacons;
MapBeaconDialog m_beaconDialog;
+ MapRadioTimeDialog m_radioTimeDialog;
explicit MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
virtual ~MapGUI();
@@ -502,6 +514,7 @@ private:
void enterEvent(QEvent*);
static QString getDataDir();
+ static const QList m_radioTimeTransmitters;
private slots:
void onMenuDialogCalled(const QPoint &p);
@@ -516,6 +529,7 @@ private slots:
void on_displaySettings_clicked();
void on_mapTypes_currentIndexChanged(int index);
void on_beacons_clicked();
+ void on_radiotime_clicked();
};
diff --git a/plugins/feature/map/mapgui.ui b/plugins/feature/map/mapgui.ui
index 05bc51f4a..8a5a5b39b 100644
--- a/plugins/feature/map/mapgui.ui
+++ b/plugins/feature/map/mapgui.ui
@@ -140,6 +140,20 @@
+ -
+
+
+ Display radio time transmitters dialog
+
+
+
+
+
+
+ :/map/icons/clock.png:/map/icons/clock.png
+
+
+
-
@@ -165,6 +179,7 @@
Adobe Devanagari
+ 9
@@ -190,6 +205,7 @@
Adobe Devanagari
+ 9
diff --git a/plugins/feature/map/mapradiotimedialog.cpp b/plugins/feature/map/mapradiotimedialog.cpp
new file mode 100644
index 000000000..4f2ebf478
--- /dev/null
+++ b/plugins/feature/map/mapradiotimedialog.cpp
@@ -0,0 +1,89 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2021 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 . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "mapradiotimedialog.h"
+
+#include
+
+#include "channel/channelwebapiutils.h"
+#include "mapgui.h"
+
+MapRadioTimeDialog::MapRadioTimeDialog(MapGUI *gui, QWidget* parent) :
+ QDialog(parent),
+ m_gui(gui),
+ ui(new Ui::MapRadioTimeDialog)
+{
+ ui->setupUi(this);
+ // Don't call updateTable until m_gui->getAzEl() will return valid location
+}
+
+MapRadioTimeDialog::~MapRadioTimeDialog()
+{
+ delete ui;
+}
+
+void MapRadioTimeDialog::updateTable()
+{
+ AzEl azEl = *m_gui->getAzEl();
+ ui->transmitters->setSortingEnabled(false);
+ const QList transmitters = m_gui->getRadioTimeTransmitters();
+ ui->transmitters->setRowCount(0);
+ ui->transmitters->setRowCount(transmitters.size());
+ QListIterator i(transmitters);
+ int row = 0;
+ for (int i = 0; i < transmitters.size(); i++)
+ {
+ ui->transmitters->setItem(row, TRANSMITTER_COL_CALLSIGN, new QTableWidgetItem(transmitters[i].m_callsign));
+ QTableWidgetItem *freq = new QTableWidgetItem();
+ freq->setText(QString("%1").arg(transmitters[i].m_frequency/1000.0));
+ freq->setData(Qt::UserRole, transmitters[i].m_frequency);
+ ui->transmitters->setItem(row, TRANSMITTER_COL_FREQUENCY, freq);
+ ui->transmitters->setItem(row, TRANSMITTER_COL_LOCATION, new QTableWidgetItem(QString("%1,%2").arg(transmitters[i].m_latitude).arg(transmitters[i].m_longitude)));
+ ui->transmitters->setItem(row, TRANSMITTER_COL_POWER, new QTableWidgetItem(QString("%1").arg(transmitters[i].m_power)));
+ azEl.setTarget(transmitters[i].m_latitude, transmitters[i].m_longitude, 1.0);
+ azEl.calculate();
+ ui->transmitters->setItem(row, TRANSMITTER_COL_AZIMUTH, new QTableWidgetItem(QString("%1").arg(round(azEl.getAzimuth()))));
+ ui->transmitters->setItem(row, TRANSMITTER_COL_ELEVATION, new QTableWidgetItem(QString("%1").arg(round(azEl.getElevation()))));
+ int km = round(azEl.getDistance()/1000);
+ QTableWidgetItem *dist = new QTableWidgetItem();
+ dist->setData(Qt::DisplayRole, km);
+ ui->transmitters->setItem(row, TRANSMITTER_COL_DISTANCE, dist);
+ row++;
+ }
+ ui->transmitters->setSortingEnabled(true);
+ ui->transmitters->resizeColumnsToContents();
+}
+
+void MapRadioTimeDialog::accept()
+{
+ QDialog::accept();
+}
+
+void MapRadioTimeDialog::on_transmitters_cellDoubleClicked(int row, int column)
+{
+ if ((column == TRANSMITTER_COL_CALLSIGN) || (column ==TRANSMITTER_COL_LOCATION))
+ {
+ // Find transmitter on map
+ QString location = ui->transmitters->item(row, column)->text();
+ m_gui->find(location);
+ }
+ else if (column == TRANSMITTER_COL_FREQUENCY)
+ {
+ // Tune to transmitter freq
+ ChannelWebAPIUtils::setCenterFrequency(0, ui->transmitters->item(row, column)->data(Qt::UserRole).toDouble());
+ }
+}
diff --git a/plugins/feature/map/mapradiotimedialog.h b/plugins/feature/map/mapradiotimedialog.h
new file mode 100644
index 000000000..b5f812814
--- /dev/null
+++ b/plugins/feature/map/mapradiotimedialog.h
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////////////
+// Copyright (C) 2021 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_FEATURE_MAPRADIOTIMEDIALOG_H
+#define INCLUDE_FEATURE_MAPRADIOTIMEDIALOG_H
+
+#include "ui_mapradiotimedialog.h"
+
+class MapGUI;
+
+class MapRadioTimeDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit MapRadioTimeDialog(MapGUI *gui, QWidget* parent = 0);
+ ~MapRadioTimeDialog();
+ void updateTable();
+
+private slots:
+ void accept();
+ void on_transmitters_cellDoubleClicked(int row, int column);
+
+private:
+ MapGUI *m_gui;
+ Ui::MapRadioTimeDialog* ui;
+
+ enum TransmitterCol {
+ TRANSMITTER_COL_CALLSIGN,
+ TRANSMITTER_COL_FREQUENCY,
+ TRANSMITTER_COL_LOCATION,
+ TRANSMITTER_COL_POWER,
+ TRANSMITTER_COL_AZIMUTH,
+ TRANSMITTER_COL_ELEVATION,
+ TRANSMITTER_COL_DISTANCE
+ };
+};
+
+#endif // INCLUDE_FEATURE_MAPRADIOTIMEDIALOG_H
diff --git a/plugins/feature/map/mapradiotimedialog.ui b/plugins/feature/map/mapradiotimedialog.ui
new file mode 100644
index 000000000..f85e52ac3
--- /dev/null
+++ b/plugins/feature/map/mapradiotimedialog.ui
@@ -0,0 +1,140 @@
+
+
+ MapRadioTimeDialog
+
+
+
+ 0
+ 0
+ 773
+ 279
+
+
+
+
+ Liberation Sans
+ 9
+
+
+
+ Radio Time Transmitters
+
+
+
-
+
+
+
+ 0
+
+
-
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ Callsign
+
+
+
+
+ Frequency (kHz)
+
+
+
+
+ Location (°)
+
+
+
+
+ Power (kW)
+
+
+
+
+ Azimuth (°)
+
+
+
+
+ Elevation (°)
+
+
+
+
+ Distance (km)
+
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QDialogButtonBox::Close
+
+
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ MapRadioTimeDialog
+ accept()
+
+
+ 248
+ 254
+
+
+ 157
+ 274
+
+
+
+
+ buttonBox
+ rejected()
+ MapRadioTimeDialog
+ reject()
+
+
+ 316
+ 260
+
+
+ 286
+ 274
+
+
+
+
+
diff --git a/plugins/feature/map/mapsettings.h b/plugins/feature/map/mapsettings.h
index fa512e551..04c0265aa 100644
--- a/plugins/feature/map/mapsettings.h
+++ b/plugins/feature/map/mapsettings.h
@@ -63,7 +63,8 @@ struct MapSettings
static const quint32 SOURCE_STAR_TRACKER = 0x8;
static const quint32 SOURCE_SATELLITE_TRACKER = 0x10;
static const quint32 SOURCE_BEACONS = 0x20;
- static const quint32 SOURCE_STATION = 0x40;
+ static const quint32 SOURCE_RADIO_TIME = 0x40;
+ static const quint32 SOURCE_STATION = 0x80;
};
#endif // INCLUDE_FEATURE_MAPSETTINGS_H_
diff --git a/plugins/feature/map/mapsettingsdialog.ui b/plugins/feature/map/mapsettingsdialog.ui
index 6308e36ce..d2de8745f 100644
--- a/plugins/feature/map/mapsettingsdialog.ui
+++ b/plugins/feature/map/mapsettingsdialog.ui
@@ -89,6 +89,14 @@
Checked
+ -
+
+ Radio Time Transmitters
+
+
+ Checked
+
+
-
diff --git a/plugins/feature/map/readme.md b/plugins/feature/map/readme.md
index c000a12aa..f9239f58e 100644
--- a/plugins/feature/map/readme.md
+++ b/plugins/feature/map/readme.md
@@ -11,6 +11,7 @@ On top of this, it can plot data from other plugins, such as:
* Satellites from the Satellite Tracker,
* The Sun, Moon and Stars from the Star Tracker,
* Beacons based on the IARU Region 1 beacon database.
+* Radio time transmitters.
It can also create tracks showing the path aircraft, ships and APRS objects have taken, as well as predicted paths for satellites.
@@ -48,23 +49,32 @@ The beacons will then be displayed in the table and on the map.
![Beacon dialog](../../../doc/img/Map_plugin_beacon_dialog.png)
-
5: Display Names
+5: Display Radio Time Transmitters dialog
+
+When clicked, opens the Radio Time Transmitters dialog.
+
+* Double clicking in a cell in the table in the Callsign or Location columns, will centre the map on that transmitter.
+* Double clicking on the Frequency column will set the Device center frequency.
+
+![Radio Time transmitters dialog](../../../doc/img/Map_plugin_radiotime_dialog.png)
+
+6: Display Names
When checked, names of objects are displayed in a bubble next to each object.
-6: Display tracks for selected object
+7: Display tracks for selected object
When checked, displays the track (taken or predicted) for the selected object.
-7: Display tracks for all objects
+8: Display tracks for all objects
When checked, displays the track (taken or predicted) for the all objects.
-8: Delete
+9: Delete
When clicked, all items will be deleted from the map.
-9: Display settings
+10: Display settings
When clicked, opens the Map Display Settings dialog, which allows setting:
@@ -93,6 +103,8 @@ IARU Region 1 beacon list used with permission from: https://iaru-r1-c5-beacons.
Mapping and geolocation services are by Open Street Map: https://www.openstreetmap.org/ esri: https://www.esri.com/ and Mapbox: https://www.mapbox.com/
+Icons made by Google from Flaticon https://www.flaticon.com
+
API
Full details of the API can be found in the Swagger documentation. Here is a quick example of how to centre the map on an object from the command line: