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
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)

Wyświetl plik

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/map/">
<file>icons/groundtracks.png</file>
<file>icons/clock.png</file>
</qresource>
</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_5_12.qml</file>
<file>map/antenna.png</file>
<file>map/antennatime.png</file>
</qresource>
</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_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<Beacon *> *beacons = Beacon::readIARUCSV(MapGUI::getBeaconFilename());
if (beacons != nullptr)
setBeacons(beacons);
addRadioTimeTransmitters();
}
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)
{
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++)

Wyświetl plik

@ -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<Beacon *> *getBeacons() { return m_beacons; }
void setBeacons(QList<Beacon *> *beacons);
QList<RadioTimeTransmitter> getRadioTimeTransmitters() { return m_radioTimeTransmitters; }
void addRadioTimeTransmitters();
void find(const QString& target);
private:
@ -487,6 +498,7 @@ private:
AzEl m_azEl; // Position of station
QList<Beacon *> *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<RadioTimeTransmitter> 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();
};

Wyświetl plik

@ -140,6 +140,20 @@
</property>
</widget>
</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>
<widget class="ButtonSwitch" name="displayNames">
<property name="toolTip">
@ -165,6 +179,7 @@
<property name="font">
<font>
<family>Adobe Devanagari</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="toolTip">
@ -190,6 +205,7 @@
<property name="font">
<font>
<family>Adobe Devanagari</family>
<pointsize>9</pointsize>
</font>
</property>
<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_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_

Wyświetl plik

@ -89,6 +89,14 @@
<enum>Checked</enum>
</property>
</item>
<item>
<property name="text">
<string>Radio Time Transmitters</string>
</property>
<property name="checkState">
<enum>Checked</enum>
</property>
</item>
</widget>
</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,
* 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)
<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.
<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.
<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.
<h3>8: Delete</h3>
<h3>9: Delete</h3>
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:
@ -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
<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: