diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp index dc917b8e..ff926a0f 100644 --- a/src/GUI/gui.cpp +++ b/src/GUI/gui.cpp @@ -121,6 +121,7 @@ GUI::GUI() updateGraphTabs(); updateStatusBarInfo(); + updateMapDEMDownloadAction(); } void GUI::createBrowser() @@ -453,11 +454,17 @@ void GUI::createActions() &MapView::useStyles); // DEM actions - _downloadDEMAction = new QAction(tr("Download DEM data"), this); - _downloadDEMAction->setMenuRole(QAction::NoRole); - _downloadDEMAction->setEnabled(false); - _downloadDEMAction->setShortcut(DOWNLOAD_DEM_SHORTCUT); - connect(_downloadDEMAction, &QAction::triggered, this, &GUI::downloadDEM); + _downloadDataDEMAction = new QAction(tr("Download data DEM"), this); + _downloadDataDEMAction->setMenuRole(QAction::NoRole); + _downloadDataDEMAction->setEnabled(false); + _downloadDataDEMAction->setShortcut(DOWNLOAD_DEM_SHORTCUT); + connect(_downloadDataDEMAction, &QAction::triggered, this, + &GUI::downloadDataDEM); + _downloadMapDEMAction = new QAction(tr("Download map DEM"), this); + _downloadMapDEMAction->setMenuRole(QAction::NoRole); + _downloadMapDEMAction->setEnabled(false); + connect(_downloadMapDEMAction, &QAction::triggered, this, + &GUI::downloadMapDEM); _showDEMTilesAction = new QAction(tr("Show local DEM tiles"), this); _showDEMTilesAction->setMenuRole(QAction::NoRole); connect(_showDEMTilesAction, &QAction::triggered, this, &GUI::showDEMTiles); @@ -715,7 +722,9 @@ void GUI::createMenus() QMenu *demMenu = menuBar()->addMenu(tr("DEM")); demMenu->addAction(_showDEMTilesAction); - demMenu->addAction(_downloadDEMAction); + demMenu->addSeparator(); + demMenu->addAction(_downloadDataDEMAction); + demMenu->addAction(_downloadMapDEMAction); demMenu->addSeparator(); demMenu->addAction(_drawHillShadingAction); @@ -1075,7 +1084,7 @@ bool GUI::loadFile(const QString &fileName, bool tryUnknown, int &showError) updateStatusBarInfo(); updateWindowTitle(); updateGraphTabs(); - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); if (_files.isEmpty()) _fileActionGroup->setEnabled(false); @@ -1156,7 +1165,7 @@ void GUI::loadData(const Data &data) } } - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); } void GUI::openPOIFile() @@ -1566,7 +1575,7 @@ void GUI::reloadFiles() else _browser->setCurrent(_files.last()); #endif // Q_OS_ANDROID - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); } void GUI::closeFiles() @@ -1599,7 +1608,7 @@ void GUI::closeAll() updateStatusBarInfo(); updateWindowTitle(); updateGraphTabs(); - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); #ifdef Q_OS_ANDROID _browser->setCurrentDir(QString()); @@ -1670,7 +1679,7 @@ void GUI::showTracks(bool show) updateStatusBarInfo(); updateGraphTabs(); - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); } void GUI::showRoutes(bool show) @@ -1682,19 +1691,19 @@ void GUI::showRoutes(bool show) updateStatusBarInfo(); updateGraphTabs(); - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); } void GUI::showWaypoints(bool show) { _mapView->showWaypoints(show); - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); } void GUI::showAreas(bool show) { _mapView->showAreas(show); - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); } void GUI::showGraphGrids(bool show) @@ -1748,6 +1757,12 @@ void GUI::loadMap() lastReady->trigger(); } +void GUI::reloadMap() +{ + _mapView->setMap(_map); + updateMapDEMDownloadAction(); +} + static MapAction *findMapAction(const QList &mapActions, const Map *map) { @@ -1951,15 +1966,33 @@ void GUI::clearMapCache() _mapView->clearMapCache(); } -void GUI::downloadDEM() +void GUI::downloadDataDEM() { - RectC br(_mapView->boundingRect()); - _demRects.append(br); - - if (!_dem->loadTiles(br) && _demRects.size() == 1) - demLoaded(); + downloadDEM(_mapView->boundingRect()); } +void GUI::downloadMapDEM() +{ + downloadDEM(_map->llBounds()); +} + +void GUI::downloadDEM(const RectC &rect) +{ + int cnt = _dem->numTiles(rect); + + if (cnt > DEM_DOWNLOAD_LIMIT) + QMessageBox::information(this, APP_NAME, + tr("DEM tiles download limit exceeded. If you really need data for " + "such a huge area, download the files manually.")); + else if (cnt < DEM_DOWNLOAD_WARNING || QMessageBox::question(this, APP_NAME, + tr("Download %1 DEM tiles?").arg(cnt)) == QMessageBox::Yes) { + _demRects.append(rect); + if (!_dem->loadTiles(rect) && _demRects.size() == 1) + demLoaded(); + } +} + + void GUI::demLoaded() { for (int i = 0; i < _demRects.size(); i++) { @@ -1970,9 +2003,14 @@ void GUI::demLoaded() } } - DEM::clearCache(); _demRects.clear(); + + DEM::lock(); + DEM::clearCache(); + DEM::unlock(); + reloadFiles(); + reloadMap(); } void GUI::showDEMTiles() @@ -2079,6 +2117,7 @@ void GUI::mapChanged(QAction *action) { _map = action->data().value(); _mapView->setMap(_map); + updateMapDEMDownloadAction(); } void GUI::nextMap() @@ -2199,12 +2238,18 @@ bool GUI::updateGraphTabs() return (hidden != _graphTabWidget->isHidden()); } -void GUI::updateDEMDownloadAction() +void GUI::updateDataDEMDownloadAction() { - _downloadDEMAction->setEnabled(!_dem->url().isEmpty() + _downloadDataDEMAction->setEnabled(!_dem->url().isEmpty() && !_dem->checkTiles(_mapView->boundingRect())); } +void GUI::updateMapDEMDownloadAction() +{ + _downloadMapDEMAction->setEnabled(!_dem->url().isEmpty() + && _map->usesDEM() && !_dem->checkTiles(_map->llBounds())); +} + void GUI::setTimeType(TimeType type) { for (int i = 0; i <_tabs.count(); i++) @@ -2976,7 +3021,9 @@ void GUI::loadOptions() Downloader::setTimeout(_options.connectionTimeout); QPixmapCache::setCacheLimit(_options.pixmapCache * 1024); + DEM::lock(); DEM::setCacheSize(_options.demCache * 1024); + DEM::unlock(); _poi->setRadius(_options.poiRadius); @@ -3101,8 +3148,11 @@ void GUI::updateOptions(const Options &options) if (options.pixmapCache != _options.pixmapCache) QPixmapCache::setCacheLimit(options.pixmapCache * 1024); - if (options.demCache != _options.demCache) + if (options.demCache != _options.demCache) { + DEM::lock(); DEM::setCacheSize(options.demCache * 1024); + DEM::unlock(); + } if (options.connectionTimeout != _options.connectionTimeout) Downloader::setTimeout(options.connectionTimeout); @@ -3121,7 +3171,7 @@ void GUI::updateOptions(const Options &options) _options = options; - updateDEMDownloadAction(); + updateDataDEMDownloadAction(); } void GUI::loadInitialMaps(const QString &selected) diff --git a/src/GUI/gui.h b/src/GUI/gui.h index 5e781e4f..1d96e311 100644 --- a/src/GUI/gui.h +++ b/src/GUI/gui.h @@ -84,7 +84,8 @@ private slots: void prevMap(); void openOptions(); void clearMapCache(); - void downloadDEM(); + void downloadDataDEM(); + void downloadMapDEM(); void showDEMTiles(); void mapChanged(QAction *action); @@ -164,7 +165,8 @@ private: void updateStatusBarInfo(); void updateWindowTitle(); bool updateGraphTabs(); - void updateDEMDownloadAction(); + void updateDataDEMDownloadAction(); + void updateMapDEMDownloadAction(); #ifndef Q_OS_ANDROID void updateRecentFiles(const QString &fileName); #endif // Q_OS_ANDROID @@ -184,12 +186,15 @@ private: void readSettings(QString &activeMap, QStringList &disabledPOIs, QStringList &recentFiles); + void reloadMap(); void loadInitialMaps(const QString &selected); void loadInitialPOIs(const QStringList &disabled); #ifndef Q_OS_ANDROID void loadRecentFiles(const QStringList &files); #endif // Q_OS_ANDROID + void downloadDEM(const RectC &rect); + void loadOptions(); void updateOptions(const Options &options); @@ -289,7 +294,8 @@ private: QAction *_useStylesAction; QAction *_showCoordinatesAction; QAction *_openOptionsAction; - QAction *_downloadDEMAction; + QAction *_downloadDataDEMAction; + QAction *_downloadMapDEMAction; QAction *_showDEMTilesAction; QAction *_drawHillShadingAction; QAction *_mapsEnd; diff --git a/src/data/demloader.cpp b/src/data/demloader.cpp index 02daf665..5bc02edf 100644 --- a/src/data/demloader.cpp +++ b/src/data/demloader.cpp @@ -4,8 +4,6 @@ #include "demloader.h" -#define DOWNLOAD_LIMIT 16 - static QList tiles(const RectC &rect) { QList list; @@ -34,6 +32,23 @@ DEMLoader::DEMLoader(const QString &dir, QObject *parent) connect(_downloader, &Downloader::finished, this, &DEMLoader::finished); } +int DEMLoader::numTiles(const RectC &rect) const +{ + QList tl(tiles(rect)); + int cnt = 0; + + for (int i = 0; i < tl.size(); i++) { + const DEM::Tile &t = tl.at(i); + QString fn(tileFile(t)); + QString zn(fn + ".zip"); + + if (!(QFileInfo::exists(zn) || QFileInfo::exists(fn))) + cnt++; + } + + return cnt; +} + bool DEMLoader::loadTiles(const RectC &rect) { QList tl(tiles(rect)); @@ -58,8 +73,8 @@ bool DEMLoader::loadTiles(const RectC &rect) dl.append(Download(url, isZip(url) ? zn : fn)); } - if (dl.size() > DOWNLOAD_LIMIT) { - qWarning("DEM download limit exceeded."); + if (dl.size() > DEM_DOWNLOAD_LIMIT) { + qWarning("DEM download limit (%d) exceeded.", DEM_DOWNLOAD_LIMIT); return false; } } diff --git a/src/data/demloader.h b/src/data/demloader.h index 84d65ac4..ce24543c 100644 --- a/src/data/demloader.h +++ b/src/data/demloader.h @@ -8,6 +8,9 @@ class RectC; +#define DEM_DOWNLOAD_WARNING 4 +#define DEM_DOWNLOAD_LIMIT 1024 + class DEMLoader : public QObject { Q_OBJECT @@ -18,6 +21,7 @@ public: void setUrl(const QString &url) {_url = url;} void setAuthorization(const Authorization &authorization); + int numTiles(const RectC &rect) const; bool loadTiles(const RectC &rect); bool checkTiles(const RectC &rect) const; diff --git a/src/map/imgmap.h b/src/map/imgmap.h index 8b96ab60..3ab2a7b4 100644 --- a/src/map/imgmap.h +++ b/src/map/imgmap.h @@ -74,6 +74,8 @@ public: bool hidpi); void unload(); + bool usesDEM() const {return true;} + bool isValid() const {return _valid;} QString errorString() const {return _errorString;} diff --git a/src/map/map.h b/src/map/map.h index e8ffa6d5..12c50338 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -57,6 +57,7 @@ public: virtual void draw(QPainter *painter, const QRectF &rect, Flags flags) = 0; virtual void clearCache() {} + virtual bool usesDEM() const {return false;} signals: void tilesLoaded(); diff --git a/src/map/mapsforgemap.h b/src/map/mapsforgemap.h index 5baf2456..4656fd6c 100644 --- a/src/map/mapsforgemap.h +++ b/src/map/mapsforgemap.h @@ -71,6 +71,8 @@ public: void draw(QPainter *painter, const QRectF &rect, Flags flags); + bool usesDEM() const {return true;} + bool isValid() const {return _data.isValid();} QString errorString() const {return _data.errorString();}