| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | ///////////////////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Copyright (C) 2021 Jon Beniston, M7RCE                                        //
 | 
					
						
							|  |  |  | // Copyright (C) 2020 Edouard Griffiths, F4EXB                                   //
 | 
					
						
							|  |  |  | //                                                                               //
 | 
					
						
							|  |  |  | // 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 <cmath>
 | 
					
						
							|  |  |  | #include <QQmlContext>
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | #include <QQmlProperty>
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | #include <QGeoLocation>
 | 
					
						
							|  |  |  | #include <QGeoCoordinate>
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | #include <QGeoCodingManager>
 | 
					
						
							|  |  |  | #include <QGeoServiceProvider>
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #ifdef QT_WEBENGINE_FOUND
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | #include <QtWebEngineWidgets/QWebEngineView>
 | 
					
						
							|  |  |  | #include <QtWebEngineWidgets/QWebEngineSettings>
 | 
					
						
							|  |  |  | #include <QtWebEngineWidgets/QWebEngineProfile>
 | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "feature/featureuiset.h"
 | 
					
						
							|  |  |  | #include "gui/basicfeaturesettingsdialog.h"
 | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #include "gui/dialogpositioner.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | #include "mainwindow.h"
 | 
					
						
							|  |  |  | #include "device/deviceuiset.h"
 | 
					
						
							|  |  |  | #include "util/units.h"
 | 
					
						
							|  |  |  | #include "util/maidenhead.h"
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  | #include "util/morse.h"
 | 
					
						
							| 
									
										
										
										
											2023-03-03 17:14:56 +00:00
										 |  |  | #include "util/navtex.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | #include "maplocationdialog.h"
 | 
					
						
							|  |  |  | #include "mapmaidenheaddialog.h"
 | 
					
						
							|  |  |  | #include "mapsettingsdialog.h"
 | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  | #include "ibpbeacon.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "ui_mapgui.h"
 | 
					
						
							|  |  |  | #include "map.h"
 | 
					
						
							|  |  |  | #include "mapgui.h"
 | 
					
						
							|  |  |  | #include "SWGMapItem.h"
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | #include "SWGTargetAzimuthElevation.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | MapGUI* MapGUI::create(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MapGUI* gui = new MapGUI(pluginAPI, featureUISet, feature); | 
					
						
							|  |  |  |     return gui; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::destroy() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::resetToDefaults() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.resetToDefaults(); | 
					
						
							|  |  |  |     displaySettings(); | 
					
						
							|  |  |  |     applySettings(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QByteArray MapGUI::serialize() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_settings.serialize(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MapGUI::deserialize(const QByteArray& data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_settings.deserialize(data)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-05-13 22:24:48 +02:00
										 |  |  |         m_feature->setWorkspaceIndex(m_settings.m_workspaceIndex); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         displaySettings(); | 
					
						
							|  |  |  |         applySettings(true); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         resetToDefaults(); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool MapGUI::handleMessage(const Message& message) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (Map::MsgConfigureMap::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug("MapGUI::handleMessage: Map::MsgConfigureMap"); | 
					
						
							|  |  |  |         const Map::MsgConfigureMap& cfg = (Map::MsgConfigureMap&) message; | 
					
						
							| 
									
										
										
										
											2022-11-27 20:00:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (cfg.getForce()) { | 
					
						
							|  |  |  |             m_settings = cfg.getSettings(); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             m_settings.applySettings(cfg.getSettingsKeys(), cfg.getSettings()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         blockApplySettings(true); | 
					
						
							|  |  |  |         displaySettings(); | 
					
						
							|  |  |  |         blockApplySettings(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-29 20:12:15 +02:00
										 |  |  |     else if (Map::MsgReportAvailableChannelOrFeatures::match(message)) | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-03-29 20:12:15 +02:00
										 |  |  |         Map::MsgReportAvailableChannelOrFeatures& report = (Map::MsgReportAvailableChannelOrFeatures&) message; | 
					
						
							|  |  |  |         m_availableChannelOrFeatures = report.getItems(); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (Map::MsgFind::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Map::MsgFind& msgFind = (Map::MsgFind&) message; | 
					
						
							|  |  |  |         find(msgFind.getTarget()); | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     else if (Map::MsgSetDateTime::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Map::MsgSetDateTime& msgSetDateTime = (Map::MsgSetDateTime&) message; | 
					
						
							|  |  |  |         if (m_cesium) { | 
					
						
							|  |  |  |             m_cesium->setDateTime(msgSetDateTime.getDateTime()); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     else if (MainCore::MsgMapItem::match(message)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         MainCore::MsgMapItem& msgMapItem = (MainCore::MsgMapItem&) message; | 
					
						
							|  |  |  |         SWGSDRangel::SWGMapItem *swgMapItem = msgMapItem.getSWGMapItem(); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         // TODO: Could have this in SWGMapItem so plugins can create additional groups
 | 
					
						
							|  |  |  |         QString group; | 
					
						
							| 
									
										
										
										
											2022-03-29 20:12:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         for (int i = 0; i < m_availableChannelOrFeatures.size(); i++) | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-03-29 20:12:15 +02:00
										 |  |  |             if (m_availableChannelOrFeatures[i].m_source == msgMapItem.getPipeSource()) | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                  for (int j = 0; j < MapSettings::m_pipeTypes.size(); j++) | 
					
						
							|  |  |  |                  { | 
					
						
							| 
									
										
										
										
											2022-03-29 20:12:15 +02:00
										 |  |  |                      if (m_availableChannelOrFeatures[i].m_type == MapSettings::m_pipeTypes[j]) { | 
					
						
							|  |  |  |                          group = m_availableChannelOrFeatures[i].m_type; | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                      } | 
					
						
							|  |  |  |                  } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-03-29 20:12:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         update(msgMapItem.getPipeSource(), swgMapItem, group); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::handleInputMessages() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Message* message; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while ((message = getInputMessageQueue()->pop())) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (handleMessage(*message)) { | 
					
						
							|  |  |  |             delete message; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::onWidgetRolled(QWidget* widget, bool rollDown) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) widget; | 
					
						
							|  |  |  |     (void) rollDown; | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-11 12:35:19 +00:00
										 |  |  |     getRollupContents()->saveState(m_rollupState); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MapGUI::MapGUI(PluginAPI* pluginAPI, FeatureUISet *featureUISet, Feature *feature, QWidget* parent) : | 
					
						
							|  |  |  |     FeatureGUI(parent), | 
					
						
							|  |  |  |     ui(new Ui::MapGUI), | 
					
						
							|  |  |  |     m_pluginAPI(pluginAPI), | 
					
						
							|  |  |  |     m_featureUISet(featureUISet), | 
					
						
							|  |  |  |     m_doApplySettings(true), | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel(this), | 
					
						
							|  |  |  |     m_imageMapModel(this), | 
					
						
							|  |  |  |     m_polygonMapModel(this), | 
					
						
							|  |  |  |     m_polylineMapModel(this), | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     m_beacons(nullptr), | 
					
						
							| 
									
										
										
										
											2021-06-23 15:15:50 +01:00
										 |  |  |     m_beaconDialog(this), | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  |     m_ibpBeaconDialog(this), | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     m_radioTimeDialog(this), | 
					
						
							|  |  |  |     m_cesium(nullptr) | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-05-13 22:24:48 +02:00
										 |  |  |     m_feature = feature; | 
					
						
							| 
									
										
										
										
											2022-04-24 19:34:48 +02:00
										 |  |  |     setAttribute(Qt::WA_DeleteOnClose, true); | 
					
						
							| 
									
										
										
										
											2021-11-24 11:31:51 +00:00
										 |  |  |     m_helpURL = "plugins/feature/map/readme.md"; | 
					
						
							| 
									
										
										
										
											2022-04-24 19:34:48 +02:00
										 |  |  |     RollupContents *rollupContents = getRollupContents(); | 
					
						
							|  |  |  | 	ui->setupUi(rollupContents); | 
					
						
							|  |  |  |     setSizePolicy(rollupContents->sizePolicy()); | 
					
						
							|  |  |  |     rollupContents->arrangeRollups(); | 
					
						
							|  |  |  | 	connect(rollupContents, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-16 11:00:30 +00:00
										 |  |  |     // Enable MSAA antialiasing on 2D map
 | 
					
						
							|  |  |  |     // This can be much faster than using layer.smooth in the QML, when there are many items
 | 
					
						
							|  |  |  |     // However, only seems to work when set to 16, and doesn't seem to be supported on all graphics cards
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     int multisamples = MainCore::instance()->getSettings().getMapMultisampling(); | 
					
						
							|  |  |  |     if (multisamples > 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QSurfaceFormat format; | 
					
						
							|  |  |  |         format.setSamples(multisamples); | 
					
						
							|  |  |  |         ui->map->setFormat(format); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     m_osmPort = 0; | 
					
						
							|  |  |  |     m_templateServer = new OSMTemplateServer(thunderforestAPIKey(), maptilerAPIKey(), m_osmPort); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Web server to serve dynamic files from QResources
 | 
					
						
							|  |  |  |     m_webPort = 0; | 
					
						
							|  |  |  |     m_webServer = new WebServer(m_webPort); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |     ui->map->setAttribute(Qt::WA_AcceptTouchEvents, true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapFilter.setSourceModel(&m_objectMapModel); | 
					
						
							|  |  |  |     m_imageMapFilter.setSourceModel(&m_imageMapModel); | 
					
						
							|  |  |  |     m_polygonMapFilter.setSourceModel(&m_polygonMapModel); | 
					
						
							|  |  |  |     m_polylineMapFilter.setSourceModel(&m_polylineMapModel); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ui->map->rootContext()->setContextProperty("mapModelFiltered", &m_objectMapFilter); | 
					
						
							|  |  |  |     ui->map->rootContext()->setContextProperty("mapModel", &m_objectMapModel); | 
					
						
							|  |  |  |     ui->map->rootContext()->setContextProperty("imageModelFiltered", &m_imageMapFilter); | 
					
						
							|  |  |  |     ui->map->rootContext()->setContextProperty("polygonModelFiltered", &m_polygonMapFilter); | 
					
						
							|  |  |  |     ui->map->rootContext()->setContextProperty("polylineModelFiltered", &m_polylineMapFilter); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     ui->map->setSource(QUrl(QStringLiteral("qrc:/map/map/map.qml"))); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     m_settings.m_modelURL = QString("http://127.0.0.1:%1/3d/").arg(m_webPort); | 
					
						
							|  |  |  |     m_webServer->addPathSubstitution("3d", m_settings.m_modelDir); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     m_map = reinterpret_cast<Map*>(feature); | 
					
						
							|  |  |  |     m_map->setMessageQueueToGUI(&m_inputMessageQueue); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-09 05:27:12 +01:00
										 |  |  |     m_settings.setRollupState(&m_rollupState); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(onMenuDialogCalled(const QPoint &))); | 
					
						
							|  |  |  |     connect(getInputMessageQueue(), SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #ifdef QT_WEBENGINE_FOUND
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     QWebEngineSettings *settings = ui->web->settings(); | 
					
						
							|  |  |  |     settings->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); | 
					
						
							|  |  |  |     connect(ui->web->page(), &QWebEnginePage::fullScreenRequested, this, &MapGUI::fullScreenRequested); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     // Get station position
 | 
					
						
							|  |  |  |     float stationLatitude = MainCore::instance()->getSettings().getLatitude(); | 
					
						
							|  |  |  |     float stationLongitude = MainCore::instance()->getSettings().getLongitude(); | 
					
						
							|  |  |  |     float stationAltitude = MainCore::instance()->getSettings().getAltitude(); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     m_azEl.setLocation(stationLatitude, stationLongitude, stationAltitude); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     QGeoCoordinate stationPosition(stationLatitude, stationLongitude, stationAltitude); | 
					
						
							|  |  |  |     m_objectMapFilter.setPosition(stationPosition); | 
					
						
							|  |  |  |     m_imageMapFilter.setPosition(stationPosition); | 
					
						
							|  |  |  |     m_polygonMapFilter.setPosition(stationPosition); | 
					
						
							|  |  |  |     m_polylineMapFilter.setPosition(stationPosition); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Centre map at My Position
 | 
					
						
							|  |  |  |     QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |     QObject *object = item->findChild<QObject*>("map"); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     if (object != nullptr) | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         QGeoCoordinate coords = object->property("center").value<QGeoCoordinate>(); | 
					
						
							|  |  |  |         coords.setLatitude(stationLatitude); | 
					
						
							|  |  |  |         coords.setLongitude(stationLongitude); | 
					
						
							|  |  |  |         object->setProperty("center", QVariant::fromValue(coords)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     // Create antenna at My Position
 | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  |     m_antennaMapItem.setName(new QString("Station")); | 
					
						
							|  |  |  |     m_antennaMapItem.setLatitude(stationLatitude); | 
					
						
							|  |  |  |     m_antennaMapItem.setLongitude(stationLongitude); | 
					
						
							|  |  |  |     m_antennaMapItem.setAltitude(stationAltitude); | 
					
						
							|  |  |  |     m_antennaMapItem.setImage(new QString("antenna.png")); | 
					
						
							|  |  |  |     m_antennaMapItem.setImageRotation(0); | 
					
						
							|  |  |  |     m_antennaMapItem.setText(new QString(MainCore::instance()->getSettings().getStationName())); | 
					
						
							|  |  |  |     m_antennaMapItem.setModel(new QString("antenna.glb")); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_antennaMapItem.setFixedPosition(false); | 
					
						
							|  |  |  |     m_antennaMapItem.setPositionDateTime(new QString(QDateTime::currentDateTime().toString(Qt::ISODateWithMs))); | 
					
						
							|  |  |  |     m_antennaMapItem.setAvailableUntil(new QString(QDateTime::currentDateTime().addDays(365).toString(Qt::ISODateWithMs))); | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  |     m_antennaMapItem.setOrientation(0); | 
					
						
							|  |  |  |     m_antennaMapItem.setLabel(new QString(MainCore::instance()->getSettings().getStationName())); | 
					
						
							|  |  |  |     m_antennaMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |     m_antennaMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |     update(m_map, &m_antennaMapItem, "Station"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Get updated when position changes
 | 
					
						
							|  |  |  |     connect(&MainCore::instance()->getSettings(), &MainSettings::preferenceChanged, this, &MapGUI::preferenceChanged); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Read beacons, if they exist
 | 
					
						
							|  |  |  |     QList<Beacon *> *beacons = Beacon::readIARUCSV(MapGUI::getBeaconFilename()); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     if (beacons != nullptr) { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         setBeacons(beacons); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  |     addIBPBeacons(); | 
					
						
							| 
									
										
										
										
											2021-06-23 15:15:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     addRadioTimeTransmitters(); | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  |     addRadar(); | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  |     addIonosonde(); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     addBroadcast(); | 
					
						
							|  |  |  |     addNavAids(); | 
					
						
							|  |  |  |     addAirspace(); | 
					
						
							|  |  |  |     addAirports(); | 
					
						
							| 
									
										
										
										
											2023-03-03 17:14:56 +00:00
										 |  |  |     addNavtex(); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     displaySettings(); | 
					
						
							|  |  |  |     applySettings(true); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 09:04:04 +00:00
										 |  |  |     connect(&m_redrawMapTimer, &QTimer::timeout, this, &MapGUI::redrawMap); | 
					
						
							|  |  |  |     m_redrawMapTimer.setSingleShot(true); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     ui->map->installEventFilter(this); | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     makeUIConnections(); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |     new DialogPositioner(&m_beaconDialog, true); | 
					
						
							|  |  |  |     new DialogPositioner(&m_ibpBeaconDialog, true); | 
					
						
							|  |  |  |     new DialogPositioner(&m_radioTimeDialog, true); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MapGUI::~MapGUI() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-03-23 09:04:04 +00:00
										 |  |  |     disconnect(&m_redrawMapTimer, &QTimer::timeout, this, &MapGUI::redrawMap); | 
					
						
							|  |  |  |     m_redrawMapTimer.stop(); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     //m_cesium->deleteLater();
 | 
					
						
							|  |  |  |     delete m_cesium; | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |     if (m_templateServer) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_templateServer->close(); | 
					
						
							|  |  |  |         delete m_templateServer; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     if (m_webServer) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_webServer->close(); | 
					
						
							|  |  |  |         delete m_webServer; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  |     delete m_giro; | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     delete ui; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 22:24:48 +02:00
										 |  |  | void MapGUI::setWorkspaceIndex(int index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_workspaceIndex = index; | 
					
						
							|  |  |  |     m_feature->setWorkspaceIndex(index); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  | // Update a map item
 | 
					
						
							| 
									
										
										
										
											2022-03-29 20:12:15 +02:00
										 |  |  | void MapGUI::update(const QObject *source, SWGSDRangel::SWGMapItem *swgMapItem, const QString &group) | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     int type = swgMapItem->getType(); | 
					
						
							|  |  |  |     if (type == 0) { | 
					
						
							|  |  |  |         m_objectMapModel.update(source, swgMapItem, group); | 
					
						
							|  |  |  |     } else if (type == 1) { | 
					
						
							|  |  |  |         m_imageMapModel.update(source, swgMapItem, group); | 
					
						
							|  |  |  |     } else if (type == 2) { | 
					
						
							|  |  |  |         m_polygonMapModel.update(source, swgMapItem, group); | 
					
						
							|  |  |  |     } else if (type == 3) { | 
					
						
							|  |  |  |         m_polylineMapModel.update(source, swgMapItem, group); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | void MapGUI::setBeacons(QList<Beacon *> *beacons) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     delete m_beacons; | 
					
						
							|  |  |  |     m_beacons = beacons; | 
					
						
							|  |  |  |     m_beaconDialog.updateTable(); | 
					
						
							|  |  |  |     // Add to Map
 | 
					
						
							|  |  |  |     QListIterator<Beacon *> i(*m_beacons); | 
					
						
							|  |  |  |     while (i.hasNext()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Beacon *beacon = i.next(); | 
					
						
							|  |  |  |         SWGSDRangel::SWGMapItem beaconMapItem; | 
					
						
							| 
									
										
										
										
											2021-02-26 20:30:59 +00:00
										 |  |  |         // Need to suffix frequency, as there are multiple becaons with same callsign at different locations
 | 
					
						
							|  |  |  |         QString name = QString("%1-%2").arg(beacon->m_callsign).arg(beacon->getFrequencyShortText()); | 
					
						
							|  |  |  |         beaconMapItem.setName(new QString(name)); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         beaconMapItem.setLatitude(beacon->m_latitude); | 
					
						
							|  |  |  |         beaconMapItem.setLongitude(beacon->m_longitude); | 
					
						
							|  |  |  |         beaconMapItem.setAltitude(beacon->m_altitude); | 
					
						
							|  |  |  |         beaconMapItem.setImage(new QString("antenna.png")); | 
					
						
							|  |  |  |         beaconMapItem.setImageRotation(0); | 
					
						
							|  |  |  |         beaconMapItem.setText(new QString(beacon->getText())); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         beaconMapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |         beaconMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |         beaconMapItem.setOrientation(0); | 
					
						
							|  |  |  |         // Just use callsign for label, so we don't have multiple labels on top of each other on 3D map
 | 
					
						
							|  |  |  |         // as it makes them unreadable
 | 
					
						
							|  |  |  |         beaconMapItem.setLabel(new QString(beacon->m_callsign)); | 
					
						
							|  |  |  |         beaconMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |         beaconMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |         update(m_map, &beaconMapItem, "Beacons"); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  | void MapGUI::addIBPBeacons() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Add to Map
 | 
					
						
							| 
									
										
										
										
											2021-12-27 19:04:23 +01:00
										 |  |  |     for (const auto& beacon : IBPBeacon::m_beacons) | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         SWGSDRangel::SWGMapItem beaconMapItem; | 
					
						
							|  |  |  |         beaconMapItem.setName(new QString(beacon.m_callsign)); | 
					
						
							|  |  |  |         beaconMapItem.setLatitude(beacon.m_latitude); | 
					
						
							|  |  |  |         beaconMapItem.setLongitude(beacon.m_longitude); | 
					
						
							|  |  |  |         beaconMapItem.setAltitude(0); | 
					
						
							|  |  |  |         beaconMapItem.setImage(new QString("antenna.png")); | 
					
						
							|  |  |  |         beaconMapItem.setImageRotation(0); | 
					
						
							|  |  |  |         beaconMapItem.setText(new QString(beacon.getText())); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         beaconMapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |         beaconMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |         beaconMapItem.setOrientation(0); | 
					
						
							|  |  |  |         beaconMapItem.setLabel(new QString(beacon.m_callsign)); | 
					
						
							|  |  |  |         beaconMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |         beaconMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |         update(m_map, &beaconMapItem, "Beacons"); | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-23 15:15:50 +01:00
										 |  |  | const QList<RadioTimeTransmitter> MapGUI::m_radioTimeTransmitters = { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     {"MSF", 60000, 54.9075f, -3.27333f, 17},            // UK
 | 
					
						
							|  |  |  |     {"DCF77", 77500, 50.01611111f, 9.00805556f, 50},    // Germany
 | 
					
						
							|  |  |  |     {"TDF", 162000, 47.1694f, 2.2044f, 800},            // France
 | 
					
						
							|  |  |  |     {"WWVB", 60000, 40.67805556f, -105.04666667f, 70},  // USA
 | 
					
						
							|  |  |  |     {"JJY-40", 40000, 37.3725f, 140.848889f, 50},       // Japan
 | 
					
						
							|  |  |  |     {"JJY-60", 60000, 33.465556f, 130.175556f, 50},     // Japan
 | 
					
						
							|  |  |  |     {"RTZ", 50000, 52.436111f, 103.685833f, 10},        // Russia - On 22:00 to 21:00 UTC
 | 
					
						
							|  |  |  |     {"RBU", 66666, 56.733333f, 37.663333f, 10},         // Russia
 | 
					
						
							|  |  |  |     {"BPC", 68500, 34.457f, 115.837f, 90},              // China - On 1:00 to 21:00 UTC
 | 
					
						
							| 
									
										
										
										
											2021-06-23 15:15:50 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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); | 
					
						
							|  |  |  |         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)); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         timeMapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |         timeMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |         timeMapItem.setOrientation(0); | 
					
						
							|  |  |  |         timeMapItem.setLabel(new QString(name)); | 
					
						
							|  |  |  |         timeMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |         timeMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |         update(m_map, &timeMapItem, "Radio Time Transmitters"); | 
					
						
							| 
									
										
										
										
											2021-06-23 15:15:50 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  | void MapGUI::addRadar() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     SWGSDRangel::SWGMapItem radarMapItem; | 
					
						
							|  |  |  |     radarMapItem.setName(new QString("GRAVES")); | 
					
						
							|  |  |  |     radarMapItem.setLatitude(47.3480); | 
					
						
							|  |  |  |     radarMapItem.setLongitude(5.5151); | 
					
						
							|  |  |  |     radarMapItem.setAltitude(0.0); | 
					
						
							|  |  |  |     radarMapItem.setImage(new QString("antenna.png")); | 
					
						
							|  |  |  |     radarMapItem.setImageRotation(0); | 
					
						
							|  |  |  |     QString text = QString("Radar\nCallsign: %1\nFrequency: %2 MHz") | 
					
						
							|  |  |  |                             .arg("GRAVES") | 
					
						
							|  |  |  |                             .arg("143.050"); | 
					
						
							|  |  |  |     radarMapItem.setText(new QString(text)); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     radarMapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |     radarMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |     radarMapItem.setOrientation(0); | 
					
						
							|  |  |  |     radarMapItem.setLabel(new QString("GRAVES")); | 
					
						
							|  |  |  |     radarMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |     radarMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |     update(m_map, &radarMapItem, "Radar"); | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  | // Ionosonde stations
 | 
					
						
							|  |  |  | void MapGUI::addIonosonde() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_giro = GIRO::create(); | 
					
						
							|  |  |  |     if (m_giro) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         connect(m_giro, &GIRO::dataUpdated, this, &MapGUI::giroDataUpdated); | 
					
						
							|  |  |  |         connect(m_giro, &GIRO::mufUpdated, this, &MapGUI::mufUpdated); | 
					
						
							|  |  |  |         connect(m_giro, &GIRO::foF2Updated, this, &MapGUI::foF2Updated); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::giroDataUpdated(const GIRO::GIROStationData& data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!data.m_station.isEmpty()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         IonosondeStation *station = nullptr; | 
					
						
							|  |  |  |         // See if we already have the station in our hash
 | 
					
						
							|  |  |  |         if (!m_ionosondeStations.contains(data.m_station)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Create new station
 | 
					
						
							|  |  |  |             station = new IonosondeStation(data); | 
					
						
							|  |  |  |             m_ionosondeStations.insert(data.m_station, station); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             station = m_ionosondeStations.value(data.m_station); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         station->update(data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Add/update map
 | 
					
						
							|  |  |  |         SWGSDRangel::SWGMapItem ionosondeStationMapItem; | 
					
						
							|  |  |  |         ionosondeStationMapItem.setName(new QString(station->m_name)); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setLatitude(station->m_latitude); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setLongitude(station->m_longitude); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setAltitude(0.0); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setImage(new QString("ionosonde.png")); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setImageRotation(0); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setText(new QString(station->m_text)); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setOrientation(0); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setLabel(new QString(station->m_label)); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |         ionosondeStationMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |         update(m_map, &ionosondeStationMapItem, "Ionosonde Stations"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::mufUpdated(const QJsonDocument& document) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Could possibly try render on 2D map, but contours
 | 
					
						
							|  |  |  |     // that cross anti-meridian are not drawn properly
 | 
					
						
							|  |  |  |     //${Qt5Location_PRIVATE_INCLUDE_DIRS}
 | 
					
						
							|  |  |  |     //#include <QtLocation/private/qgeojson_p.h>
 | 
					
						
							|  |  |  |     //QVariantList list = QGeoJson::importGeoJson(document);
 | 
					
						
							|  |  |  |     m_webServer->addFile("/map/map/muf.geojson", document.toJson()); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |     if (m_cesium) { | 
					
						
							|  |  |  |         m_cesium->showMUF(m_settings.m_displayMUF); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::foF2Updated(const QJsonDocument& document) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_webServer->addFile("/map/map/fof2.geojson", document.toJson()); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |     if (m_cesium) { | 
					
						
							|  |  |  |         m_cesium->showfoF2(m_settings.m_displayfoF2); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  | void MapGUI::addBroadcast() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QFile file(":/map/data/transmitters.csv"); | 
					
						
							|  |  |  |     if (file.open(QIODevice::ReadOnly | QIODevice::Text)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QTextStream in(&file); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QString error; | 
					
						
							|  |  |  |         QHash<QString, int> colIndexes = CSV::readHeader(in, {"Type", "Id", "Name", "Frequency (Hz)", "Latitude", "Longitude", "Altitude (m)", "Power", "TII Main", "TII Sub"}, error); | 
					
						
							|  |  |  |         if (error.isEmpty()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             int typeCol = colIndexes.value("Type"); | 
					
						
							|  |  |  |             int idCol = colIndexes.value("Id"); | 
					
						
							|  |  |  |             int nameCol = colIndexes.value("Name"); | 
					
						
							|  |  |  |             int frequencyCol = colIndexes.value("Frequency (Hz)"); | 
					
						
							|  |  |  |             int latCol = colIndexes.value("Latitude"); | 
					
						
							|  |  |  |             int longCol = colIndexes.value("Longitude"); | 
					
						
							|  |  |  |             int altCol = colIndexes.value("Altitude (m)"); | 
					
						
							|  |  |  |             int powerCol = colIndexes.value("Power"); | 
					
						
							|  |  |  |             int tiiMainCol = colIndexes.value("TII Main"); | 
					
						
							|  |  |  |             int tiiSubCol = colIndexes.value("TII Sub"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QStringList cols; | 
					
						
							|  |  |  |             while (CSV::readRow(in, &cols)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QString type = cols[typeCol]; | 
					
						
							|  |  |  |                 QString id = cols[idCol]; | 
					
						
							|  |  |  |                 QString name = cols[nameCol]; | 
					
						
							|  |  |  |                 QString frequency = cols[frequencyCol]; | 
					
						
							|  |  |  |                 double latitude = cols[latCol].toDouble(); | 
					
						
							|  |  |  |                 double longitude = cols[longCol].toDouble(); | 
					
						
							|  |  |  |                 double altitude = cols[altCol].toDouble(); | 
					
						
							|  |  |  |                 QString power = cols[powerCol]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 SWGSDRangel::SWGMapItem mapItem; | 
					
						
							|  |  |  |                 mapItem.setLatitude(latitude); | 
					
						
							|  |  |  |                 mapItem.setLongitude(longitude); | 
					
						
							|  |  |  |                 mapItem.setAltitude(altitude); | 
					
						
							|  |  |  |                 mapItem.setImageRotation(0); | 
					
						
							|  |  |  |                 mapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |                 mapItem.setFixedPosition(true); | 
					
						
							|  |  |  |                 mapItem.setOrientation(0); | 
					
						
							|  |  |  |                 mapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |                 mapItem.setAltitudeReference(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (type == "AM") | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // Name should be unique
 | 
					
						
							|  |  |  |                     mapItem.setName(new QString(id)); | 
					
						
							|  |  |  |                     mapItem.setImage(new QString("antennaam.png")); | 
					
						
							|  |  |  |                     mapItem.setLabel(new QString(name)); | 
					
						
							|  |  |  |                     QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 kHz\nPower (ERMP): %4 kW") | 
					
						
							|  |  |  |                                             .arg(type) | 
					
						
							|  |  |  |                                             .arg(name) | 
					
						
							|  |  |  |                                             .arg(frequency.toDouble() / 1e3) | 
					
						
							|  |  |  |                                             .arg(power) | 
					
						
							|  |  |  |                                             ; | 
					
						
							|  |  |  |                     mapItem.setText(new QString(text)); | 
					
						
							|  |  |  |                     update(m_map, &mapItem, "AM"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else if (type == "FM") | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     mapItem.setName(new QString(id)); | 
					
						
							|  |  |  |                     mapItem.setImage(new QString("antennafm.png")); | 
					
						
							|  |  |  |                     mapItem.setLabel(new QString(name)); | 
					
						
							|  |  |  |                     QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 MHz\nPower (ERP): %4 kW") | 
					
						
							|  |  |  |                                             .arg(type) | 
					
						
							|  |  |  |                                             .arg(name) | 
					
						
							|  |  |  |                                             .arg(frequency.toDouble() / 1e6) | 
					
						
							|  |  |  |                                             .arg(power) | 
					
						
							|  |  |  |                                             ; | 
					
						
							|  |  |  |                     mapItem.setText(new QString(text)); | 
					
						
							|  |  |  |                     update(m_map, &mapItem, "FM"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else if (type == "DAB") | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     mapItem.setName(new QString(id)); | 
					
						
							|  |  |  |                     mapItem.setImage(new QString("antennadab.png")); | 
					
						
							|  |  |  |                     mapItem.setLabel(new QString(name)); | 
					
						
							|  |  |  |                     QString text = QString("%1 Transmitter\nEnsemble: %2\nFrequency: %3 MHz\nPower (ERP): %4 kW\nTII: %5 %6") | 
					
						
							|  |  |  |                                             .arg(type) | 
					
						
							|  |  |  |                                             .arg(name) | 
					
						
							|  |  |  |                                             .arg(frequency.toDouble() / 1e6) | 
					
						
							|  |  |  |                                             .arg(power) | 
					
						
							|  |  |  |                                             .arg(cols[tiiMainCol]) | 
					
						
							|  |  |  |                                             .arg(cols[tiiSubCol]) | 
					
						
							|  |  |  |                                             ; | 
					
						
							|  |  |  |                     mapItem.setText(new QString(text)); | 
					
						
							|  |  |  |                     update(m_map, &mapItem, "DAB"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |            } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |         qCritical() << "MapGUI::addBroadcast: Failed reading transmitters.csv - " << error; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qCritical() << "MapGUI::addBroadcast: Failed to open transmitters.csv"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-16 12:18:58 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static QString arrayToString(QJsonArray array) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QString s; | 
					
						
							|  |  |  |     for (int i = 0; i < array.size(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         s = s.append(array[i].toString()); | 
					
						
							|  |  |  |         s = s.append(" "); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Code for FM list / DAB list, should they allow access
 | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | void MapGUI::addDAB() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QFile file("stationlist_SI.json"); | 
					
						
							|  |  |  |     if (file.open(QIODevice::ReadOnly)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QByteArray bytes = file.readAll(); | 
					
						
							|  |  |  |         QJsonParseError error; | 
					
						
							|  |  |  |         QJsonDocument json = QJsonDocument::fromJson(bytes, &error); | 
					
						
							|  |  |  |         if (!json.isNull()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (json.isObject()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QJsonObject obj = json.object(); | 
					
						
							|  |  |  |                 QJsonValue stations = obj.value("stations"); | 
					
						
							|  |  |  |                 QJsonArray stationsArray = stations.toArray(); | 
					
						
							|  |  |  |                 for (int i = 0; i < stationsArray.size(); i++) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     QJsonObject station = stationsArray[i].toObject(); | 
					
						
							|  |  |  |                     // "txs" contains array of transmitters
 | 
					
						
							|  |  |  |                     QString stationName = station.value("stationName").toString(); | 
					
						
							|  |  |  |                     QJsonArray txs = station.value("txs").toArray(); | 
					
						
							|  |  |  |                     QString languages = arrayToString(station.value("language").toArray()); | 
					
						
							|  |  |  |                     QString format = arrayToString(station.value("format").toArray()); | 
					
						
							|  |  |  |                     for (int j = 0; j < txs.size(); j++) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         QJsonObject tx = txs[j].toObject(); | 
					
						
							|  |  |  |                         QString band = tx.value("band").toString(); | 
					
						
							|  |  |  |                         double lat = tx.value("latitude").toString().toDouble(); | 
					
						
							|  |  |  |                         double lon = tx.value("longitude").toString().toDouble(); | 
					
						
							|  |  |  |                         double alt = tx.value("haat").toString().toDouble(); // This is height above terrain - not actual height - Check "haatUnits" is m
 | 
					
						
							|  |  |  |                         double frequency = tx.value("frequency").toString().toDouble();  // Can be MHz or kHz for AM
 | 
					
						
							|  |  |  |                         double erp = tx.value("erp").toString().toDouble(); | 
					
						
							|  |  |  |                         SWGSDRangel::SWGMapItem mapItem; | 
					
						
							|  |  |  |                         mapItem.setLatitude(lat); | 
					
						
							|  |  |  |                         mapItem.setLongitude(lon); | 
					
						
							|  |  |  |                         mapItem.setAltitude(alt); | 
					
						
							|  |  |  |                         mapItem.setImageRotation(0); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                         mapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |                         mapItem.setFixedPosition(true); | 
					
						
							|  |  |  |                         mapItem.setOrientation(0); | 
					
						
							|  |  |  |                         mapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |                         mapItem.setAltitudeReference(1); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |                         if (band == "DAB") | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             // Name should be unique - can we use TII code for this? can it repeat across countries?
 | 
					
						
							|  |  |  |                             QString name = QString("%1").arg(tx.value("tsId").toString()); | 
					
						
							|  |  |  |                             mapItem.setName(new QString(name)); | 
					
						
							|  |  |  |                             mapItem.setImage(new QString("antennadab.png")); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                             mapItem.setLabel(new QString(name)); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |                             // Need tiicode?
 | 
					
						
							|  |  |  |                             QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 %4\nPower: %5 %6\nLanguage(s): %7\nType: %8\nService: %9\nEnsemble: %10") | 
					
						
							|  |  |  |                                                     .arg(band) | 
					
						
							|  |  |  |                                                     .arg(stationName) | 
					
						
							|  |  |  |                                                     .arg(frequency) | 
					
						
							|  |  |  |                                                     .arg(tx.value("frequencyUnits").toString()) | 
					
						
							|  |  |  |                                                     .arg(erp) | 
					
						
							|  |  |  |                                                     .arg(tx.value("erpUnits").toString()) | 
					
						
							|  |  |  |                                                     .arg(languages) | 
					
						
							|  |  |  |                                                     .arg(format) | 
					
						
							|  |  |  |                                                     .arg(tx.value("serviceLabel").toString()) | 
					
						
							|  |  |  |                                                     .arg(tx.value("ensembleLabel").toString()) | 
					
						
							|  |  |  |                                                     ; | 
					
						
							|  |  |  |                             mapItem.setText(new QString(text)); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                             update(m_map, &mapItem, "DAB"); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |                         } | 
					
						
							|  |  |  |                         else if (band == "FM") | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             // Name should be unique
 | 
					
						
							|  |  |  |                             QString name = QString("%1").arg(tx.value("tsId").toString()); | 
					
						
							|  |  |  |                             mapItem.setName(new QString(name)); | 
					
						
							|  |  |  |                             mapItem.setImage(new QString("antennafm.png")); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                             mapItem.setLabel(new QString(name)); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |                             QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 %4\nPower: %5 %6\nLanguage(s): %7\nType: %8") | 
					
						
							|  |  |  |                                                     .arg(band) | 
					
						
							|  |  |  |                                                     .arg(stationName) | 
					
						
							|  |  |  |                                                     .arg(frequency) | 
					
						
							|  |  |  |                                                     .arg(tx.value("frequencyUnits").toString()) | 
					
						
							|  |  |  |                                                     .arg(erp) | 
					
						
							|  |  |  |                                                     .arg(tx.value("erpUnits").toString()) | 
					
						
							|  |  |  |                                                     .arg(languages) | 
					
						
							|  |  |  |                                                     .arg(format) | 
					
						
							|  |  |  |                                                     ; | 
					
						
							|  |  |  |                             mapItem.setText(new QString(text)); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                             update(m_map, &mapItem, "FM"); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |                         } | 
					
						
							|  |  |  |                         else if (band == "AM") | 
					
						
							|  |  |  |                         { | 
					
						
							|  |  |  |                             // Name should be unique
 | 
					
						
							|  |  |  |                             QString name = QString("%1").arg(tx.value("tsId").toString()); | 
					
						
							|  |  |  |                             mapItem.setName(new QString(name)); | 
					
						
							|  |  |  |                             mapItem.setImage(new QString("antennaam.png")); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                             mapItem.setLabel(new QString(name)); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |                             QString text = QString("%1 Transmitter\nStation: %2\nFrequency: %3 %4\nPower: %5 %6\nLanguage(s): %7\nType: %8") | 
					
						
							|  |  |  |                                                     .arg(band) | 
					
						
							|  |  |  |                                                     .arg(stationName) | 
					
						
							|  |  |  |                                                     .arg(frequency) | 
					
						
							|  |  |  |                                                     .arg(tx.value("frequencyUnits").toString()) | 
					
						
							|  |  |  |                                                     .arg(erp) | 
					
						
							|  |  |  |                                                     .arg(tx.value("erpUnits").toString()) | 
					
						
							|  |  |  |                                                     .arg(languages) | 
					
						
							|  |  |  |                                                     .arg(format) | 
					
						
							|  |  |  |                                                     ; | 
					
						
							|  |  |  |                             mapItem.setText(new QString(text)); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                             update(m_map, &mapItem, "AM"); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |                         } | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 qDebug() << "MapGUI::addDAB: Expecting an object in DAB json:"; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug() << "MapGUI::addDAB: Failed to parse DAB json: " << error.errorString(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "MapGUI::addDAB: Failed to open DAB json"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::addNavAids() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_navAids = OpenAIP::getNavAids(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (const auto navAid : *m_navAids) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         SWGSDRangel::SWGMapItem navAidMapItem; | 
					
						
							|  |  |  |         navAidMapItem.setName(new QString(navAid->m_name + " " + navAid->m_ident)); // Neither name or ident are unique...
 | 
					
						
							|  |  |  |         navAidMapItem.setLatitude(navAid->m_latitude); | 
					
						
							|  |  |  |         navAidMapItem.setLongitude(navAid->m_longitude); | 
					
						
							|  |  |  |         navAidMapItem.setAltitude(Units::feetToMetres(navAid->m_elevation)); | 
					
						
							|  |  |  |         QString image = QString("%1.png").arg(navAid->m_type); | 
					
						
							|  |  |  |         navAidMapItem.setImage(new QString(image)); | 
					
						
							|  |  |  |         navAidMapItem.setImageRotation(0); | 
					
						
							|  |  |  |         QString text = QString("NAVAID\nName: %1").arg(navAid->m_name); | 
					
						
							|  |  |  |         if (navAid->m_type == "NDB") { | 
					
						
							|  |  |  |             text.append(QString("\nFrequency: %1 kHz").arg(navAid->m_frequencykHz, 0, 'f', 1)); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             text.append(QString("\nFrequency: %1 MHz").arg(navAid->m_frequencykHz / 1000.0f, 0, 'f', 2)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (navAid->m_channel != "") { | 
					
						
							|  |  |  |             text.append(QString("\nChannel: %1").arg(navAid->m_channel)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         text.append(QString("\nIdent: %1 %2").arg(navAid->m_ident).arg(Morse::toSpacedUnicodeMorse(navAid->m_ident))); | 
					
						
							|  |  |  |         text.append(QString("\nRange: %1 nm").arg(navAid->m_range)); | 
					
						
							|  |  |  |         if (navAid->m_alignedTrueNorth) { | 
					
						
							|  |  |  |             text.append(QString("\nMagnetic declination: Aligned to true North")); | 
					
						
							|  |  |  |         } else if (navAid->m_magneticDeclination != 0.0f) { | 
					
						
							|  |  |  |             text.append(QString("\nMagnetic declination: %1%2").arg(std::round(navAid->m_magneticDeclination)).arg(QChar(0x00b0))); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         navAidMapItem.setText(new QString(text)); | 
					
						
							|  |  |  |         navAidMapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |         navAidMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |         navAidMapItem.setOrientation(0); | 
					
						
							|  |  |  |         navAidMapItem.setLabel(new QString(navAid->m_name)); | 
					
						
							|  |  |  |         navAidMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |         navAidMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |         update(m_map, &navAidMapItem, "NavAid"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::addAirspace(const Airspace *airspace, const QString& group, int cnt) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     //MapSettings::MapItemSettings *itemSettings = getItemSettings(group);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QString details; | 
					
						
							|  |  |  |     details.append(airspace->m_name); | 
					
						
							|  |  |  |     details.append(QString("\n%1 - %2") | 
					
						
							|  |  |  |                 .arg(airspace->getAlt(&airspace->m_bottom)) | 
					
						
							|  |  |  |                 .arg(airspace->getAlt(&airspace->m_top))); | 
					
						
							|  |  |  |     QString name = QString("Airspace %1 (%2)").arg(airspace->m_name).arg(cnt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SWGSDRangel::SWGMapItem airspaceMapItem; | 
					
						
							|  |  |  |     airspaceMapItem.setName(new QString(name)); | 
					
						
							|  |  |  |     airspaceMapItem.setLatitude(airspace->m_position.y()); | 
					
						
							|  |  |  |     airspaceMapItem.setLongitude(airspace->m_position.x()); | 
					
						
							|  |  |  |     airspaceMapItem.setAltitude(airspace->bottomHeightInMetres()); | 
					
						
							|  |  |  |     QString image = QString("none"); | 
					
						
							|  |  |  |     airspaceMapItem.setImage(new QString(image)); | 
					
						
							|  |  |  |     airspaceMapItem.setImageRotation(0); | 
					
						
							|  |  |  |     airspaceMapItem.setText(new QString(details));   // Not used - label is used instead for now
 | 
					
						
							|  |  |  |     airspaceMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |     airspaceMapItem.setLabel(new QString(details)); | 
					
						
							|  |  |  |     airspaceMapItem.setAltitudeReference(0); | 
					
						
							|  |  |  |     QList<SWGSDRangel::SWGMapCoordinate *> *coords = new QList<SWGSDRangel::SWGMapCoordinate *>(); | 
					
						
							|  |  |  |     for (const auto p : airspace->m_polygon) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         SWGSDRangel::SWGMapCoordinate* c = new SWGSDRangel::SWGMapCoordinate(); | 
					
						
							|  |  |  |         c->setLatitude(p.y()); | 
					
						
							|  |  |  |         c->setLongitude(p.x()); | 
					
						
							|  |  |  |         c->setAltitude(airspace->bottomHeightInMetres()); | 
					
						
							|  |  |  |         coords->append(c); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     airspaceMapItem.setCoordinates(coords); | 
					
						
							|  |  |  |     airspaceMapItem.setExtrudedHeight(airspace->topHeightInMetres()); | 
					
						
							|  |  |  |     airspaceMapItem.setType(2); | 
					
						
							|  |  |  |     update(m_map, &airspaceMapItem, group); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::addAirspace() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_airspaces = OpenAIP::getAirspaces(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int cnt = 0; | 
					
						
							|  |  |  |     for (const auto airspace : *m_airspaces) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |          static const QMap<QString, QString> groupMap { | 
					
						
							|  |  |  |             {"A", "Airspace (A)"}, | 
					
						
							|  |  |  |             {"B", "Airspace (B)"}, | 
					
						
							|  |  |  |             {"C", "Airspace (C)"}, | 
					
						
							|  |  |  |             {"D", "Airspace (D)"}, | 
					
						
							|  |  |  |             {"E", "Airspace (E)"}, | 
					
						
							|  |  |  |             {"F", "Airspace (F)"}, | 
					
						
							|  |  |  |             {"G", "Airspace (G)"}, | 
					
						
							|  |  |  |             {"FIR", "Airspace (FIR)"}, | 
					
						
							|  |  |  |             {"CTR", "Airspace (CTR)"}, | 
					
						
							|  |  |  |             {"RMZ", "Airspace (RMZ)"}, | 
					
						
							|  |  |  |             {"TMA", "Airspace (TMA)"}, | 
					
						
							|  |  |  |             {"TMZ", "Airspace (TMZ)"}, | 
					
						
							|  |  |  |             {"OTH", "Airspace (OTH)"}, | 
					
						
							|  |  |  |             {"RESTRICTED", "Airspace (Restricted)"}, | 
					
						
							|  |  |  |             {"GLIDING", "Airspace (Gliding)"}, | 
					
						
							|  |  |  |             {"DANGER", "Airspace (Danger)"}, | 
					
						
							|  |  |  |             {"PROHIBITED", "Airspace (Prohibited)"}, | 
					
						
							|  |  |  |             {"WAVE", "Airspace (Wave)"}, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (groupMap.contains(airspace->m_category)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QString group = groupMap[airspace->m_category]; | 
					
						
							|  |  |  |             addAirspace(airspace, group, cnt); | 
					
						
							|  |  |  |             cnt++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (   (airspace->bottomHeightInMetres() == 0) | 
					
						
							|  |  |  |                 && ((airspace->m_category == "D") || (airspace->m_category == "G") || (airspace->m_category == "CTR")) | 
					
						
							|  |  |  |                 && (!((airspace->m_country == "IT") && (airspace->m_name.startsWith("FIR")))) | 
					
						
							|  |  |  |                 && (!((airspace->m_country == "PL") && (airspace->m_name.startsWith("FIS")))) | 
					
						
							|  |  |  |                ) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 group = "Airspace (Airports)"; | 
					
						
							|  |  |  |                 addAirspace(airspace, group, cnt); | 
					
						
							|  |  |  |                 cnt++; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug() << "MapGUI::addAirspace: No group for airspace category " << airspace->m_category; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::addAirports() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_airportInfo = OurAirportsDB::getAirportsById(); | 
					
						
							|  |  |  |     if (m_airportInfo) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QHashIterator<int, AirportInformation *> i(*m_airportInfo); | 
					
						
							|  |  |  |         while (i.hasNext()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             i.next(); | 
					
						
							|  |  |  |             AirportInformation *airport = i.value(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             SWGSDRangel::SWGMapItem airportMapItem; | 
					
						
							|  |  |  |             airportMapItem.setName(new QString(airport->m_ident)); | 
					
						
							|  |  |  |             airportMapItem.setLatitude(airport->m_latitude); | 
					
						
							|  |  |  |             airportMapItem.setLongitude(airport->m_longitude); | 
					
						
							|  |  |  |             airportMapItem.setAltitude(Units::feetToMetres(airport->m_elevation)); | 
					
						
							|  |  |  |             airportMapItem.setImage(new QString(airport->getImageName())); | 
					
						
							|  |  |  |             airportMapItem.setImageRotation(0); | 
					
						
							|  |  |  |             QStringList list; | 
					
						
							|  |  |  |             list.append(QString("%1: %2").arg(airport->m_ident).arg(airport->m_name)); | 
					
						
							|  |  |  |             for (int i = 0; i < airport->m_frequencies.size(); i++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 const AirportInformation::FrequencyInformation *frequencyInfo = airport->m_frequencies[i]; | 
					
						
							|  |  |  |                 list.append(QString("%1: %2 MHz").arg(frequencyInfo->m_type).arg(frequencyInfo->m_frequency)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             airportMapItem.setText(new QString(list.join("\n"))); | 
					
						
							|  |  |  |             airportMapItem.setModel(new QString("airport.glb")); // No such model currently, but we don't really want one
 | 
					
						
							|  |  |  |             airportMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |             airportMapItem.setOrientation(0); | 
					
						
							|  |  |  |             airportMapItem.setLabel(new QString(airport->m_ident)); | 
					
						
							|  |  |  |             airportMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |             airportMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |             QString group; | 
					
						
							|  |  |  |             if (airport->m_type == AirportInformation::Small) { | 
					
						
							|  |  |  |                 group = "Airport (Small)"; | 
					
						
							|  |  |  |             } else if (airport->m_type == AirportInformation::Medium) { | 
					
						
							|  |  |  |                 group = "Airport (Medium)"; | 
					
						
							|  |  |  |             } else if (airport->m_type == AirportInformation::Large) { | 
					
						
							|  |  |  |                 group = "Airport (Large)"; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 group = "Heliport"; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             update(m_map, &airportMapItem, group); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::navAidsUpdated() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     addNavAids(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::airspacesUpdated() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     addAirspace(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::airportsUpdated() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     addAirports(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-03 17:14:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::addNavtex() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (int i = 0; i < NavtexTransmitter::m_navtexTransmitters.size(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         SWGSDRangel::SWGMapItem navtexMapItem; | 
					
						
							|  |  |  |         QString name = QString("%1").arg(NavtexTransmitter::m_navtexTransmitters[i].m_station); | 
					
						
							|  |  |  |         navtexMapItem.setName(new QString(name)); | 
					
						
							|  |  |  |         navtexMapItem.setLatitude(NavtexTransmitter::m_navtexTransmitters[i].m_latitude); | 
					
						
							|  |  |  |         navtexMapItem.setLongitude(NavtexTransmitter::m_navtexTransmitters[i].m_longitude); | 
					
						
							|  |  |  |         navtexMapItem.setAltitude(0.0); | 
					
						
							|  |  |  |         navtexMapItem.setImage(new QString("antenna.png")); | 
					
						
							|  |  |  |         navtexMapItem.setImageRotation(0); | 
					
						
							|  |  |  |         QString text = QString("Navtex Transmitter\nStation: %1\nArea: %2") | 
					
						
							|  |  |  |                                 .arg(NavtexTransmitter::m_navtexTransmitters[i].m_station) | 
					
						
							|  |  |  |                                 .arg(NavtexTransmitter::m_navtexTransmitters[i].m_area); | 
					
						
							|  |  |  |         QStringList schedules; | 
					
						
							|  |  |  |         for (const auto& schedule : NavtexTransmitter::m_navtexTransmitters[i].m_schedules) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QString scheduleText = QString("\nFrequency: %1 kHz\nID: %2").arg(schedule.m_frequency / 1000).arg(schedule.m_id); | 
					
						
							|  |  |  |             if (schedule.m_times.size() > 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QStringList times; | 
					
						
							|  |  |  |                 for (const auto& time : schedule.m_times) { | 
					
						
							|  |  |  |                     times.append(time.toString("hh:mm")); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 scheduleText.append("\nTimes: "); | 
					
						
							|  |  |  |                 scheduleText.append(times.join(" ")); | 
					
						
							|  |  |  |                 scheduleText.append(" UTC"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             schedules.append(scheduleText); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         text.append(schedules.join("")); | 
					
						
							|  |  |  |         navtexMapItem.setText(new QString(text)); | 
					
						
							|  |  |  |         navtexMapItem.setModel(new QString("antenna.glb")); | 
					
						
							|  |  |  |         navtexMapItem.setFixedPosition(true); | 
					
						
							|  |  |  |         navtexMapItem.setOrientation(0); | 
					
						
							|  |  |  |         navtexMapItem.setLabel(new QString(name)); | 
					
						
							|  |  |  |         navtexMapItem.setLabelAltitudeOffset(4.5); | 
					
						
							|  |  |  |         navtexMapItem.setAltitudeReference(1); | 
					
						
							|  |  |  |         update(m_map, &navtexMapItem, "Navtex"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | void MapGUI::blockApplySettings(bool block) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_doApplySettings = !block; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | QString MapGUI::osmCachePath() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/QtLocation/5.8/tiles/osm/sdrangel_map"; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::clearOSMCache() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Delete all cached custom tiles when user changes the URL. Is there a better way to do this?
 | 
					
						
							|  |  |  |     QDir dir(osmCachePath()); | 
					
						
							|  |  |  |     if (dir.exists()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QStringList filenames = dir.entryList({"osm_100-l-8-*.png"}); | 
					
						
							|  |  |  |         for (const auto& filename : filenames) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QFile file(dir.filePath(filename)); | 
					
						
							|  |  |  |             if (!file.remove()) { | 
					
						
							|  |  |  |                 qDebug() << "MapGUI::clearOSMCache: Failed to remove " << file; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | void MapGUI::applyMap2DSettings(bool reloadMap) | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     ui->map->setVisible(m_settings.m_map2DEnabled); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     if (m_settings.m_map2DEnabled && reloadMap) | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         float stationLatitude = MainCore::instance()->getSettings().getLatitude(); | 
					
						
							|  |  |  |         float stationLongitude = MainCore::instance()->getSettings().getLongitude(); | 
					
						
							|  |  |  |         float stationAltitude = MainCore::instance()->getSettings().getAltitude(); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QObject *object = item->findChild<QObject*>("map"); | 
					
						
							|  |  |  |         QGeoCoordinate coords; | 
					
						
							|  |  |  |         double zoom; | 
					
						
							|  |  |  |         if (object != nullptr) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Save existing position of map
 | 
					
						
							|  |  |  |             coords = object->property("center").value<QGeoCoordinate>(); | 
					
						
							|  |  |  |             zoom = object->property("zoomLevel").value<double>(); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Center on my location when map is first opened
 | 
					
						
							|  |  |  |             coords.setLatitude(stationLatitude); | 
					
						
							|  |  |  |             coords.setLongitude(stationLongitude); | 
					
						
							|  |  |  |             coords.setAltitude(stationAltitude); | 
					
						
							|  |  |  |             zoom = 10.0; | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         // Create the map using the specified provider
 | 
					
						
							| 
									
										
										
										
											2023-02-16 11:00:30 +00:00
										 |  |  |         QQmlProperty::write(item, "smoothing", MainCore::instance()->getSettings().getMapSmoothing()); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         QQmlProperty::write(item, "mapProvider", m_settings.m_mapProvider); | 
					
						
							|  |  |  |         QVariantMap parameters; | 
					
						
							|  |  |  |         if (!m_settings.m_mapBoxAPIKey.isEmpty() && m_settings.m_mapProvider == "mapbox") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             parameters["mapbox.map_id"] = "mapbox.satellite"; // The only one that works
 | 
					
						
							|  |  |  |             parameters["mapbox.access_token"] = m_settings.m_mapBoxAPIKey; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!m_settings.m_mapBoxAPIKey.isEmpty() && m_settings.m_mapProvider == "mapboxgl") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             parameters["mapboxgl.access_token"] = m_settings.m_mapBoxAPIKey; | 
					
						
							|  |  |  |             if (!m_settings.m_mapBoxStyles.isEmpty()) | 
					
						
							|  |  |  |                 parameters["mapboxgl.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (m_settings.m_mapProvider == "maplibre") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             parameters["maplibre.access_token"] = m_settings.m_mapBoxAPIKey; | 
					
						
							|  |  |  |             if (!m_settings.m_mapBoxStyles.isEmpty()) | 
					
						
							|  |  |  |                 parameters["maplibre.mapping.additional_style_urls"] = m_settings.m_mapBoxStyles; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (m_settings.m_mapProvider == "osm") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Allow user to specify URL
 | 
					
						
							|  |  |  |             if (!m_settings.m_osmURL.isEmpty()) { | 
					
						
							|  |  |  |                 parameters["osm.mapping.custom.host"] = m_settings.m_osmURL;  // E.g: "http://a.tile.openstreetmap.fr/hot/"
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             // Use our repo, so we can append API key
 | 
					
						
							|  |  |  |             parameters["osm.mapping.providersrepository.address"] = QString("http://127.0.0.1:%1/").arg(m_osmPort); | 
					
						
							|  |  |  |             // Use application specific cache, as other apps may not use API key so will have different images
 | 
					
						
							|  |  |  |             QString cachePath = osmCachePath(); | 
					
						
							|  |  |  |             parameters["osm.mapping.cache.directory"] = cachePath; | 
					
						
							|  |  |  |             // On Linux, we need to create the directory
 | 
					
						
							|  |  |  |             QDir dir(cachePath); | 
					
						
							|  |  |  |             if (!dir.exists()) { | 
					
						
							|  |  |  |                 dir.mkpath(cachePath); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QVariant retVal; | 
					
						
							|  |  |  |         if (!QMetaObject::invokeMethod(item, "createMap", Qt::DirectConnection, | 
					
						
							|  |  |  |                                     Q_RETURN_ARG(QVariant, retVal), | 
					
						
							|  |  |  |                                     Q_ARG(QVariant, QVariant::fromValue(parameters)), | 
					
						
							|  |  |  |                                     //Q_ARG(QVariant, mapType),
 | 
					
						
							|  |  |  |                                     Q_ARG(QVariant, QVariant::fromValue(this)))) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qCritical() << "MapGUI::applyMap2DSettings - Failed to invoke createMap"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         QObject *newMap = retVal.value<QObject *>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Restore position of map
 | 
					
						
							|  |  |  |         if (newMap != nullptr) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (coords.isValid()) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 newMap->setProperty("zoomLevel", QVariant::fromValue(zoom)); | 
					
						
							|  |  |  |                 newMap->setProperty("center", QVariant::fromValue(coords)); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qCritical() << "MapGUI::applyMap2DSettings - createMap returned a nullptr"; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         supportedMapsChanged(); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | void MapGUI::redrawMap() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // An awful workaround for https://bugreports.qt.io/browse/QTBUG-100333
 | 
					
						
							|  |  |  |     // Also used in ADS-B demod
 | 
					
						
							|  |  |  |     QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |     if (item) | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         QObject *object = item->findChild<QObject*>("map"); | 
					
						
							|  |  |  |         if (object) | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             double zoom = object->property("zoomLevel").value<double>(); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |             object->setProperty("zoomLevel", QVariant::fromValue(zoom+1.0)); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             object->setProperty("zoomLevel", QVariant::fromValue(zoom)); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::showEvent(QShowEvent *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!event->spontaneous()) | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         // Workaround for https://bugreports.qt.io/browse/QTBUG-100333
 | 
					
						
							|  |  |  |         // MapQuickItems can be in wrong position when window is first displayed
 | 
					
						
							| 
									
										
										
										
											2022-03-23 09:04:04 +00:00
										 |  |  |         m_redrawMapTimer.start(500); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | bool MapGUI::eventFilter(QObject *obj, QEvent *event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (obj == ui->map) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (event->type() == QEvent::Resize) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Workaround for https://bugreports.qt.io/browse/QTBUG-100333
 | 
					
						
							|  |  |  |             // MapQuickItems can be in wrong position after vertical resize
 | 
					
						
							|  |  |  |             QResizeEvent *resizeEvent = static_cast<QResizeEvent *>(event); | 
					
						
							|  |  |  |             QSize oldSize = resizeEvent->oldSize(); | 
					
						
							|  |  |  |             QSize size = resizeEvent->size(); | 
					
						
							|  |  |  |             if (oldSize.height() != size.height()) { | 
					
						
							|  |  |  |                 redrawMap(); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |     return FeatureGUI::eventFilter(obj, event); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  | MapSettings::MapItemSettings *MapGUI::getItemSettings(const QString &group) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_settings.m_itemSettings.contains(group)) { | 
					
						
							|  |  |  |         return m_settings.m_itemSettings[group]; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         return nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  | void MapGUI::supportedMapsChanged() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |     QObject *object = item->findChild<QObject*>("map"); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Get list of map types
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     ui->mapTypes->blockSignals(true); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     ui->mapTypes->clear(); | 
					
						
							|  |  |  |     if (object != nullptr) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // Mapbox plugin only works for Satellite imagary, despite what is indicated
 | 
					
						
							|  |  |  |         if (m_settings.m_mapProvider == "mapbox") | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |             ui->mapTypes->addItem("Satellite"); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             QVariant mapTypesVariant; | 
					
						
							|  |  |  |             QMetaObject::invokeMethod(item, "getMapTypes", Q_RETURN_ARG(QVariant, mapTypesVariant)); | 
					
						
							|  |  |  |             QStringList mapTypes = mapTypesVariant.value<QStringList>(); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |             for (int i = 0; i < mapTypes.size(); i++) { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |                 ui->mapTypes->addItem(mapTypes[i]); | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     ui->mapTypes->blockSignals(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Try to select desired map, if available
 | 
					
						
							|  |  |  |     if (!m_settings.m_mapType.isEmpty()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         int index = ui->mapTypes->findText(m_settings.m_mapType); | 
					
						
							|  |  |  |         if (index != -1) { | 
					
						
							|  |  |  |             ui->mapTypes->setCurrentIndex(index); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::on_mapTypes_currentIndexChanged(int index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     if (index >= 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QVariant mapType = index; | 
					
						
							|  |  |  |         QMetaObject::invokeMethod(ui->map->rootObject(), "setMapType", Q_ARG(QVariant, mapType)); | 
					
						
							|  |  |  |         QString currentMap = ui->mapTypes->currentText(); | 
					
						
							| 
									
										
										
										
											2022-11-27 20:00:43 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         if (!currentMap.isEmpty()) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             m_settings.m_mapType = currentMap; | 
					
						
							| 
									
										
										
										
											2022-11-27 20:00:43 +01:00
										 |  |  |             m_settingsKeys.append("mapType"); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             applySettings(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::applyMap3DSettings(bool reloadMap) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #ifdef QT_WEBENGINE_FOUND
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     if (m_settings.m_map3DEnabled && ((m_cesium == nullptr) || reloadMap)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |         if (m_cesium == nullptr) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             m_cesium = new CesiumInterface(&m_settings); | 
					
						
							|  |  |  |             connect(m_cesium, &CesiumInterface::connected, this, &MapGUI::init3DMap); | 
					
						
							|  |  |  |             connect(m_cesium, &CesiumInterface::received, this, &MapGUI::receivedCesiumEvent); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         m_webServer->addSubstitution("/map/map/map3d.html", "$WS_PORT$", QString::number(m_cesium->serverPort())); | 
					
						
							|  |  |  |         m_webServer->addSubstitution("/map/map/map3d.html", "$CESIUM_ION_API_KEY$", cesiumIonAPIKey()); | 
					
						
							|  |  |  |         //ui->web->page()->profile()->clearHttpCache();
 | 
					
						
							|  |  |  |         ui->web->load(QUrl(QString("http://127.0.0.1:%1/map/map/map3d.html").arg(m_webPort))); | 
					
						
							| 
									
										
										
										
											2022-11-11 12:35:19 +00:00
										 |  |  |         //ui->web->load(QUrl(QString("http://webglreport.com/")));
 | 
					
						
							|  |  |  |         //ui->web->load(QUrl(QString("https://sandcastle.cesium.com/")));
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         //ui->web->load(QUrl("chrome://gpu/"));
 | 
					
						
							|  |  |  |         ui->web->show(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (!m_settings.m_map3DEnabled && (m_cesium != nullptr)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ui->web->setHtml("<html></html>"); | 
					
						
							|  |  |  |         m_cesium->deleteLater(); | 
					
						
							|  |  |  |         m_cesium = nullptr; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     ui->web->setVisible(m_settings.m_map3DEnabled); | 
					
						
							|  |  |  |     if (m_cesium && m_cesium->isConnected()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_cesium->setTerrain(m_settings.m_terrain, maptilerAPIKey()); | 
					
						
							|  |  |  |         m_cesium->setBuildings(m_settings.m_buildings); | 
					
						
							|  |  |  |         m_cesium->setSunLight(m_settings.m_sunLightEnabled); | 
					
						
							|  |  |  |         m_cesium->setCameraReferenceFrame(m_settings.m_eciCamera); | 
					
						
							|  |  |  |         m_cesium->setAntiAliasing(m_settings.m_antiAliasing); | 
					
						
							| 
									
										
										
										
											2022-02-09 16:41:40 +00:00
										 |  |  |         m_cesium->getDateTime(); | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  |         m_cesium->showMUF(m_settings.m_displayMUF); | 
					
						
							|  |  |  |         m_cesium->showfoF2(m_settings.m_displayfoF2); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |         m_objectMapModel.allUpdated(); | 
					
						
							|  |  |  |         m_imageMapModel.allUpdated(); | 
					
						
							|  |  |  |         m_polygonMapModel.allUpdated(); | 
					
						
							|  |  |  |         m_polylineMapModel.allUpdated(); | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     MapSettings::MapItemSettings *ionosondeItemSettings = getItemSettings("Ionosonde Stations"); | 
					
						
							|  |  |  |     if (ionosondeItemSettings) { | 
					
						
							|  |  |  |         m_giro->getDataPeriodically(ionosondeItemSettings->m_enabled ? 2 : 0); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  |     m_giro->getMUFPeriodically(m_settings.m_displayMUF ? 15 : 0); | 
					
						
							|  |  |  |     m_giro->getfoF2Periodically(m_settings.m_displayfoF2 ? 15 : 0); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  |     ui->displayMUF->setVisible(false); | 
					
						
							|  |  |  |     ui->displayfoF2->setVisible(false); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel.allUpdated(); | 
					
						
							|  |  |  |     m_imageMapModel.allUpdated(); | 
					
						
							|  |  |  |     m_polygonMapModel.allUpdated(); | 
					
						
							|  |  |  |     m_polylineMapModel.allUpdated(); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::init3DMap() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #ifdef QT_WEBENGINE_FOUND
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     qDebug() << "MapGUI::init3DMap"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_cesium->initCZML(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     float stationLatitude = MainCore::instance()->getSettings().getLatitude(); | 
					
						
							|  |  |  |     float stationLongitude = MainCore::instance()->getSettings().getLongitude(); | 
					
						
							|  |  |  |     float stationAltitude = MainCore::instance()->getSettings().getLongitude(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     m_cesium->setPosition(QGeoCoordinate(stationLatitude, stationLongitude, stationAltitude)); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     m_cesium->setTerrain(m_settings.m_terrain, maptilerAPIKey()); | 
					
						
							|  |  |  |     m_cesium->setBuildings(m_settings.m_buildings); | 
					
						
							|  |  |  |     m_cesium->setSunLight(m_settings.m_sunLightEnabled); | 
					
						
							|  |  |  |     m_cesium->setCameraReferenceFrame(m_settings.m_eciCamera); | 
					
						
							|  |  |  |     m_cesium->setAntiAliasing(m_settings.m_antiAliasing); | 
					
						
							| 
									
										
										
										
											2022-02-09 16:41:40 +00:00
										 |  |  |     m_cesium->getDateTime(); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel.allUpdated(); | 
					
						
							|  |  |  |     m_imageMapModel.allUpdated(); | 
					
						
							|  |  |  |     m_polygonMapModel.allUpdated(); | 
					
						
							|  |  |  |     m_polylineMapModel.allUpdated(); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Set 3D view after loading initial objects
 | 
					
						
							|  |  |  |     m_cesium->setHomeView(stationLatitude, stationLongitude); | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_cesium->showMUF(m_settings.m_displayMUF); | 
					
						
							|  |  |  |     m_cesium->showfoF2(m_settings.m_displayfoF2); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | void MapGUI::displaySettings() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     setTitleColor(m_settings.m_rgbColor); | 
					
						
							|  |  |  |     setWindowTitle(m_settings.m_title); | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  |     setTitle(m_settings.m_title); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     blockApplySettings(true); | 
					
						
							|  |  |  |     ui->displayNames->setChecked(m_settings.m_displayNames); | 
					
						
							| 
									
										
										
										
											2021-02-26 20:30:59 +00:00
										 |  |  |     ui->displaySelectedGroundTracks->setChecked(m_settings.m_displaySelectedGroundTracks); | 
					
						
							|  |  |  |     ui->displayAllGroundTracks->setChecked(m_settings.m_displayAllGroundTracks); | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  |     ui->displayMUF->setChecked(m_settings.m_displayMUF); | 
					
						
							|  |  |  |     ui->displayfoF2->setChecked(m_settings.m_displayfoF2); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel.setDisplayNames(m_settings.m_displayNames); | 
					
						
							|  |  |  |     m_objectMapModel.setDisplaySelectedGroundTracks(m_settings.m_displaySelectedGroundTracks); | 
					
						
							|  |  |  |     m_objectMapModel.setDisplayAllGroundTracks(m_settings.m_displayAllGroundTracks); | 
					
						
							|  |  |  |     m_objectMapModel.updateItemSettings(m_settings.m_itemSettings); | 
					
						
							|  |  |  |     m_imageMapModel.updateItemSettings(m_settings.m_itemSettings); | 
					
						
							|  |  |  |     m_polygonMapModel.updateItemSettings(m_settings.m_itemSettings); | 
					
						
							|  |  |  |     m_polylineMapModel.updateItemSettings(m_settings.m_itemSettings); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     applyMap2DSettings(true); | 
					
						
							|  |  |  |     applyMap3DSettings(true); | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  |     getRollupContents()->restoreState(m_rollupState); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |     blockApplySettings(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::onMenuDialogCalled(const QPoint &p) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_contextMenuType == ContextMenuChannelSettings) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         BasicFeatureSettingsDialog dialog(this); | 
					
						
							|  |  |  |         dialog.setTitle(m_settings.m_title); | 
					
						
							|  |  |  |         dialog.setUseReverseAPI(m_settings.m_useReverseAPI); | 
					
						
							|  |  |  |         dialog.setReverseAPIAddress(m_settings.m_reverseAPIAddress); | 
					
						
							|  |  |  |         dialog.setReverseAPIPort(m_settings.m_reverseAPIPort); | 
					
						
							|  |  |  |         dialog.setReverseAPIFeatureSetIndex(m_settings.m_reverseAPIFeatureSetIndex); | 
					
						
							|  |  |  |         dialog.setReverseAPIFeatureIndex(m_settings.m_reverseAPIFeatureIndex); | 
					
						
							| 
									
										
										
										
											2022-04-18 12:08:33 +02:00
										 |  |  |         dialog.setDefaultTitle(m_displayedName); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         dialog.move(p); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |         new DialogPositioner(&dialog, false); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         dialog.exec(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         m_settings.m_title = dialog.getTitle(); | 
					
						
							|  |  |  |         m_settings.m_useReverseAPI = dialog.useReverseAPI(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIAddress = dialog.getReverseAPIAddress(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIPort = dialog.getReverseAPIPort(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIFeatureSetIndex = dialog.getReverseAPIFeatureSetIndex(); | 
					
						
							|  |  |  |         m_settings.m_reverseAPIFeatureIndex = dialog.getReverseAPIFeatureIndex(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-18 12:08:33 +02:00
										 |  |  |         setTitle(m_settings.m_title); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         setTitleColor(m_settings.m_rgbColor); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-27 20:00:43 +01:00
										 |  |  |         m_settingsKeys.append("title"); | 
					
						
							|  |  |  |         m_settingsKeys.append("rgbColor"); | 
					
						
							|  |  |  |         m_settingsKeys.append("useReverseAPI"); | 
					
						
							|  |  |  |         m_settingsKeys.append("reverseAPIAddress"); | 
					
						
							|  |  |  |         m_settingsKeys.append("reverseAPIPort"); | 
					
						
							|  |  |  |         m_settingsKeys.append("reverseAPIFeatureSetIndex"); | 
					
						
							|  |  |  |         m_settingsKeys.append("reverseAPIFeatureIndex"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         applySettings(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     resetContextMenuType(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::applySettings(bool force) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_doApplySettings) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2022-11-27 20:00:43 +01:00
										 |  |  |         Map::MsgConfigureMap* message = Map::MsgConfigureMap::create(m_settings, m_settingsKeys, force); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         m_map->getInputMessageQueue()->push(message); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-11-27 20:00:43 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     m_settingsKeys.clear(); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 15:22:47 +00:00
										 |  |  | void MapGUI::on_maidenhead_clicked() | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     MapMaidenheadDialog dialog; | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |     new DialogPositioner(&dialog, true); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     dialog.exec(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | void MapGUI::on_displayNames_clicked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_displayNames = checked; | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel.setDisplayNames(checked); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-26 20:30:59 +00:00
										 |  |  | void MapGUI::on_displaySelectedGroundTracks_clicked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_displaySelectedGroundTracks = checked; | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel.setDisplaySelectedGroundTracks(checked); | 
					
						
							| 
									
										
										
										
											2021-02-26 20:30:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::on_displayAllGroundTracks_clicked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_displayAllGroundTracks = checked; | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel.setDisplayAllGroundTracks(checked); | 
					
						
							| 
									
										
										
										
											2021-02-26 20:30:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  | void MapGUI::on_displayMUF_clicked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_displayMUF = checked; | 
					
						
							|  |  |  |     // Only call show if disabling, so we don't get two updates
 | 
					
						
							|  |  |  |     // (as getMUFPeriodically results in a call to showMUF when the data is available)
 | 
					
						
							|  |  |  |      m_giro->getMUFPeriodically(m_settings.m_displayMUF ? 15 : 0); | 
					
						
							|  |  |  |     if (m_cesium && !m_settings.m_displayMUF) { | 
					
						
							|  |  |  |         m_cesium->showMUF(m_settings.m_displayMUF); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::on_displayfoF2_clicked(bool checked) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_settings.m_displayfoF2 = checked; | 
					
						
							|  |  |  |     m_giro->getfoF2Periodically(m_settings.m_displayfoF2 ? 15 : 0); | 
					
						
							|  |  |  |     if (m_cesium && !m_settings.m_displayfoF2) { | 
					
						
							|  |  |  |         m_cesium->showfoF2(m_settings.m_displayfoF2); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | void MapGUI::on_find_returnPressed() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     find(ui->find->text().trimmed()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | void MapGUI::geoReply() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QGeoCodeReply *pQGeoCode = dynamic_cast<QGeoCodeReply*>(sender()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((pQGeoCode != nullptr) && (pQGeoCode->error() == QGeoCodeReply::NoError)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QList<QGeoLocation> qGeoLocs = pQGeoCode->locations(); | 
					
						
							|  |  |  |         QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |         QObject *map = item->findChild<QObject*>("map"); | 
					
						
							|  |  |  |         if (qGeoLocs.size() == 1) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Only one result, so centre map on that
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             QGeoCoordinate coord = qGeoLocs.at(0).coordinate(); | 
					
						
							|  |  |  |             map->setProperty("center", QVariant::fromValue(coord)); | 
					
						
							|  |  |  |             if (m_cesium) { | 
					
						
							|  |  |  |                 m_cesium->setView(coord.latitude(), coord.longitude()); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         else if (qGeoLocs.size() == 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             qDebug() << "MapGUI::geoReply: No location found for address"; | 
					
						
							|  |  |  |             QApplication::beep(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             // Show dialog allowing user to select from the results
 | 
					
						
							|  |  |  |             MapLocationDialog dialog(qGeoLocs); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |             new DialogPositioner(&dialog, true); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |             if (dialog.exec() == QDialog::Accepted) | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             { | 
					
						
							|  |  |  |                 QGeoCoordinate coord = dialog.m_selectedLocation.coordinate(); | 
					
						
							|  |  |  |                 map->setProperty("center", QVariant::fromValue(coord)); | 
					
						
							|  |  |  |                 if (m_cesium) { | 
					
						
							|  |  |  |                     m_cesium->setView(coord.latitude(), coord.longitude()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         qWarning() << "MapGUI::geoReply: GeoCode error: " << pQGeoCode->error(); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     pQGeoCode->deleteLater(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | // Free keys, so no point in stealing them :)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString MapGUI::thunderforestAPIKey() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_settings.m_thunderforestAPIKey.isEmpty() ? "3e1f614f78a345459931ba3c898e975e" : m_settings.m_thunderforestAPIKey; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString MapGUI::maptilerAPIKey() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_settings.m_maptilerAPIKey.isEmpty() ? "q2RVNAe3eFKCH4XsrE3r" : m_settings.m_maptilerAPIKey; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString MapGUI::cesiumIonAPIKey() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return m_settings.m_cesiumIonAPIKey.isEmpty() | 
					
						
							|  |  |  |         ? "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyNTcxMDA2OC0yNTIzLTQxMGYtYTNiMS1iM2I3MDFhNWVlMDYiLCJpZCI6ODEyMDUsImlhdCI6MTY0MzY2OTIzOX0.A7NchU4LzaNsuAUpsrA9ZwekOJfMoNcja-8XeRdRoIg" | 
					
						
							|  |  |  |         : m_settings.m_cesiumIonAPIKey; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | void MapGUI::find(const QString& target) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!target.isEmpty()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |         QObject *map = item->findChild<QObject*>("map"); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         if (map != nullptr) | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |             // Search as:
 | 
					
						
							|  |  |  |             //  latitude and longitude
 | 
					
						
							|  |  |  |             //  Maidenhead locator
 | 
					
						
							|  |  |  |             //  object name
 | 
					
						
							|  |  |  |             //  address
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |             float latitude, longitude; | 
					
						
							|  |  |  |             if (Units::stringToLatitudeAndLongitude(target, latitude, longitude)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 map->setProperty("center", QVariant::fromValue(QGeoCoordinate(latitude, longitude))); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                 if (m_cesium) { | 
					
						
							|  |  |  |                     m_cesium->setView(latitude, longitude); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else if (Maidenhead::fromMaidenhead(target, latitude, longitude)) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 map->setProperty("center", QVariant::fromValue(QGeoCoordinate(latitude, longitude))); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                 if (m_cesium) { | 
					
						
							|  |  |  |                     m_cesium->setView(latitude, longitude); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |                 // FIXME: Support polygon/polyline
 | 
					
						
							|  |  |  |                 ObjectMapItem *mapItem = m_objectMapModel.findMapItem(target); | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |                 if (mapItem != nullptr) | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                 { | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |                     map->setProperty("center", QVariant::fromValue(mapItem->getCoordinates())); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                     if (m_cesium) { | 
					
						
							|  |  |  |                         m_cesium->track(target); | 
					
						
							|  |  |  |                     } | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |                     m_objectMapModel.moveToFront(m_objectMapModel.findMapItemIndex(target).row()); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     QGeoServiceProvider* geoSrv = new QGeoServiceProvider("osm"); | 
					
						
							|  |  |  |                     if (geoSrv != nullptr) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         QLocale qLocaleC(QLocale::C, QLocale::AnyCountry); | 
					
						
							|  |  |  |                         geoSrv->setLocale(qLocaleC); | 
					
						
							|  |  |  |                         QGeoCodeReply *pQGeoCode = geoSrv->geocodingManager()->geocode(target); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                         if (pQGeoCode) { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |                             QObject::connect(pQGeoCode, &QGeoCodeReply::finished, this, &MapGUI::geoReply); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                         } else { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |                             qDebug() << "MapGUI::find: GeoCoding failed"; | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                         } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |                     } | 
					
						
							|  |  |  |                     else | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                     { | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |                         qDebug() << "MapGUI::find: osm not available"; | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |                     } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | void MapGUI::track3D(const QString& target) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (m_cesium) { | 
					
						
							|  |  |  |         m_cesium->track(target); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | void MapGUI::on_deleteAll_clicked() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     m_objectMapModel.removeAll(); | 
					
						
							|  |  |  |     m_imageMapModel.removeAll(); | 
					
						
							|  |  |  |     m_polygonMapModel.removeAll(); | 
					
						
							|  |  |  |     m_polylineMapModel.removeAll(); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     if (m_cesium) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         m_cesium->removeAllCZMLEntities(); | 
					
						
							|  |  |  |         m_cesium->removeAllImages(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-01-13 20:07:28 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::on_displaySettings_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     MapSettingsDialog dialog(&m_settings); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |     connect(&dialog, &MapSettingsDialog::navAidsUpdated, this, &MapGUI::navAidsUpdated); | 
					
						
							|  |  |  |     connect(&dialog, &MapSettingsDialog::airspacesUpdated, this, &MapGUI::airspacesUpdated); | 
					
						
							|  |  |  |     connect(&dialog, &MapSettingsDialog::airportsUpdated, this, &MapGUI::airportsUpdated); | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  |     new DialogPositioner(&dialog, true); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     if (dialog.exec() == QDialog::Accepted) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-11-23 16:44:07 +00:00
										 |  |  |         if (dialog.m_osmURLChanged) { | 
					
						
							|  |  |  |             clearOSMCache(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |         applyMap2DSettings(dialog.m_map2DSettingsChanged); | 
					
						
							|  |  |  |         applyMap3DSettings(dialog.m_map3DSettingsChanged); | 
					
						
							| 
									
										
										
										
											2023-03-21 11:07:25 +00:00
										 |  |  |         m_settingsKeys.append(dialog.m_settingsKeysChanged); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |         applySettings(); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |         m_objectMapModel.allUpdated(); | 
					
						
							|  |  |  |         m_imageMapModel.allUpdated(); | 
					
						
							|  |  |  |         m_polygonMapModel.allUpdated(); | 
					
						
							|  |  |  |         m_polylineMapModel.allUpdated(); | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::on_beacons_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_beaconDialog.show(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-03 18:23:14 +00:00
										 |  |  | void MapGUI::on_ibpBeacons_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_ibpBeaconDialog.show(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-23 15:15:50 +01:00
										 |  |  | void MapGUI::on_radiotime_clicked() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     m_radioTimeDialog.updateTable(); | 
					
						
							|  |  |  |     m_radioTimeDialog.show(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 14:54:22 +00:00
										 |  |  | QString MapGUI::getDataDir() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // Get directory to store app data in (aircraft & airport databases and user-definable icons)
 | 
					
						
							|  |  |  |     QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation); | 
					
						
							|  |  |  |     // First dir is writable
 | 
					
						
							|  |  |  |     return locations[0]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QString MapGUI::getBeaconFilename() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return MapGUI::getDataDir() + "/iaru_beacons.csv"; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2021-02-26 20:30:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | QQuickItem *MapGUI::getMapItem() { | 
					
						
							|  |  |  |     return ui->map->rootObject(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::receivedCesiumEvent(const QJsonObject &obj) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (obj.contains("event")) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QString event = obj.value("event").toString(); | 
					
						
							|  |  |  |         if (event == "selected") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (obj.contains("id")) { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |                 m_objectMapModel.setSelected3D(obj.value("id").toString()); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |                 m_objectMapModel.setSelected3D(""); | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else if (event == "tracking") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (obj.contains("id")) { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |                 //m_objectMapModel.setTarget(obj.value("id").toString());
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |                 //m_objectMapModel.setTarget("");
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-09 16:41:40 +00:00
										 |  |  |         else if (event == "clock") | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (m_map) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 QDateTime mapDateTime = QDateTime::fromString(obj.value("currentTime").toString(), Qt::ISODateWithMs); | 
					
						
							|  |  |  |                 QDateTime systemDateTime = QDateTime::fromString(obj.value("systemTime").toString(), Qt::ISODateWithMs); | 
					
						
							|  |  |  |                 double multiplier = obj.value("multiplier").toDouble(); | 
					
						
							|  |  |  |                 bool canAnimate = obj.value("canAnimate").toBool(); | 
					
						
							|  |  |  |                 bool shouldAnimate = obj.value("shouldAnimate").toBool(); | 
					
						
							|  |  |  |                 m_map->setMapDateTime(mapDateTime, systemDateTime, canAnimate && shouldAnimate ? multiplier : 0.0); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         qDebug() << "MapGUI::receivedCesiumEvent - Unexpected event: " << obj; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #ifdef QT_WEBENGINE_FOUND
 | 
					
						
							| 
									
										
										
										
											2022-02-04 20:40:43 +00:00
										 |  |  | void MapGUI::fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     fullScreenRequest.accept(); | 
					
						
							|  |  |  |     if (fullScreenRequest.toggleOn()) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ui->web->setParent(nullptr); | 
					
						
							|  |  |  |         ui->web->showFullScreen(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ui->splitter->addWidget(ui->web); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-01-02 15:48:08 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::preferenceChanged(int elementType) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Preferences::ElementType pref = (Preferences::ElementType)elementType; | 
					
						
							|  |  |  |     if ((pref == Preferences::Latitude) || (pref == Preferences::Longitude) || (pref == Preferences::Altitude)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         float stationLatitude = MainCore::instance()->getSettings().getLatitude(); | 
					
						
							|  |  |  |         float stationLongitude = MainCore::instance()->getSettings().getLongitude(); | 
					
						
							|  |  |  |         float stationAltitude = MainCore::instance()->getSettings().getAltitude(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |         QGeoCoordinate stationPosition(stationLatitude, stationLongitude, stationAltitude); | 
					
						
							|  |  |  |         QGeoCoordinate previousPosition(m_azEl.getLocationSpherical().m_latitude, m_azEl.getLocationSpherical().m_longitude, m_azEl.getLocationSpherical().m_altitude); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (stationPosition != previousPosition) | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  |         { | 
					
						
							|  |  |  |             // Update position of station
 | 
					
						
							|  |  |  |             m_azEl.setLocation(stationLatitude, stationLongitude, stationAltitude); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             m_antennaMapItem.setLatitude(stationLatitude); | 
					
						
							|  |  |  |             m_antennaMapItem.setLongitude(stationLongitude); | 
					
						
							|  |  |  |             m_antennaMapItem.setAltitude(stationAltitude); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  |             delete m_antennaMapItem.getPositionDateTime(); | 
					
						
							|  |  |  |             m_antennaMapItem.setPositionDateTime(new QString(QDateTime::currentDateTime().toString(Qt::ISODateWithMs))); | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  |             update(m_map, &m_antennaMapItem, "Station"); | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             m_objectMapFilter.setPosition(stationPosition); | 
					
						
							|  |  |  |             m_imageMapFilter.setPosition(stationPosition); | 
					
						
							|  |  |  |             m_polygonMapFilter.setPosition(stationPosition); | 
					
						
							|  |  |  |             m_polylineMapFilter.setPosition(stationPosition); | 
					
						
							|  |  |  |             if (m_cesium) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 m_cesium->setPosition(stationPosition); | 
					
						
							|  |  |  |                 if (!m_lastFullUpdatePosition.isValid() || (stationPosition.distanceTo(m_lastFullUpdatePosition) >= 1000)) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     // Update all objects so distance filter is reapplied
 | 
					
						
							|  |  |  |                     m_objectMapModel.allUpdated(); | 
					
						
							|  |  |  |                     m_lastFullUpdatePosition = stationPosition; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-02-16 11:00:30 +00:00
										 |  |  |     else if (pref == Preferences::StationName) | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  |     { | 
					
						
							|  |  |  |         // Update station name
 | 
					
						
							|  |  |  |         m_antennaMapItem.setLabel(new QString(MainCore::instance()->getSettings().getStationName())); | 
					
						
							|  |  |  |         m_antennaMapItem.setText(new QString(MainCore::instance()->getSettings().getStationName())); | 
					
						
							|  |  |  |         update(m_map, &m_antennaMapItem, "Station"); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-02-16 11:00:30 +00:00
										 |  |  |     else if (pref == Preferences::MapSmoothing) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QQuickItem *item = ui->map->rootObject(); | 
					
						
							|  |  |  |         QQmlProperty::write(item, "smoothing", MainCore::instance()->getSettings().getMapSmoothing()); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2022-03-21 10:14:35 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | void MapGUI::makeUIConnections() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QObject::connect(ui->displayNames, &ButtonSwitch::clicked, this, &MapGUI::on_displayNames_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->displayAllGroundTracks, &ButtonSwitch::clicked, this, &MapGUI::on_displayAllGroundTracks_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->displaySelectedGroundTracks, &ButtonSwitch::clicked, this, &MapGUI::on_displaySelectedGroundTracks_clicked); | 
					
						
							| 
									
										
										
										
											2022-07-20 17:41:11 +01:00
										 |  |  |     QObject::connect(ui->displayMUF, &ButtonSwitch::clicked, this, &MapGUI::on_displayMUF_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->displayfoF2, &ButtonSwitch::clicked, this, &MapGUI::on_displayfoF2_clicked); | 
					
						
							| 
									
										
										
										
											2022-04-04 10:23:52 +02:00
										 |  |  |     QObject::connect(ui->find, &QLineEdit::returnPressed, this, &MapGUI::on_find_returnPressed); | 
					
						
							|  |  |  |     QObject::connect(ui->maidenhead, &QToolButton::clicked, this, &MapGUI::on_maidenhead_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->deleteAll, &QToolButton::clicked, this, &MapGUI::on_deleteAll_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->displaySettings, &QToolButton::clicked, this, &MapGUI::on_displaySettings_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->mapTypes, qOverload<int>(&QComboBox::currentIndexChanged), this, &MapGUI::on_mapTypes_currentIndexChanged); | 
					
						
							|  |  |  |     QObject::connect(ui->beacons, &QToolButton::clicked, this, &MapGUI::on_beacons_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->ibpBeacons, &QToolButton::clicked, this, &MapGUI::on_ibpBeacons_clicked); | 
					
						
							|  |  |  |     QObject::connect(ui->radiotime, &QToolButton::clicked, this, &MapGUI::on_radiotime_clicked); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2023-02-14 14:46:08 +00:00
										 |  |  | 
 |