Enroute Flight Navigation
A navigation app for VFR pilots
GeoMapProvider.h
1/***************************************************************************
2 * Copyright (C) 2019-2024 by Stefan Kebekus *
3 * stefan.kebekus@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#pragma once
22
23#include <QCache>
24#include <QFuture>
25#include <QGeoRectangle>
26#include <QImage>
27#include <QProperty>
28#include <QQmlEngine>
29#include <QStandardPaths>
30#include <QTemporaryFile>
31#include <QTimer>
32
33#include "Airspace.h"
34#include "GlobalObject.h"
35#include "TileServer.h"
36#include "Waypoint.h"
37#include "fileFormats/MBTILES.h"
38
39using namespace Qt::Literals::StringLiterals;
40
41
42namespace GeoMaps
43{
44
63
65{
66 Q_OBJECT
67 QML_ELEMENT
68 QML_SINGLETON
69
70public:
77 explicit GeoMapProvider(QObject *parent = nullptr);
78
79 // No default constructor, important for QML singleton
80 explicit GeoMapProvider() = delete;
81
82 // deferred initialization
83 void deferredInitialization() override;
84
85 // factory function for QML singleton
86 static GeoMaps::GeoMapProvider* create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/)
87 {
89 }
90
92 ~GeoMapProvider() override = default;
93
94
95
96 //
97 // Properties
98 //
99
105
106
111 Q_PROPERTY(QString copyrightNotice READ copyrightNotice CONSTANT)
112
123
129 Q_PROPERTY(QByteArray geoJSON READ geoJSON NOTIFY geoJSONChanged)
130
137 Q_PROPERTY(QString serverUrl READ serverUrl NOTIFY serverUrlChanged)
138
148 Q_PROPERTY(QString styleFileURL READ styleFileURL NOTIFY styleFileURLChanged)
149
151 Q_PROPERTY(QList<QSharedPointer<FileFormats::MBTILES>> terrainMapTiles READ terrainMapTiles NOTIFY terrainMapTilesChanged)
152
158 Q_PROPERTY(QList<GeoMaps::Waypoint> waypoints READ waypoints NOTIFY waypointsChanged)
159
160
161
162 //
163 // Getter Methods
164 //
165
170 [[nodiscard]] QStringList availableRasterMaps() const
171 {
172 return m_availableRasterMaps.value();
173 }
174
179 [[nodiscard]] QBindable<QStringList> bindableAvailableRasterMaps() const
180 {
181 return &m_availableRasterMaps;
182 }
183
188 [[nodiscard]] static QString copyrightNotice();
189
194 [[nodiscard]] QString currentRasterMap() const {return m_currentRasterMap.value();}
195
200 [[nodiscard]] QBindable<QString> bindableCurrentRasterMap() const {return &m_currentRasterMap;}
201
206 [[nodiscard]] QByteArray geoJSON();
207
212 [[nodiscard]] QString serverUrl() {return m_tileServer.serverUrl();}
213
218 [[nodiscard]] QString styleFileURL();
219
224 [[nodiscard]] QList<QSharedPointer<FileFormats::MBTILES>> terrainMapTiles() const
225 {
226 return m_terrainMapTiles;
227 }
228
233 [[nodiscard]] QList<Waypoint> waypoints();
234
235
236
237 //
238 // Setter Methods
239 //
240
245 void setCurrentRasterMap(const QString& mapName);
246
247
248
249 //
250 // Methods
251 //
252
257 [[nodiscard]] Q_INVOKABLE QList<GeoMaps::Airspace> airspaces();
258
267 [[nodiscard]] Q_INVOKABLE QVariantList airspaces(const QGeoCoordinate &position);
268
281 [[nodiscard]] Q_INVOKABLE GeoMaps::Waypoint closestWaypoint(QGeoCoordinate position, const QGeoCoordinate &distPosition);
282
290 [[nodiscard]] Q_INVOKABLE static GeoMaps::Waypoint createWaypoint()
291 {
292 return {};
293 }
294
302 [[nodiscard]] Q_INVOKABLE Units::Distance terrainElevationAMSL(const QGeoCoordinate& coordinate);
303
308 [[nodiscard]] Q_INVOKABLE static QByteArray emptyGeoJSON();
309
318 [[nodiscard]] Q_INVOKABLE QVector<GeoMaps::Waypoint> filteredWaypoints(const QString& filter);
319
326 [[nodiscard]] Q_INVOKABLE Waypoint findByID(const QString& icaoID);
327
338 [[nodiscard]] Q_INVOKABLE QList<GeoMaps::Waypoint> nearbyWaypoints(const QGeoCoordinate& position, const QString& type);
339
340
341signals:
344
347
350
353
356
357private:
358 Q_DISABLE_COPY_MOVE(GeoMapProvider)
359
360 // This slot is called every time the the set of aviation maps qchanges. It
361 // fills the aviation data cache.
362 void onAviationMapsChanged();
363
364 // This slot is called every time the the set of MBTile files changes. It
365 // sets up the tile server to and generates a new style file.
366 void onMBTILESChanged();
367
368 // Interal function that does most of the work for aviationMapsChanged()
369 // emits geoJSONChanged() when done. This function is meant to be run in a
370 // separate thread.
371 void fillAviationDataCache(QStringList JSONFileNames, Units::Distance airspaceAltitudeLimit, bool hideGlidingSectors);
372
373 // Caches used to speed up the method simplifySpecialChars
374 QRegularExpression specialChars{QStringLiteral("[^a-zA-Z0-9]")};
375 QHash<QString, QString> simplifySpecialChars_cache;
376
377 // This is the path under which map tiles are available on the _tileServer.
378 // This is set to a random number that changes every time the set of MBTile
379 // files changes
380 QString _currentBaseMapPath;
381 QString _currentTerrainMapPath;
382
383 // Tile Server
384 TileServer m_tileServer;
385
386 // Temporary file that holds the current style file
387 QPointer<QTemporaryFile> m_styleFile;
388
389 //
390 // Aviation Data Cache
391 //
392 QFuture<void> _aviationDataCacheFuture; // Future; indicates if fillAviationDataCache() is currently running
393 QTimer _aviationDataCacheTimer; // Timer used to start another run of fillAviationDataCache()
394
395 //
396 // MBTILES
397 //
398 QList<QSharedPointer<FileFormats::MBTILES>> m_baseMapVectorTiles;
399 QProperty<QList<QSharedPointer<FileFormats::MBTILES>>> m_baseMapRasterTiles;
400 QList<QSharedPointer<FileFormats::MBTILES>> m_terrainMapTiles;
401
402 QProperty<QStringList> m_availableRasterMaps;
403 QStringList computeAvailableRasterMaps();
404
405 QProperty<QString> m_currentRasterMap {u"non-empty place holder"_s};
406 QPropertyNotifier m_currentRasterMapNotifier; // Used to save the currentRasterMap
407
408 // The data in this group is accessed by several threads. The following
409 // classes (whose names ends in an underscore) are therefore protected by
410 // this mutex.
411 QMutex m_aviationDataMutex;
412 QByteArray _combinedGeoJSON_; // Cache: GeoJSON
413 QList<Waypoint> _waypoints_; // Cache: Waypoints
414 QList<Airspace> _airspaces_; // Cache: Airspaces
415
416 // TerrainImageCache
417 QCache<qint64,QImage> terrainTileCache {6}; // Hold 6 tiles, roughly 1.2MB
418
419 // GeoJSON file
420 QString geoJSONCache {QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + u"/aviationData.json"_s};
421};
422
423} // namespace GeoMaps
Provides geographic information.
QBindable< QString > bindableCurrentRasterMap() const
Getter function for the property with the same name.
Q_INVOKABLE QVariantList airspaces(const QGeoCoordinate &position)
List of airspaces at a given location.
QList< Waypoint > waypoints()
Getter function for the property with the same name.
Q_INVOKABLE QList< GeoMaps::Waypoint > nearbyWaypoints(const QGeoCoordinate &position, const QString &type)
void terrainMapTilesChanged()
Notification signal for the property with the same name.
QList< QSharedPointer< FileFormats::MBTILES > > terrainMapTiles() const
Getter function for the property with the same name.
QBindable< QStringList > bindableAvailableRasterMaps() const
Getter function for the property with the same name.
QString serverUrl()
Getter function for the property with the same name.
QStringList availableRasterMaps
Available Raster Maps.
Q_INVOKABLE Waypoint findByID(const QString &icaoID)
QString currentRasterMap
Current Raster Map.
QString currentRasterMap() const
Getter function for the property with the same name.
static Q_INVOKABLE GeoMaps::Waypoint createWaypoint()
Create invalid waypoint.
~GeoMapProvider() override=default
Destructor.
Q_INVOKABLE QVector< GeoMaps::Waypoint > filteredWaypoints(const QString &filter)
Waypoints containing a given substring.
static Q_INVOKABLE QByteArray emptyGeoJSON()
Create empty GeoJSON document.
Q_INVOKABLE QList< GeoMaps::Airspace > airspaces()
List of all airspaces known to Enroute Flight Navigation.
QByteArray geoJSON
Union of all aviation maps in GeoJSON format.
void styleFileURLChanged()
Notification signal for the property with the same name.
Q_INVOKABLE Units::Distance terrainElevationAMSL(const QGeoCoordinate &coordinate)
Elevation of terrain at a given coordinate, above sea level.
QString serverUrl
URL under which this server is presently reachable.
GeoMapProvider(QObject *parent=nullptr)
Creates a new GeoMap provider.
void geoJSONChanged()
Notification signal for the property with the same name.
QString styleFileURL()
Getter function for the property with the same name.
QString copyrightNotice
Copyright notice for the map.
QList< GeoMaps::Waypoint > waypoints
Waypoints.
void serverUrlChanged()
Notification signal for the property with the same name.
void deferredInitialization() override
Non-constructor initialization.
void waypointsChanged()
Notification signal for the property with the same name.
QString styleFileURL
URL where a style file for the base map can be retrieved.
void setCurrentRasterMap(const QString &mapName)
Setter function for the property with the same name.
QListQSharedPointer< FileFormats::MBTILES > terrainMapTiles
List of terrain map MBTILES.
QByteArray geoJSON()
Getter function for the property with the same name.
Q_INVOKABLE GeoMaps::Waypoint closestWaypoint(QGeoCoordinate position, const QGeoCoordinate &distPosition)
Find closest waypoint to a given position.
static QString copyrightNotice()
Getter function for the property with the same name.
HTTP server for mapbox' MBTiles files.
Definition TileServer.h:59
Waypoint, such as an airfield, a navaid station or a reporting point.
Definition Waypoint.h:41
static Q_INVOKABLE GeoMaps::GeoMapProvider * geoMapProvider()
Pointer to appplication-wide static GeoMaps::GeoMapProvider instance.
GlobalObject(QObject *parent=nullptr)
Standard constructor.
Convenience class for distance computations.
Definition Distance.h:35