Add radio time transmitters to map

pull/936/head
Jon Beniston 2021-06-23 15:15:50 +01:00
rodzic fd8577cc60
commit b7ef6fe421
15 zmienionych plików z 384 dodań i 7 usunięć

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 14 KiB

Wyświetl plik

@ -33,6 +33,8 @@ if(NOT SERVER_MODE)
mapsettingsdialog.ui mapsettingsdialog.ui
mapbeacondialog.cpp mapbeacondialog.cpp
mapbeacondialog.ui mapbeacondialog.ui
mapradiotimedialog.cpp
mapradiotimedialog.ui
map.qrc map.qrc
icons.qrc icons.qrc
) )
@ -43,6 +45,7 @@ if(NOT SERVER_MODE)
mapmaidenheaddialog.h mapmaidenheaddialog.h
mapsettingsdialog.h mapsettingsdialog.h
mapbeacondialog.h mapbeacondialog.h
mapradiotimedialog.h
) )
set(TARGET_NAME map) set(TARGET_NAME map)

Wyświetl plik

@ -1,5 +1,6 @@
<RCC> <RCC>
<qresource prefix="/map/"> <qresource prefix="/map/">
<file>icons/groundtracks.png</file> <file>icons/groundtracks.png</file>
<file>icons/clock.png</file>
</qresource> </qresource>
</RCC> </RCC>

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 440 B

Wyświetl plik

@ -3,5 +3,6 @@
<file>map/map.qml</file> <file>map/map.qml</file>
<file>map/map_5_12.qml</file> <file>map/map_5_12.qml</file>
<file>map/antenna.png</file> <file>map/antenna.png</file>
<file>map/antennatime.png</file>
</qresource> </qresource>
</RCC> </RCC>

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 6.0 KiB

Wyświetl plik

@ -679,7 +679,8 @@ MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
m_doApplySettings(true), m_doApplySettings(true),
m_mapModel(this), m_mapModel(this),
m_beacons(nullptr), m_beacons(nullptr),
m_beaconDialog(this) m_beaconDialog(this),
m_radioTimeDialog(this)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -738,6 +739,8 @@ MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *featur
QList<Beacon *> *beacons = Beacon::readIARUCSV(MapGUI::getBeaconFilename()); QList<Beacon *> *beacons = Beacon::readIARUCSV(MapGUI::getBeaconFilename());
if (beacons != nullptr) if (beacons != nullptr)
setBeacons(beacons); setBeacons(beacons);
addRadioTimeTransmitters();
} }
MapGUI::~MapGUI() MapGUI::~MapGUI()
@ -770,6 +773,37 @@ void MapGUI::setBeacons(QList<Beacon *> *beacons)
} }
} }
const QList<RadioTimeTransmitter> 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) void MapGUI::blockApplySettings(bool block)
{ {
m_doApplySettings = !block; m_doApplySettings = !block;
@ -1033,6 +1067,12 @@ void MapGUI::on_beacons_clicked()
m_beaconDialog.show(); m_beaconDialog.show();
} }
void MapGUI::on_radiotime_clicked()
{
m_radioTimeDialog.updateTable();
m_radioTimeDialog.show();
}
quint32 MapGUI::getSourceMask(const PipeEndPoint *sourcePipe) quint32 MapGUI::getSourceMask(const PipeEndPoint *sourcePipe)
{ {
for (int i = 0; i < m_availablePipes.size(); i++) for (int i = 0; i < m_availablePipes.size(); i++)

Wyświetl plik

@ -31,6 +31,7 @@
#include "mapsettings.h" #include "mapsettings.h"
#include "SWGMapItem.h" #include "SWGMapItem.h"
#include "mapbeacondialog.h" #include "mapbeacondialog.h"
#include "mapradiotimedialog.h"
class PluginAPI; class PluginAPI;
class FeatureUISet; class FeatureUISet;
@ -45,6 +46,14 @@ class MapModel;
class QQuickItem; class QQuickItem;
struct Beacon; 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 // Information required about each item displayed on the map
class MapItem { class MapItem {
@ -471,6 +480,8 @@ public:
static QString getBeaconFilename(); static QString getBeaconFilename();
QList<Beacon *> *getBeacons() { return m_beacons; } QList<Beacon *> *getBeacons() { return m_beacons; }
void setBeacons(QList<Beacon *> *beacons); void setBeacons(QList<Beacon *> *beacons);
QList<RadioTimeTransmitter> getRadioTimeTransmitters() { return m_radioTimeTransmitters; }
void addRadioTimeTransmitters();
void find(const QString& target); void find(const QString& target);
private: private:
@ -487,6 +498,7 @@ private:
AzEl m_azEl; // Position of station AzEl m_azEl; // Position of station
QList<Beacon *> *m_beacons; QList<Beacon *> *m_beacons;
MapBeaconDialog m_beaconDialog; MapBeaconDialog m_beaconDialog;
MapRadioTimeDialog m_radioTimeDialog;
explicit MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr); explicit MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent = nullptr);
virtual ~MapGUI(); virtual ~MapGUI();
@ -502,6 +514,7 @@ private:
void enterEvent(QEvent*); void enterEvent(QEvent*);
static QString getDataDir(); static QString getDataDir();
static const QList<RadioTimeTransmitter> m_radioTimeTransmitters;
private slots: private slots:
void onMenuDialogCalled(const QPoint &p); void onMenuDialogCalled(const QPoint &p);
@ -516,6 +529,7 @@ private slots:
void on_displaySettings_clicked(); void on_displaySettings_clicked();
void on_mapTypes_currentIndexChanged(int index); void on_mapTypes_currentIndexChanged(int index);
void on_beacons_clicked(); void on_beacons_clicked();
void on_radiotime_clicked();
}; };

Wyświetl plik

@ -140,6 +140,20 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QToolButton" name="radiotime">
<property name="toolTip">
<string>Display radio time transmitters dialog</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="icons.qrc">
<normaloff>:/map/icons/clock.png</normaloff>:/map/icons/clock.png</iconset>
</property>
</widget>
</item>
<item> <item>
<widget class="ButtonSwitch" name="displayNames"> <widget class="ButtonSwitch" name="displayNames">
<property name="toolTip"> <property name="toolTip">
@ -165,6 +179,7 @@
<property name="font"> <property name="font">
<font> <font>
<family>Adobe Devanagari</family> <family>Adobe Devanagari</family>
<pointsize>9</pointsize>
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">
@ -190,6 +205,7 @@
<property name="font"> <property name="font">
<font> <font>
<family>Adobe Devanagari</family> <family>Adobe Devanagari</family>
<pointsize>9</pointsize>
</font> </font>
</property> </property>
<property name="toolTip"> <property name="toolTip">

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#include "mapradiotimedialog.h"
#include <QDebug>
#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<RadioTimeTransmitter> transmitters = m_gui->getRadioTimeTransmitters();
ui->transmitters->setRowCount(0);
ui->transmitters->setRowCount(transmitters.size());
QListIterator<RadioTimeTransmitter> 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());
}
}

Wyświetl plik

@ -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 <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
#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

Wyświetl plik

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MapRadioTimeDialog</class>
<widget class="QDialog" name="MapRadioTimeDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>773</width>
<height>279</height>
</rect>
</property>
<property name="font">
<font>
<family>Liberation Sans</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="windowTitle">
<string>Radio Time Transmitters</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="topMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTableWidget" name="transmitters">
<property name="toolTip">
<string/>
</property>
<column>
<property name="text">
<string>Callsign</string>
</property>
</column>
<column>
<property name="text">
<string>Frequency (kHz)</string>
</property>
</column>
<column>
<property name="text">
<string>Location (°)</string>
</property>
</column>
<column>
<property name="text">
<string>Power (kW)</string>
</property>
</column>
<column>
<property name="text">
<string>Azimuth (°)</string>
</property>
</column>
<column>
<property name="text">
<string>Elevation (°)</string>
</property>
</column>
<column>
<property name="text">
<string>Distance (km)</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="../../../sdrgui/resources/res.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>MapRadioTimeDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>MapRadioTimeDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

Wyświetl plik

@ -63,7 +63,8 @@ struct MapSettings
static const quint32 SOURCE_STAR_TRACKER = 0x8; static const quint32 SOURCE_STAR_TRACKER = 0x8;
static const quint32 SOURCE_SATELLITE_TRACKER = 0x10; static const quint32 SOURCE_SATELLITE_TRACKER = 0x10;
static const quint32 SOURCE_BEACONS = 0x20; 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_ #endif // INCLUDE_FEATURE_MAPSETTINGS_H_

Wyświetl plik

@ -89,6 +89,14 @@
<enum>Checked</enum> <enum>Checked</enum>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>Radio Time Transmitters</string>
</property>
<property name="checkState">
<enum>Checked</enum>
</property>
</item>
</widget> </widget>
</item> </item>
<item> <item>

Wyświetl plik

@ -11,6 +11,7 @@ On top of this, it can plot data from other plugins, such as:
* Satellites from the Satellite Tracker, * Satellites from the Satellite Tracker,
* The Sun, Moon and Stars from the Star Tracker, * The Sun, Moon and Stars from the Star Tracker,
* Beacons based on the IARU Region 1 beacon database. * 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. 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) ![Beacon dialog](../../../doc/img/Map_plugin_beacon_dialog.png)
<h3>5: Display Names</h3> <h3>5: Display Radio Time Transmitters dialog</h3>
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)
<h3>6: Display Names</h3>
When checked, names of objects are displayed in a bubble next to each object. When checked, names of objects are displayed in a bubble next to each object.
<h3>6: Display tracks for selected object</h3> <h3>7: Display tracks for selected object</h3>
When checked, displays the track (taken or predicted) for the selected object. When checked, displays the track (taken or predicted) for the selected object.
<h3>7: Display tracks for all objects</h3> <h3>8: Display tracks for all objects</h3>
When checked, displays the track (taken or predicted) for the all objects. When checked, displays the track (taken or predicted) for the all objects.
<h3>8: Delete</h3> <h3>9: Delete</h3>
When clicked, all items will be deleted from the map. When clicked, all items will be deleted from the map.
<h3>9: Display settings</h3> <h3>10: Display settings</h3>
When clicked, opens the Map Display Settings dialog, which allows setting: 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/ 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
<h2>API</h2> <h2>API</h2>
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: 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: