Enroute Flight Navigation
A navigation app for VFR pilots
DataManager.h
1/***************************************************************************
2 * Copyright (C) 2019-2026 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 <QJsonDocument>
24#include <QQmlEngine>
25#include <QStandardPaths>
26
27#include "GlobalObject.h"
28#include "dataManagement/Downloadable_MultiFile.h"
29#include "dataManagement/Downloadable_SingleFile.h"
30#include "units/ByteSize.h"
31
32
33namespace DataManagement {
34
71
73{
74 Q_OBJECT
75 QML_ELEMENT
76 QML_SINGLETON
77
78public:
87 explicit DataManager(QObject* parent=nullptr);
88
89 ~DataManager() override = default;
90
91 // No default constructor, important for QML singleton
92 explicit DataManager() = delete;
93
94 // factory function for QML singleton
95 static DataManagement::DataManager* create(QQmlEngine* /*unused*/, QJSEngine* /*unused*/)
96 {
98 }
99
100
101 // deferred initialization
102 void deferredInitialization() override;
103
104
105
106 //
107 // PROPERTIES
108 //
109
117 [[nodiscard]] bool appUpdateRequired() const { return m_appUpdateRequired; }
118
124 [[nodiscard]] DataManagement::Downloadable_MultiFile* aviationMaps() { return &m_aviationMaps; }
125
131 [[nodiscard]] DataManagement::Downloadable_MultiFile* baseMapsRaster() { return &m_baseMapsRaster; }
132
138 [[nodiscard]] DataManagement::Downloadable_MultiFile* baseMapsVector() { return &m_baseMapsVector; }
139
145 [[nodiscard]] DataManagement::Downloadable_MultiFile* baseMaps() { return &m_baseMaps; }
146
152 [[nodiscard]] DataManagement::Downloadable_MultiFile* databases() { return &m_databases; }
153
160 [[nodiscard]] DataManagement::Downloadable_MultiFile* items() { return &m_items; }
161
164 [[nodiscard]] DataManagement::Downloadable_SingleFile* mapList() { return &m_mapList; }
165
168 [[nodiscard]] DataManagement::Downloadable_MultiFile* mapsAndData() { return &m_mapsAndData; }
169
175 [[nodiscard]] DataManagement::Downloadable_MultiFile* mapSets() { return &m_mapSets; }
176
182 [[nodiscard]] DataManagement::Downloadable_MultiFile* terrainMaps() { return &m_terrainMaps; }
183
190 [[nodiscard]] DataManagement::Downloadable_MultiFile* vacCollections() { return &m_vacCollections; }
191
193 Q_PROPERTY(QString whatsNew READ whatsNew NOTIFY whatsNewChanged)
194 [[nodiscard]] QString whatsNew() const { return m_whatsNew; }
195
198 [[nodiscard]] Units::ByteSize whatsNewHash() const { return qHash(m_whatsNew, 0); }
199
200
201 //
202 // Methods
203 //
204
222 Q_INVOKABLE QString import(const QString& fileName, const QString& newName);
223
239 Q_INVOKABLE QString importOpenAir(const QString& fileName, const QString& newName);
240
255 Q_INVOKABLE QString importCub(const QString& fileName, const QString& newName);
256
257public slots:
264
265signals:
268
276 void error(const QString& message);
277
280
281private:
282 Q_DISABLE_COPY_MOVE(DataManager)
283
284 // Shared backend for importOpenAir and importCub: reports parse errors as
285 // an HTML string, or writes the GeoJSON document to the directory of
286 // manually imported maps. Returns an empty string on success.
287 QString saveAirspaceJson(const QJsonDocument& json, const QStringList& errors, const QString& newName);
288
289 // Clean the data directory.
290 //
291 // - delete all files with unexpected file names
292 // - earlier versions of this program constructed files with names ending in
293 // ".geojson.geojson" or ".mbtiles.mbtiles". We correct those file names
294 // here.
295 // - remove all empty sub directories
296 void cleanDataDirectory();
297
298 // This slot is called when a local file of one of the Downloadables changes
299 // content or existence. If the Downloadable in question has no file
300 // anymore, and has an invalid URL, it is then removed.
301 void onItemFileChanged();
302
303 // This slot updates the DownloadableGroups as well as the propery
304 // 'whatsNew', by reading the file 'maps.json' and by checking the data
305 // directory for locally installed, unsupported files.
306 void updateDataItemListAndWhatsNew();
307
308 // This method checks if a Downloadable item with the given url and
309 // localFileName already exists in _items. If so, it returns a pointer to
310 // that item. If not, then a Downloadable with the url and localFileName is
311 // created and added to _items. Depending on localFileName, it will also be
312 // added to _aviationMap, _baseMaps, or _databases. A pointer to that item is
313 // then returned.
314 DataManagement::Downloadable_SingleFile* createOrRecycleItem(const QUrl& url, const QString& localFileName, const QGeoRectangle& bBox);
315
316 bool m_appUpdateRequired {false};
317
318 // Full path name of data directory, without trailing slash
319 QString m_dataDirectory {QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/aviation_maps"};
320
321 // The current whats new string from _aviationMaps.
322 QString m_whatsNew;
323
324 // This Downloadable object manages the central text file that describes the
325 // remotely available aviation maps.
326 DataManagement::Downloadable_SingleFile m_mapList { QUrl(QStringLiteral("https://enroute-data.akaflieg-freiburg.de/enroute-GeoJSONv003/maps.json")), QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/maps.json" };
327
328 // List of geographic maps
329 DataManagement::Downloadable_MultiFile m_aviationMaps {DataManagement::Downloadable_MultiFile::SingleUpdate};
330 DataManagement::Downloadable_MultiFile m_baseMaps {DataManagement::Downloadable_MultiFile::SingleUpdate};
331 DataManagement::Downloadable_MultiFile m_baseMapsRaster {DataManagement::Downloadable_MultiFile::SingleUpdate};
332 DataManagement::Downloadable_MultiFile m_baseMapsVector {DataManagement::Downloadable_MultiFile::SingleUpdate};
333 DataManagement::Downloadable_MultiFile m_databases {DataManagement::Downloadable_MultiFile::SingleUpdate};
334 DataManagement::Downloadable_MultiFile m_items {DataManagement::Downloadable_MultiFile::SingleUpdate};
335 DataManagement::Downloadable_MultiFile m_mapsAndData {DataManagement::Downloadable_MultiFile::SingleUpdate};
336 DataManagement::Downloadable_MultiFile m_terrainMaps {DataManagement::Downloadable_MultiFile::SingleUpdate};
337 DataManagement::Downloadable_MultiFile m_vacCollections {DataManagement::Downloadable_MultiFile::SingleUpdate};
338
339 // List of geographic map sets
340 DataManagement::Downloadable_MultiFile m_mapSets {DataManagement::Downloadable_MultiFile::SingleUpdate};
341};
342
343} // namespace DataManagement
Manages the list of geographic maps.
Definition DataManager.h:73
Units::ByteSize whatsNewHash
Hash of the current "what's new" message.
DataManagement::Downloadable_MultiFile * baseMaps
Downloadable_MultiFile that holds all base maps.
void deferredInitialization() override
Non-constructor initialization.
DataManagement::Downloadable_MultiFile * terrainMaps
Downloadable_MultiFile that holds all terrain maps.
bool appUpdateRequired
Indiates that the app needs to be updated.
DataManagement::Downloadable_MultiFile * aviationMaps
Downloadable_MultiFile that holds all aviation maps.
DataManagement::Downloadable_MultiFile * vacCollections
Downloadable_MultiFile that holds all VAC collections.
DataManagement::Downloadable_MultiFile * databases
Downloadable_MultiFile that holds all databases.
Q_INVOKABLE QString importOpenAir(const QString &fileName, const QString &newName)
Import airspace data into the library of locally installed maps.
DataManagement::Downloadable_MultiFile * items
Downloadable_MultiFile that holds all data items.
DataManagement::Downloadable_MultiFile * baseMapsRaster
Downloadable_MultiFile that holds all base maps in raster format.
Q_INVOKABLE QString importCub(const QString &fileName, const QString &newName)
Import airspace data into the library of locally installed maps.
DataManagement::Downloadable_MultiFile * baseMapsVector
Downloadable_MultiFile that holds all base maps in vector format.
void whatsNewChanged()
Notifier signal.
DataManagement::Downloadable_MultiFile * mapsAndData
Downloadable_MultiFile that holds all the map sets and databases.
DataManager(QObject *parent=nullptr)
Standard constructor.
DataManagement::Downloadable_SingleFile * mapList
Downloadable_SingleFile that holds the list of all maps and databases.
DataManagement::Downloadable_MultiFile * mapSets
Downloadable_MultiFile that holds all map sets.
void error(const QString &message)
Error message for user.
void updateRemoteDataItemListIfOutdated()
Triggers an update of the list of remotely available data items.
QString whatsNew
Current "what's new" message.
Group of closely related downloadable items.
@ SingleUpdate
Update children that are updatable.
static Q_INVOKABLE DataManagement::DataManager * dataManager()
Pointer to appplication-wide static GeoMaps::DataManager instance.
GlobalObject(QObject *parent=nullptr)
Standard constructor.
Convenience class for size_t.
Definition ByteSize.h:37