mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-24 11:45:53 +01:00
Added support for downloading DEM tiles
This commit is contained in:
parent
94a0158243
commit
2232b011a1
@ -1,4 +1,4 @@
|
|||||||
version: 9.5.{build}
|
version: 9.6.{build}
|
||||||
|
|
||||||
configuration:
|
configuration:
|
||||||
- Release
|
- Release
|
||||||
|
@ -3,7 +3,7 @@ unix:!macx {
|
|||||||
} else {
|
} else {
|
||||||
TARGET = GPXSee
|
TARGET = GPXSee
|
||||||
}
|
}
|
||||||
VERSION = 9.5
|
VERSION = 9.6
|
||||||
|
|
||||||
QT += core \
|
QT += core \
|
||||||
gui \
|
gui \
|
||||||
@ -18,10 +18,12 @@ greaterThan(QT_MAJOR_VERSION, 5) {QT += openglwidgets}
|
|||||||
CONFIG += object_parallel_to_source
|
CONFIG += object_parallel_to_source
|
||||||
INCLUDEPATH += ./src
|
INCLUDEPATH += ./src
|
||||||
HEADERS += src/common/config.h \
|
HEADERS += src/common/config.h \
|
||||||
|
src/GUI/authenticationwidget.h \
|
||||||
src/GUI/axislabelitem.h \
|
src/GUI/axislabelitem.h \
|
||||||
src/GUI/dirselectwidget.h \
|
src/GUI/dirselectwidget.h \
|
||||||
src/GUI/flowlayout.h \
|
src/GUI/flowlayout.h \
|
||||||
src/GUI/graphicsscene.h \
|
src/GUI/graphicsscene.h \
|
||||||
|
src/GUI/infolabel.h \
|
||||||
src/GUI/mapaction.h \
|
src/GUI/mapaction.h \
|
||||||
src/GUI/mapitem.h \
|
src/GUI/mapitem.h \
|
||||||
src/GUI/marginswidget.h \
|
src/GUI/marginswidget.h \
|
||||||
@ -194,6 +196,7 @@ HEADERS += src/common/config.h \
|
|||||||
src/data/locparser.h \
|
src/data/locparser.h \
|
||||||
src/data/slfparser.h \
|
src/data/slfparser.h \
|
||||||
src/data/dem.h \
|
src/data/dem.h \
|
||||||
|
src/data/demloader.h \
|
||||||
src/common/polygon.h \
|
src/common/polygon.h \
|
||||||
src/data/area.h \
|
src/data/area.h \
|
||||||
src/map/obliquestereographic.h \
|
src/map/obliquestereographic.h \
|
||||||
@ -231,9 +234,11 @@ HEADERS += src/common/config.h \
|
|||||||
src/map/worldfilemap.h
|
src/map/worldfilemap.h
|
||||||
|
|
||||||
SOURCES += src/main.cpp \
|
SOURCES += src/main.cpp \
|
||||||
|
src/GUI/authenticationwidget.cpp \
|
||||||
src/GUI/axislabelitem.cpp \
|
src/GUI/axislabelitem.cpp \
|
||||||
src/GUI/dirselectwidget.cpp \
|
src/GUI/dirselectwidget.cpp \
|
||||||
src/GUI/flowlayout.cpp \
|
src/GUI/flowlayout.cpp \
|
||||||
|
src/GUI/infolabel.cpp \
|
||||||
src/GUI/mapitem.cpp \
|
src/GUI/mapitem.cpp \
|
||||||
src/GUI/marginswidget.cpp \
|
src/GUI/marginswidget.cpp \
|
||||||
src/GUI/markerinfoitem.cpp \
|
src/GUI/markerinfoitem.cpp \
|
||||||
@ -377,6 +382,7 @@ SOURCES += src/main.cpp \
|
|||||||
src/data/locparser.cpp \
|
src/data/locparser.cpp \
|
||||||
src/data/slfparser.cpp \
|
src/data/slfparser.cpp \
|
||||||
src/data/dem.cpp \
|
src/data/dem.cpp \
|
||||||
|
src/data/demloader.cpp \
|
||||||
src/map/obliquestereographic.cpp \
|
src/map/obliquestereographic.cpp \
|
||||||
src/GUI/coordinatesitem.cpp \
|
src/GUI/coordinatesitem.cpp \
|
||||||
src/map/rmap.cpp \
|
src/map/rmap.cpp \
|
||||||
|
@ -43,6 +43,8 @@
|
|||||||
<file alias="view-filter@2x.png">icons/GUI/view-filter@2x.png</file>
|
<file alias="view-filter@2x.png">icons/GUI/view-filter@2x.png</file>
|
||||||
<file alias="applications-internet_32.png">icons/GUI/applications-internet_32.png</file>
|
<file alias="applications-internet_32.png">icons/GUI/applications-internet_32.png</file>
|
||||||
<file alias="applications-internet_32@2x.png">icons/GUI/applications-internet_32@2x.png</file>
|
<file alias="applications-internet_32@2x.png">icons/GUI/applications-internet_32@2x.png</file>
|
||||||
|
<file alias="view-grid.png">icons/GUI/view-grid.png</file>
|
||||||
|
<file alias="view-grid@2x.png">icons/GUI/view-grid@2x.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
|
||||||
<!-- POI icons for default IMG map style -->
|
<!-- POI icons for default IMG map style -->
|
||||||
|
BIN
icons/GUI/view-grid.png
Normal file
BIN
icons/GUI/view-grid.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
icons/GUI/view-grid@2x.png
Normal file
BIN
icons/GUI/view-grid@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
@ -9,7 +9,7 @@ Unicode true
|
|||||||
; The name of the installer
|
; The name of the installer
|
||||||
Name "GPXSee"
|
Name "GPXSee"
|
||||||
; Program version
|
; Program version
|
||||||
!define VERSION "9.5"
|
!define VERSION "9.6"
|
||||||
|
|
||||||
; The file to write
|
; The file to write
|
||||||
OutFile "GPXSee-${VERSION}.exe"
|
OutFile "GPXSee-${VERSION}.exe"
|
||||||
|
@ -9,7 +9,7 @@ Unicode true
|
|||||||
; The name of the installer
|
; The name of the installer
|
||||||
Name "GPXSee"
|
Name "GPXSee"
|
||||||
; Program version
|
; Program version
|
||||||
!define VERSION "9.5"
|
!define VERSION "9.6"
|
||||||
|
|
||||||
; The file to write
|
; The file to write
|
||||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||||
|
14
src/GUI/authenticationwidget.cpp
Normal file
14
src/GUI/authenticationwidget.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include <QFormLayout>
|
||||||
|
#include "authenticationwidget.h"
|
||||||
|
|
||||||
|
AuthenticationWidget::AuthenticationWidget(QWidget *parent) : QWidget(parent)
|
||||||
|
{
|
||||||
|
_username = new QLineEdit();
|
||||||
|
_password = new QLineEdit();
|
||||||
|
|
||||||
|
QFormLayout *layout = new QFormLayout();
|
||||||
|
layout->addRow(tr("Username:"), _username);
|
||||||
|
layout->addRow(tr("Password:"), _password);
|
||||||
|
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
24
src/GUI/authenticationwidget.h
Normal file
24
src/GUI/authenticationwidget.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef AUTHENTICATIONWIDGET_H
|
||||||
|
#define AUTHENTICATIONWIDGET_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QLineEdit>
|
||||||
|
|
||||||
|
class AuthenticationWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
AuthenticationWidget(QWidget *parent = 0);
|
||||||
|
|
||||||
|
QString username() const {return _username->text();}
|
||||||
|
QString password() const {return _password->text();}
|
||||||
|
|
||||||
|
void setUsername(const QString &username) {_username->setText(username);}
|
||||||
|
void setPassword(const QString &password) {_password->setText(password);}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineEdit *_username, *_password;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // AUTHENTICATIONWIDGET_H
|
@ -29,6 +29,7 @@
|
|||||||
#include "common/downloader.h"
|
#include "common/downloader.h"
|
||||||
#include "data/data.h"
|
#include "data/data.h"
|
||||||
#include "data/poi.h"
|
#include "data/poi.h"
|
||||||
|
#include "data/demloader.h"
|
||||||
#include "map/maplist.h"
|
#include "map/maplist.h"
|
||||||
#include "map/emptymap.h"
|
#include "map/emptymap.h"
|
||||||
#include "map/crs.h"
|
#include "map/crs.h"
|
||||||
@ -62,6 +63,8 @@ GUI::GUI()
|
|||||||
TreeNode<POIAction*> poiActions;
|
TreeNode<POIAction*> poiActions;
|
||||||
|
|
||||||
_poi = new POI(this);
|
_poi = new POI(this);
|
||||||
|
_dem = new DEMLoader(ProgramPaths::demDir(true), this);
|
||||||
|
connect(_dem, &DEMLoader::finished, this, &GUI::demLoaded);
|
||||||
|
|
||||||
createMapView();
|
createMapView();
|
||||||
createGraphTabs();
|
createGraphTabs();
|
||||||
@ -402,6 +405,12 @@ void GUI::createActions(TreeNode<MapAction*> &mapActions,
|
|||||||
_showMarkerCoordinatesAction->setCheckable(true);
|
_showMarkerCoordinatesAction->setCheckable(true);
|
||||||
_showMarkerCoordinatesAction->setActionGroup(markerInfoGroup);
|
_showMarkerCoordinatesAction->setActionGroup(markerInfoGroup);
|
||||||
|
|
||||||
|
// DEM actions
|
||||||
|
_downloadDEMAction = new QAction(tr("Download DEM data"), this);
|
||||||
|
_downloadDEMAction->setMenuRole(QAction::NoRole);
|
||||||
|
_downloadDEMAction->setEnabled(false);
|
||||||
|
connect(_downloadDEMAction, &QAction::triggered, this, &GUI::downloadDEM);
|
||||||
|
|
||||||
// Graph actions
|
// Graph actions
|
||||||
_showGraphsAction = new QAction(QIcon(SHOW_GRAPHS_ICON), tr("Show graphs"),
|
_showGraphsAction = new QAction(QIcon(SHOW_GRAPHS_ICON), tr("Show graphs"),
|
||||||
this);
|
this);
|
||||||
@ -585,18 +594,6 @@ void GUI::createMenus(const TreeNode<MapAction*> &mapActions,
|
|||||||
graphMenu->addSeparator();
|
graphMenu->addSeparator();
|
||||||
graphMenu->addAction(_showGraphsAction);
|
graphMenu->addAction(_showGraphsAction);
|
||||||
|
|
||||||
_poiMenu = menuBar()->addMenu(tr("&POI"));
|
|
||||||
createPOINodeMenu(poiActions, _poiMenu);
|
|
||||||
_poisEnd = _poiMenu->addSeparator();
|
|
||||||
_poiMenu->addAction(_openPOIAction);
|
|
||||||
_poiMenu->addAction(_selectAllPOIAction);
|
|
||||||
_poiMenu->addAction(_unselectAllPOIAction);
|
|
||||||
_poiMenu->addSeparator();
|
|
||||||
_poiMenu->addAction(_showPOILabelsAction);
|
|
||||||
_poiMenu->addAction(_overlapPOIAction);
|
|
||||||
_poiMenu->addSeparator();
|
|
||||||
_poiMenu->addAction(_showPOIAction);
|
|
||||||
|
|
||||||
QMenu *dataMenu = menuBar()->addMenu(tr("&Data"));
|
QMenu *dataMenu = menuBar()->addMenu(tr("&Data"));
|
||||||
dataMenu->addAction(_showWaypointLabelsAction);
|
dataMenu->addAction(_showWaypointLabelsAction);
|
||||||
dataMenu->addAction(_showRouteWaypointsAction);
|
dataMenu->addAction(_showRouteWaypointsAction);
|
||||||
@ -612,6 +609,22 @@ void GUI::createMenus(const TreeNode<MapAction*> &mapActions,
|
|||||||
dataMenu->addAction(_showAreasAction);
|
dataMenu->addAction(_showAreasAction);
|
||||||
dataMenu->addAction(_showWaypointsAction);
|
dataMenu->addAction(_showWaypointsAction);
|
||||||
|
|
||||||
|
_poiMenu = menuBar()->addMenu(tr("&POI"));
|
||||||
|
createPOINodeMenu(poiActions, _poiMenu);
|
||||||
|
_poisEnd = _poiMenu->addSeparator();
|
||||||
|
_poiMenu->addAction(_openPOIAction);
|
||||||
|
_poiMenu->addAction(_selectAllPOIAction);
|
||||||
|
_poiMenu->addAction(_unselectAllPOIAction);
|
||||||
|
_poiMenu->addSeparator();
|
||||||
|
_poiMenu->addAction(_showPOILabelsAction);
|
||||||
|
_poiMenu->addAction(_overlapPOIAction);
|
||||||
|
_poiMenu->addSeparator();
|
||||||
|
_poiMenu->addAction(_showPOIAction);
|
||||||
|
|
||||||
|
QMenu *demMenu = menuBar()->addMenu(tr("DEM"));
|
||||||
|
demMenu->addSeparator();
|
||||||
|
demMenu->addAction(_downloadDEMAction);
|
||||||
|
|
||||||
QMenu *settingsMenu = menuBar()->addMenu(tr("&Settings"));
|
QMenu *settingsMenu = menuBar()->addMenu(tr("&Settings"));
|
||||||
QMenu *timeMenu = settingsMenu->addMenu(tr("Time"));
|
QMenu *timeMenu = settingsMenu->addMenu(tr("Time"));
|
||||||
timeMenu->addAction(_totalTimeAction);
|
timeMenu->addAction(_totalTimeAction);
|
||||||
@ -1052,6 +1065,16 @@ void GUI::openOptions()
|
|||||||
if (options.poiRadius != _options.poiRadius)
|
if (options.poiRadius != _options.poiRadius)
|
||||||
_poi->setRadius(options.poiRadius);
|
_poi->setRadius(options.poiRadius);
|
||||||
|
|
||||||
|
if (options.demURL != _options.demURL)
|
||||||
|
_dem->setUrl(options.demURL);
|
||||||
|
if (options.demAuthorization != _options.demAuthorization
|
||||||
|
|| options.demUsername != _options.demUsername
|
||||||
|
|| options.demPassword != _options.demPassword)
|
||||||
|
_dem->setAuthorization(options.demAuthorization
|
||||||
|
? Authorization(options.demUsername, options.demPassword)
|
||||||
|
: Authorization());
|
||||||
|
_downloadDEMAction->setEnabled(!options.demURL.isEmpty());
|
||||||
|
|
||||||
if (options.pixmapCache != _options.pixmapCache)
|
if (options.pixmapCache != _options.pixmapCache)
|
||||||
QPixmapCache::setCacheLimit(options.pixmapCache * 1024);
|
QPixmapCache::setCacheLimit(options.pixmapCache * 1024);
|
||||||
|
|
||||||
@ -1688,6 +1711,26 @@ void GUI::clearMapCache()
|
|||||||
_mapView->clearMapCache();
|
_mapView->clearMapCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GUI::downloadDEM()
|
||||||
|
{
|
||||||
|
_demRect = _mapView->boundingRect();
|
||||||
|
|
||||||
|
if (_dem->loadTiles(_demRect))
|
||||||
|
_downloadDEMAction->setEnabled(false);
|
||||||
|
else
|
||||||
|
demLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GUI::demLoaded()
|
||||||
|
{
|
||||||
|
if (!_dem->checkTiles(_demRect))
|
||||||
|
QMessageBox::warning(this, APP_NAME,
|
||||||
|
tr("Could not download all required DEM files."));
|
||||||
|
|
||||||
|
reloadFiles();
|
||||||
|
_downloadDEMAction->setEnabled(!_options.demURL.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
void GUI::updateStatusBarInfo()
|
void GUI::updateStatusBarInfo()
|
||||||
{
|
{
|
||||||
if (_files.count() == 0)
|
if (_files.count() == 0)
|
||||||
@ -2236,6 +2279,14 @@ void GUI::writeSettings()
|
|||||||
settings.setValue(USE_SEGMENTS_SETTING, _options.useSegments);
|
settings.setValue(USE_SEGMENTS_SETTING, _options.useSegments);
|
||||||
if (_options.poiRadius != POI_RADIUS_DEFAULT)
|
if (_options.poiRadius != POI_RADIUS_DEFAULT)
|
||||||
settings.setValue(POI_RADIUS_SETTING, _options.poiRadius);
|
settings.setValue(POI_RADIUS_SETTING, _options.poiRadius);
|
||||||
|
if (_options.demURL != DEM_URL_DEFAULT)
|
||||||
|
settings.setValue(DEM_URL_SETTING, _options.demURL);
|
||||||
|
if (_options.demAuthorization != DEM_AUTH_DEFAULT)
|
||||||
|
settings.setValue(DEM_AUTH_SETTING, _options.demAuthorization);
|
||||||
|
if (_options.demUsername != DEM_USERNAME_DEFAULT)
|
||||||
|
settings.setValue(DEM_USERNAME_SETTING, _options.demUsername);
|
||||||
|
if (_options.demPassword != DEM_PASSWORD_DEFAULT)
|
||||||
|
settings.setValue(DEM_PASSWORD_SETTING, _options.demPassword);
|
||||||
if (_options.useOpenGL != USE_OPENGL_DEFAULT)
|
if (_options.useOpenGL != USE_OPENGL_DEFAULT)
|
||||||
settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL);
|
settings.setValue(USE_OPENGL_SETTING, _options.useOpenGL);
|
||||||
if (_options.enableHTTP2 != ENABLE_HTTP2_DEFAULT)
|
if (_options.enableHTTP2 != ENABLE_HTTP2_DEFAULT)
|
||||||
@ -2547,6 +2598,13 @@ void GUI::readSettings()
|
|||||||
PAUSE_INTERVAL_DEFAULT).toInt();
|
PAUSE_INTERVAL_DEFAULT).toInt();
|
||||||
_options.poiRadius = settings.value(POI_RADIUS_SETTING, POI_RADIUS_DEFAULT)
|
_options.poiRadius = settings.value(POI_RADIUS_SETTING, POI_RADIUS_DEFAULT)
|
||||||
.toInt();
|
.toInt();
|
||||||
|
_options.demURL = settings.value(DEM_URL_SETTING, DEM_URL_DEFAULT).toString();
|
||||||
|
_options.demAuthorization = settings.value(DEM_AUTH_SETTING,
|
||||||
|
DEM_AUTH_DEFAULT).toBool();
|
||||||
|
_options.demUsername = settings.value(DEM_USERNAME_SETTING,
|
||||||
|
DEM_USERNAME_DEFAULT).toString();
|
||||||
|
_options.demPassword = settings.value(DEM_PASSWORD_SETTING,
|
||||||
|
DEM_PASSWORD_DEFAULT).toString();
|
||||||
_options.useOpenGL = settings.value(USE_OPENGL_SETTING, USE_OPENGL_DEFAULT)
|
_options.useOpenGL = settings.value(USE_OPENGL_SETTING, USE_OPENGL_DEFAULT)
|
||||||
.toBool();
|
.toBool();
|
||||||
_options.enableHTTP2 = settings.value(ENABLE_HTTP2_SETTING,
|
_options.enableHTTP2 = settings.value(ENABLE_HTTP2_SETTING,
|
||||||
@ -2641,6 +2699,13 @@ void GUI::readSettings()
|
|||||||
|
|
||||||
_poi->setRadius(_options.poiRadius);
|
_poi->setRadius(_options.poiRadius);
|
||||||
|
|
||||||
|
_dem->setUrl(_options.demURL);
|
||||||
|
if (_options.demAuthorization)
|
||||||
|
_dem->setAuthorization(Authorization(_options.demUsername,
|
||||||
|
_options.demPassword));
|
||||||
|
if (!_options.demURL.isEmpty())
|
||||||
|
_downloadDEMAction->setEnabled(true);
|
||||||
|
|
||||||
QPixmapCache::setCacheLimit(_options.pixmapCache * 1024);
|
QPixmapCache::setCacheLimit(_options.pixmapCache * 1024);
|
||||||
|
|
||||||
settings.endGroup();
|
settings.endGroup();
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <QDate>
|
#include <QDate>
|
||||||
#include <QPrinter>
|
#include <QPrinter>
|
||||||
#include "common/treenode.h"
|
#include "common/treenode.h"
|
||||||
|
#include "common/rectc.h"
|
||||||
#include "data/graph.h"
|
#include "data/graph.h"
|
||||||
#include "units.h"
|
#include "units.h"
|
||||||
#include "timetype.h"
|
#include "timetype.h"
|
||||||
@ -32,6 +33,7 @@ class QScreen;
|
|||||||
class MapAction;
|
class MapAction;
|
||||||
class POIAction;
|
class POIAction;
|
||||||
class Data;
|
class Data;
|
||||||
|
class DEMLoader;
|
||||||
|
|
||||||
class GUI : public QMainWindow
|
class GUI : public QMainWindow
|
||||||
{
|
{
|
||||||
@ -71,6 +73,7 @@ private slots:
|
|||||||
void prevMap();
|
void prevMap();
|
||||||
void openOptions();
|
void openOptions();
|
||||||
void clearMapCache();
|
void clearMapCache();
|
||||||
|
void downloadDEM();
|
||||||
|
|
||||||
void mapChanged(QAction *action);
|
void mapChanged(QAction *action);
|
||||||
void graphChanged(int);
|
void graphChanged(int);
|
||||||
@ -102,6 +105,8 @@ private slots:
|
|||||||
void mapLoadedDir();
|
void mapLoadedDir();
|
||||||
void mapInitialized();
|
void mapInitialized();
|
||||||
|
|
||||||
|
void demLoaded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef QPair<QDateTime, QDateTime> DateTimeRange;
|
typedef QPair<QDateTime, QDateTime> DateTimeRange;
|
||||||
|
|
||||||
@ -224,6 +229,7 @@ private:
|
|||||||
QAction *_showTicksAction;
|
QAction *_showTicksAction;
|
||||||
QAction *_showCoordinatesAction;
|
QAction *_showCoordinatesAction;
|
||||||
QAction *_openOptionsAction;
|
QAction *_openOptionsAction;
|
||||||
|
QAction *_downloadDEMAction;
|
||||||
QAction *_mapsEnd;
|
QAction *_mapsEnd;
|
||||||
QAction *_poisEnd;
|
QAction *_poisEnd;
|
||||||
|
|
||||||
@ -239,6 +245,7 @@ private:
|
|||||||
|
|
||||||
POI *_poi;
|
POI *_poi;
|
||||||
Map *_map;
|
Map *_map;
|
||||||
|
DEMLoader *_dem;
|
||||||
|
|
||||||
FileBrowser *_browser;
|
FileBrowser *_browser;
|
||||||
QList<QString> _files;
|
QList<QString> _files;
|
||||||
@ -260,6 +267,8 @@ private:
|
|||||||
QString _dataDir, _mapDir, _poiDir;
|
QString _dataDir, _mapDir, _poiDir;
|
||||||
|
|
||||||
Units _units;
|
Units _units;
|
||||||
|
|
||||||
|
RectC _demRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GUI_H
|
#endif // GUI_H
|
||||||
|
@ -26,5 +26,6 @@
|
|||||||
#define PRINT_EXPORT_ICON ":/document-print_32.png"
|
#define PRINT_EXPORT_ICON ":/document-print_32.png"
|
||||||
#define DATA_ICON ":/view-filter.png"
|
#define DATA_ICON ":/view-filter.png"
|
||||||
#define MAPS_ICON ":/applications-internet_32.png"
|
#define MAPS_ICON ":/applications-internet_32.png"
|
||||||
|
#define DEM_ICON ":/view-grid.png"
|
||||||
|
|
||||||
#endif /* ICONS_H */
|
#endif /* ICONS_H */
|
||||||
|
10
src/GUI/infolabel.cpp
Normal file
10
src/GUI/infolabel.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#include "infolabel.h"
|
||||||
|
|
||||||
|
InfoLabel::InfoLabel(const QString &text, QWidget *parent)
|
||||||
|
: QLabel(text, parent)
|
||||||
|
{
|
||||||
|
QFont f(font());
|
||||||
|
f.setPointSize(f.pointSize() - 1);
|
||||||
|
setWordWrap(true);
|
||||||
|
setFont(f);
|
||||||
|
}
|
12
src/GUI/infolabel.h
Normal file
12
src/GUI/infolabel.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef INFOLABEL_H
|
||||||
|
#define INFOLABEL_H
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
class InfoLabel : public QLabel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InfoLabel(const QString &text, QWidget *parent = 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // INFOLABEL_H
|
@ -88,6 +88,8 @@ public:
|
|||||||
void clearMapCache();
|
void clearMapCache();
|
||||||
void fitContentToSize();
|
void fitContentToSize();
|
||||||
|
|
||||||
|
RectC boundingRect() const {return _tr | _rr | _wr | _ar;}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showMap(bool show);
|
void showMap(bool show);
|
||||||
void showPOI(bool show);
|
void showPOI(bool show);
|
||||||
|
@ -14,12 +14,14 @@
|
|||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
#include <QButtonGroup>
|
#include <QButtonGroup>
|
||||||
#include "icons.h"
|
#include "icons.h"
|
||||||
|
#include "infolabel.h"
|
||||||
#include "colorbox.h"
|
#include "colorbox.h"
|
||||||
#include "stylecombobox.h"
|
#include "stylecombobox.h"
|
||||||
#include "oddspinbox.h"
|
#include "oddspinbox.h"
|
||||||
#include "percentslider.h"
|
#include "percentslider.h"
|
||||||
#include "projectioncombobox.h"
|
#include "projectioncombobox.h"
|
||||||
#include "dirselectwidget.h"
|
#include "dirselectwidget.h"
|
||||||
|
#include "authenticationwidget.h"
|
||||||
#include "optionsdialog.h"
|
#include "optionsdialog.h"
|
||||||
|
|
||||||
|
|
||||||
@ -53,17 +55,11 @@ QWidget *OptionsDialog::createMapPage()
|
|||||||
_inputProjection->setCurrentIndex(_inputProjection->findData(
|
_inputProjection->setCurrentIndex(_inputProjection->findData(
|
||||||
_options.inputProjection));
|
_options.inputProjection));
|
||||||
|
|
||||||
QLabel *inInfo = new QLabel(tr("Select the proper projection of maps"
|
InfoLabel *inInfo = new InfoLabel(tr("Select the proper projection of maps"
|
||||||
" without a projection definition (JNX, KMZ and world file maps)."));
|
" without a projection definition (JNX, KMZ and world file maps)."));
|
||||||
QLabel *outInfo = new QLabel(tr("Select the desired projection of vector"
|
InfoLabel *outInfo = new InfoLabel(tr("Select the desired projection of"
|
||||||
" maps (IMG and Mapsforge maps). The projection must be valid for"
|
" vector maps (IMG and Mapsforge maps). The projection must be valid for"
|
||||||
" the whole map area."));
|
" the whole map area."));
|
||||||
QFont f = inInfo->font();
|
|
||||||
f.setPointSize(f.pointSize() - 1);
|
|
||||||
inInfo->setWordWrap(true);
|
|
||||||
outInfo->setWordWrap(true);
|
|
||||||
inInfo->setFont(f);
|
|
||||||
outInfo->setFont(f);
|
|
||||||
|
|
||||||
_hidpi = new QRadioButton(tr("High-resolution"));
|
_hidpi = new QRadioButton(tr("High-resolution"));
|
||||||
_lodpi = new QRadioButton(tr("Standard"));
|
_lodpi = new QRadioButton(tr("Standard"));
|
||||||
@ -71,14 +67,10 @@ QWidget *OptionsDialog::createMapPage()
|
|||||||
_hidpi->setChecked(true);
|
_hidpi->setChecked(true);
|
||||||
else
|
else
|
||||||
_lodpi->setChecked(true);
|
_lodpi->setChecked(true);
|
||||||
QLabel *lhi = new QLabel(tr("Non-HiDPI maps are loaded as HiDPI maps. "
|
InfoLabel *lhi = new InfoLabel(tr("Non-HiDPI maps are loaded as HiDPI maps. "
|
||||||
"The map is sharp but map objects are small/hard to read."));
|
"The map is sharp but map objects are small/hard to read."));
|
||||||
QLabel *llo = new QLabel(tr("Non-HiDPI maps are loaded such as they are. "
|
InfoLabel *llo = new InfoLabel(tr("Non-HiDPI maps are loaded such as they are. "
|
||||||
"Map objects have the expected size but the map is blurry."));
|
"Map objects have the expected size but the map is blurry."));
|
||||||
lhi->setWordWrap(true);
|
|
||||||
llo->setWordWrap(true);
|
|
||||||
lhi->setFont(f);
|
|
||||||
llo->setFont(f);
|
|
||||||
|
|
||||||
QVBoxLayout *inLayout = new QVBoxLayout();
|
QVBoxLayout *inLayout = new QVBoxLayout();
|
||||||
inLayout->addWidget(_inputProjection);
|
inLayout->addWidget(_inputProjection);
|
||||||
@ -576,6 +568,42 @@ QWidget *OptionsDialog::createPOIPage()
|
|||||||
return poiPage;
|
return poiPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *OptionsDialog::createDEMPage()
|
||||||
|
{
|
||||||
|
_demURL = new QLineEdit();
|
||||||
|
_demURL->setText(_options.demURL);
|
||||||
|
_demAuth = new AuthenticationWidget();
|
||||||
|
_demAuth->setUsername(_options.demUsername);
|
||||||
|
_demAuth->setPassword(_options.demPassword);
|
||||||
|
_demAuth->setEnabled(_options.demAuthorization);
|
||||||
|
|
||||||
|
QCheckBox *useAuth = new QCheckBox(tr("Use HTTP authentication"));
|
||||||
|
useAuth->setChecked(_demAuth->isEnabled());
|
||||||
|
connect(useAuth, &QRadioButton::toggled, _demAuth,
|
||||||
|
&AuthenticationWidget::setEnabled);
|
||||||
|
|
||||||
|
InfoLabel *info = new InfoLabel(tr("Use $lat and $lon for NYY/SYY and EXXX/WXXX in the URL."));
|
||||||
|
|
||||||
|
QFormLayout *urlLayout = new QFormLayout();
|
||||||
|
urlLayout->addRow(tr("URL:"), _demURL);
|
||||||
|
urlLayout->addRow(info);
|
||||||
|
|
||||||
|
QVBoxLayout *sourceLayout = new QVBoxLayout();
|
||||||
|
sourceLayout->addLayout(urlLayout);
|
||||||
|
sourceLayout->addSpacing(10);
|
||||||
|
sourceLayout->addWidget(useAuth);
|
||||||
|
sourceLayout->addWidget(_demAuth);
|
||||||
|
sourceLayout->addStretch();
|
||||||
|
|
||||||
|
QWidget *sourceTab = new QWidget();
|
||||||
|
sourceTab->setLayout(sourceLayout);
|
||||||
|
|
||||||
|
QTabWidget *demPage = new QTabWidget();
|
||||||
|
demPage->addTab(sourceTab, tr("Source"));
|
||||||
|
|
||||||
|
return demPage;
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *OptionsDialog::createExportPage()
|
QWidget *OptionsDialog::createExportPage()
|
||||||
{
|
{
|
||||||
_wysiwyg = new QRadioButton(tr("WYSIWYG"));
|
_wysiwyg = new QRadioButton(tr("WYSIWYG"));
|
||||||
@ -584,17 +612,11 @@ QWidget *OptionsDialog::createExportPage()
|
|||||||
_hires->setChecked(true);
|
_hires->setChecked(true);
|
||||||
else
|
else
|
||||||
_wysiwyg->setChecked(true);
|
_wysiwyg->setChecked(true);
|
||||||
QLabel *lw = new QLabel(tr("The printed area is approximately the display"
|
InfoLabel *lw = new InfoLabel(tr("The printed area is approximately the "
|
||||||
" area. The map zoom level does not change."));
|
"display area. The map zoom level does not change."));
|
||||||
QLabel *lh = new QLabel(tr("The zoom level will be changed so that"
|
InfoLabel *lh = new InfoLabel(tr("The zoom level will be changed so that"
|
||||||
" the whole content (tracks/waypoints) fits to the printed area and"
|
" the whole content (tracks/waypoints) fits to the printed area and"
|
||||||
" the map resolution is as close as possible to the print resolution."));
|
" the map resolution is as close as possible to the print resolution."));
|
||||||
QFont f = lw->font();
|
|
||||||
f.setPointSize(f.pointSize() - 1);
|
|
||||||
lw->setWordWrap(true);
|
|
||||||
lh->setWordWrap(true);
|
|
||||||
lw->setFont(f);
|
|
||||||
lh->setFont(f);
|
|
||||||
|
|
||||||
QVBoxLayout *modeTabLayout = new QVBoxLayout();
|
QVBoxLayout *modeTabLayout = new QVBoxLayout();
|
||||||
modeTabLayout->addWidget(_wysiwyg);
|
modeTabLayout->addWidget(_wysiwyg);
|
||||||
@ -691,12 +713,8 @@ QWidget *OptionsDialog::createSystemPage()
|
|||||||
_poiPath = new DirSelectWidget();
|
_poiPath = new DirSelectWidget();
|
||||||
_poiPath->setDir(_options.poiPath);
|
_poiPath->setDir(_options.poiPath);
|
||||||
|
|
||||||
QLabel *info = new QLabel(tr("Select the initial paths of the file open"
|
InfoLabel *info = new InfoLabel(tr("Select the initial paths of the file"
|
||||||
" dialogues. Leave the field empty for the system default."));
|
" open dialogues. Leave the field empty for the system default."));
|
||||||
QFont f = info->font();
|
|
||||||
f.setPointSize(f.pointSize() - 1);
|
|
||||||
info->setFont(f);
|
|
||||||
info->setWordWrap(true);
|
|
||||||
|
|
||||||
QFormLayout *pathsFormLayout = new QFormLayout();
|
QFormLayout *pathsFormLayout = new QFormLayout();
|
||||||
pathsFormLayout->addRow(tr("Data:"), _dataPath);
|
pathsFormLayout->addRow(tr("Data:"), _dataPath);
|
||||||
@ -705,8 +723,8 @@ QWidget *OptionsDialog::createSystemPage()
|
|||||||
|
|
||||||
QWidget *pathsTab = new QWidget();
|
QWidget *pathsTab = new QWidget();
|
||||||
QVBoxLayout *pathsTabLayout = new QVBoxLayout();
|
QVBoxLayout *pathsTabLayout = new QVBoxLayout();
|
||||||
pathsTabLayout->addWidget(info);
|
|
||||||
pathsTabLayout->addLayout(pathsFormLayout);
|
pathsTabLayout->addLayout(pathsFormLayout);
|
||||||
|
pathsTabLayout->addWidget(info);
|
||||||
pathsTabLayout->addStretch();
|
pathsTabLayout->addStretch();
|
||||||
pathsTab->setLayout(pathsTabLayout);
|
pathsTab->setLayout(pathsTabLayout);
|
||||||
|
|
||||||
@ -725,6 +743,7 @@ OptionsDialog::OptionsDialog(Options &options, Units units, QWidget *parent)
|
|||||||
pages->addWidget(createMapPage());
|
pages->addWidget(createMapPage());
|
||||||
pages->addWidget(createDataPage());
|
pages->addWidget(createDataPage());
|
||||||
pages->addWidget(createPOIPage());
|
pages->addWidget(createPOIPage());
|
||||||
|
pages->addWidget(createDEMPage());
|
||||||
pages->addWidget(createExportPage());
|
pages->addWidget(createExportPage());
|
||||||
pages->addWidget(createSystemPage());
|
pages->addWidget(createSystemPage());
|
||||||
|
|
||||||
@ -735,6 +754,7 @@ OptionsDialog::OptionsDialog(Options &options, Units units, QWidget *parent)
|
|||||||
new QListWidgetItem(QIcon(MAPS_ICON), tr("Maps"), menu);
|
new QListWidgetItem(QIcon(MAPS_ICON), tr("Maps"), menu);
|
||||||
new QListWidgetItem(QIcon(DATA_ICON), tr("Data"), menu);
|
new QListWidgetItem(QIcon(DATA_ICON), tr("Data"), menu);
|
||||||
new QListWidgetItem(QIcon(POI_ICON), tr("POI"), menu);
|
new QListWidgetItem(QIcon(POI_ICON), tr("POI"), menu);
|
||||||
|
new QListWidgetItem(QIcon(DEM_ICON), tr("DEM"), menu);
|
||||||
new QListWidgetItem(QIcon(PRINT_EXPORT_ICON), tr("Print & Export"),
|
new QListWidgetItem(QIcon(PRINT_EXPORT_ICON), tr("Print & Export"),
|
||||||
menu);
|
menu);
|
||||||
new QListWidgetItem(QIcon(SYSTEM_ICON), tr("System"), menu);
|
new QListWidgetItem(QIcon(SYSTEM_ICON), tr("System"), menu);
|
||||||
@ -831,6 +851,11 @@ void OptionsDialog::accept()
|
|||||||
if (qAbs(poiRadius - _options.poiRadius) > 0.01)
|
if (qAbs(poiRadius - _options.poiRadius) > 0.01)
|
||||||
_options.poiRadius = poiRadius;
|
_options.poiRadius = poiRadius;
|
||||||
|
|
||||||
|
_options.demURL = _demURL->text();
|
||||||
|
_options.demAuthorization = _demAuth->isEnabled();
|
||||||
|
_options.demUsername = _demAuth->username();
|
||||||
|
_options.demPassword = _demAuth->password();
|
||||||
|
|
||||||
_options.useOpenGL = _useOpenGL->isChecked();
|
_options.useOpenGL = _useOpenGL->isChecked();
|
||||||
_options.enableHTTP2 = _enableHTTP2->isChecked();
|
_options.enableHTTP2 = _enableHTTP2->isChecked();
|
||||||
_options.pixmapCache = _pixmapCache->value();
|
_options.pixmapCache = _pixmapCache->value();
|
||||||
|
@ -6,18 +6,19 @@
|
|||||||
#include "units.h"
|
#include "units.h"
|
||||||
#include "timezoneinfo.h"
|
#include "timezoneinfo.h"
|
||||||
|
|
||||||
class ColorBox;
|
|
||||||
class StyleComboBox;
|
|
||||||
class OddSpinBox;
|
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
class QDoubleSpinBox;
|
class QDoubleSpinBox;
|
||||||
class QComboBox;
|
class QComboBox;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
class QRadioButton;
|
class QRadioButton;
|
||||||
|
class QLineEdit;
|
||||||
|
class ColorBox;
|
||||||
|
class StyleComboBox;
|
||||||
|
class OddSpinBox;
|
||||||
class PercentSlider;
|
class PercentSlider;
|
||||||
class ProjectionComboBox;
|
class ProjectionComboBox;
|
||||||
class DirSelectWidget;
|
class DirSelectWidget;
|
||||||
|
class AuthenticationWidget;
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
// Appearance
|
// Appearance
|
||||||
@ -61,6 +62,11 @@ struct Options {
|
|||||||
bool useSegments;
|
bool useSegments;
|
||||||
// POI
|
// POI
|
||||||
int poiRadius;
|
int poiRadius;
|
||||||
|
// DEM
|
||||||
|
QString demURL;
|
||||||
|
QString demUsername;
|
||||||
|
QString demPassword;
|
||||||
|
bool demAuthorization;
|
||||||
// System
|
// System
|
||||||
bool useOpenGL;
|
bool useOpenGL;
|
||||||
bool enableHTTP2;
|
bool enableHTTP2;
|
||||||
@ -100,6 +106,7 @@ private:
|
|||||||
QWidget *createPOIPage();
|
QWidget *createPOIPage();
|
||||||
QWidget *createSystemPage();
|
QWidget *createSystemPage();
|
||||||
QWidget *createExportPage();
|
QWidget *createExportPage();
|
||||||
|
QWidget *createDEMPage();
|
||||||
|
|
||||||
Options &_options;
|
Options &_options;
|
||||||
|
|
||||||
@ -153,6 +160,9 @@ private:
|
|||||||
QCheckBox *_useSegments;
|
QCheckBox *_useSegments;
|
||||||
// POI
|
// POI
|
||||||
QDoubleSpinBox *_poiRadius;
|
QDoubleSpinBox *_poiRadius;
|
||||||
|
// DEM
|
||||||
|
QLineEdit *_demURL;
|
||||||
|
AuthenticationWidget *_demAuth;
|
||||||
// System
|
// System
|
||||||
QSpinBox *_pixmapCache;
|
QSpinBox *_pixmapCache;
|
||||||
QSpinBox *_connectionTimeout;
|
QSpinBox *_connectionTimeout;
|
||||||
|
@ -173,6 +173,14 @@
|
|||||||
#define USE_SEGMENTS_DEFAULT true
|
#define USE_SEGMENTS_DEFAULT true
|
||||||
#define POI_RADIUS_SETTING "poiRadius"
|
#define POI_RADIUS_SETTING "poiRadius"
|
||||||
#define POI_RADIUS_DEFAULT (int)(IMPERIAL_UNITS() ? MIINM : KMINM)
|
#define POI_RADIUS_DEFAULT (int)(IMPERIAL_UNITS() ? MIINM : KMINM)
|
||||||
|
#define DEM_URL_SETTING "demURL"
|
||||||
|
#define DEM_URL_DEFAULT ""
|
||||||
|
#define DEM_AUTH_SETTING "demAuthentication"
|
||||||
|
#define DEM_AUTH_DEFAULT false
|
||||||
|
#define DEM_USERNAME_SETTING "demUsername"
|
||||||
|
#define DEM_USERNAME_DEFAULT ""
|
||||||
|
#define DEM_PASSWORD_SETTING "demPassword"
|
||||||
|
#define DEM_PASSWORD_DEFAULT ""
|
||||||
#define USE_OPENGL_SETTING "useOpenGL"
|
#define USE_OPENGL_SETTING "useOpenGL"
|
||||||
#define USE_OPENGL_DEFAULT false
|
#define USE_OPENGL_DEFAULT false
|
||||||
#define ENABLE_HTTP2_SETTING "enableHTTP2"
|
#define ENABLE_HTTP2_SETTING "enableHTTP2"
|
||||||
|
@ -77,7 +77,7 @@ QNetworkAccessManager *Downloader::_manager = 0;
|
|||||||
int Downloader::_timeout = 30;
|
int Downloader::_timeout = 30;
|
||||||
bool Downloader::_http2 = true;
|
bool Downloader::_http2 = true;
|
||||||
|
|
||||||
bool Downloader::doDownload(const Download &dl, const QByteArray &authorization)
|
bool Downloader::doDownload(const Download &dl, const Authorization &auth)
|
||||||
{
|
{
|
||||||
const QUrl &url = dl.url();
|
const QUrl &url = dl.url();
|
||||||
|
|
||||||
@ -98,8 +98,8 @@ bool Downloader::doDownload(const Download &dl, const QByteArray &authorization)
|
|||||||
QNetworkRequest::NoLessSafeRedirectPolicy);
|
QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||||
request.setAttribute(ATTR_HTTP2_ALLOWED, QVariant(_http2));
|
request.setAttribute(ATTR_HTTP2_ALLOWED, QVariant(_http2));
|
||||||
request.setRawHeader("User-Agent", USER_AGENT);
|
request.setRawHeader("User-Agent", USER_AGENT);
|
||||||
if (!authorization.isNull())
|
if (!auth.isNull())
|
||||||
request.setRawHeader("Authorization", authorization);
|
request.setRawHeader("Authorization", auth.header());
|
||||||
|
|
||||||
QFile *file = new QFile(tmpName(dl.file()));
|
QFile *file = new QFile(tmpName(dl.file()));
|
||||||
if (!file->open(QIODevice::WriteOnly)) {
|
if (!file->open(QIODevice::WriteOnly)) {
|
||||||
@ -182,7 +182,7 @@ bool Downloader::get(const QList<Download> &list,
|
|||||||
bool finishEmitted = false;
|
bool finishEmitted = false;
|
||||||
|
|
||||||
for (int i = 0; i < list.count(); i++)
|
for (int i = 0; i < list.count(); i++)
|
||||||
finishEmitted |= doDownload(list.at(i), authorization.header());
|
finishEmitted |= doDownload(list.at(i), authorization);
|
||||||
|
|
||||||
return finishEmitted;
|
return finishEmitted;
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ public:
|
|||||||
Authorization() {}
|
Authorization() {}
|
||||||
Authorization(const QString &username, const QString &password);
|
Authorization(const QString &username, const QString &password);
|
||||||
|
|
||||||
|
bool isNull() const {return _header.isNull();}
|
||||||
const QByteArray &header() const {return _header;}
|
const QByteArray &header() const {return _header;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -79,7 +80,7 @@ private:
|
|||||||
class ReplyTimeout;
|
class ReplyTimeout;
|
||||||
|
|
||||||
void insertError(const QUrl &url, QNetworkReply::NetworkError error);
|
void insertError(const QUrl &url, QNetworkReply::NetworkError error);
|
||||||
bool doDownload(const Download &dl, const QByteArray &authorization);
|
bool doDownload(const Download &dl, const Authorization &auth);
|
||||||
void downloadFinished(QNetworkReply *reply);
|
void downloadFinished(QNetworkReply *reply);
|
||||||
void readData(QNetworkReply *reply);
|
void readData(QNetworkReply *reply);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <private/qzipreader_p.h>
|
#include <private/qzipreader_p.h>
|
||||||
#include "common/coordinates.h"
|
#include "common/rectc.h"
|
||||||
#include "dem.h"
|
#include "dem.h"
|
||||||
|
|
||||||
|
|
||||||
@ -66,19 +66,26 @@ static qreal height(const Coordinates &c, const QByteArray *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QString DEM::_dir;
|
QString DEM::Tile::latStr() const
|
||||||
QCache<DEM::Key, QByteArray> DEM::_data;
|
|
||||||
|
|
||||||
QString DEM::baseName(const Key &key)
|
|
||||||
{
|
{
|
||||||
const char ns = (key.lat() >= 0) ? 'N' : 'S';
|
const char ns = (_lat >= 0) ? 'N' : 'S';
|
||||||
const char ew = (key.lon() >= 0) ? 'E' : 'W';
|
return QString("%1%2").arg(ns).arg(qAbs(_lat), 2, 10, QChar('0'));
|
||||||
|
|
||||||
return QString("%1%2%3%4.hgt").arg(ns)
|
|
||||||
.arg(qAbs(key.lat()), 2, 10, QChar('0')).arg(ew)
|
|
||||||
.arg(qAbs(key.lon()), 3, 10, QChar('0'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString DEM::Tile::lonStr() const
|
||||||
|
{
|
||||||
|
const char ew = (_lon >= 0) ? 'E' : 'W';
|
||||||
|
return QString("%1%2").arg(ew).arg(qAbs(_lon), 3, 10, QChar('0'));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DEM::Tile::baseName() const
|
||||||
|
{
|
||||||
|
return QString("%1%2.hgt").arg(latStr(), lonStr());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DEM::_dir;
|
||||||
|
QCache<DEM::Tile, QByteArray> DEM::_data;
|
||||||
|
|
||||||
QString DEM::fileName(const QString &baseName)
|
QString DEM::fileName(const QString &baseName)
|
||||||
{
|
{
|
||||||
return QDir(_dir).absoluteFilePath(baseName);
|
return QDir(_dir).absoluteFilePath(baseName);
|
||||||
@ -87,6 +94,7 @@ QString DEM::fileName(const QString &baseName)
|
|||||||
void DEM::setDir(const QString &path)
|
void DEM::setDir(const QString &path)
|
||||||
{
|
{
|
||||||
_dir = path;
|
_dir = path;
|
||||||
|
_data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal DEM::elevation(const Coordinates &c)
|
qreal DEM::elevation(const Coordinates &c)
|
||||||
@ -94,11 +102,11 @@ qreal DEM::elevation(const Coordinates &c)
|
|||||||
if (_dir.isEmpty())
|
if (_dir.isEmpty())
|
||||||
return NAN;
|
return NAN;
|
||||||
|
|
||||||
Key k(qFloor(c.lon()), qFloor(c.lat()));
|
Tile tile(qFloor(c.lon()), qFloor(c.lat()));
|
||||||
|
|
||||||
QByteArray *ba = _data[k];
|
QByteArray *ba = _data[tile];
|
||||||
if (!ba) {
|
if (!ba) {
|
||||||
QString bn(baseName(k));
|
QString bn(tile.baseName());
|
||||||
QString fn(fileName(bn));
|
QString fn(fileName(bn));
|
||||||
QString zn(fn + ".zip");
|
QString zn(fn + ".zip");
|
||||||
|
|
||||||
@ -106,22 +114,30 @@ qreal DEM::elevation(const Coordinates &c)
|
|||||||
QZipReader zip(zn, QIODevice::ReadOnly);
|
QZipReader zip(zn, QIODevice::ReadOnly);
|
||||||
ba = new QByteArray(zip.fileData(bn));
|
ba = new QByteArray(zip.fileData(bn));
|
||||||
qreal ele = height(c, ba);
|
qreal ele = height(c, ba);
|
||||||
_data.insert(k, ba);
|
_data.insert(tile, ba);
|
||||||
return ele;
|
return ele;
|
||||||
} else {
|
} else {
|
||||||
QFile file(fn);
|
QFile file(fn);
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
qWarning("%s: %s", qPrintable(file.fileName()),
|
qWarning("%s: %s", qPrintable(file.fileName()),
|
||||||
qPrintable(file.errorString()));
|
qPrintable(file.errorString()));
|
||||||
_data.insert(k, new QByteArray());
|
_data.insert(tile, new QByteArray());
|
||||||
return NAN;
|
return NAN;
|
||||||
} else {
|
} else {
|
||||||
ba = new QByteArray(file.readAll());
|
ba = new QByteArray(file.readAll());
|
||||||
qreal ele = height(c, ba);
|
qreal ele = height(c, ba);
|
||||||
_data.insert(k, ba);
|
_data.insert(tile, ba);
|
||||||
return ele;
|
return ele;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
return height(c, ba);
|
return height(c, ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
QDebug operator<<(QDebug dbg, const DEM::Tile &tile)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "Tile(" << tile.baseName() << ")";
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
#endif // QT_NO_DEBUG
|
||||||
|
@ -8,18 +8,23 @@
|
|||||||
|
|
||||||
class QString;
|
class QString;
|
||||||
class Coordinates;
|
class Coordinates;
|
||||||
|
class RectC;
|
||||||
|
|
||||||
class DEM
|
class DEM
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
class Key {
|
|
||||||
public:
|
public:
|
||||||
Key(int lon, int lat) : _lon(lon), _lat(lat) {}
|
class Tile {
|
||||||
|
public:
|
||||||
|
Tile(int lon, int lat) : _lon(lon), _lat(lat) {}
|
||||||
|
|
||||||
int lon() const {return _lon;}
|
int lon() const {return _lon;}
|
||||||
int lat() const {return _lat;}
|
int lat() const {return _lat;}
|
||||||
|
|
||||||
bool operator==(const Key &other) const
|
QString lonStr() const;
|
||||||
|
QString latStr() const;
|
||||||
|
QString baseName() const;
|
||||||
|
|
||||||
|
bool operator==(const Tile &other) const
|
||||||
{
|
{
|
||||||
return (_lon == other._lon && _lat == other._lat);
|
return (_lon == other._lon && _lat == other._lat);
|
||||||
}
|
}
|
||||||
@ -28,22 +33,23 @@ private:
|
|||||||
int _lon, _lat;
|
int _lon, _lat;
|
||||||
};
|
};
|
||||||
|
|
||||||
static QString baseName(const Key &key);
|
|
||||||
static QString fileName(const QString &baseName);
|
|
||||||
|
|
||||||
static QString _dir;
|
|
||||||
static QCache<Key, QByteArray> _data;
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void setDir(const QString &path);
|
static void setDir(const QString &path);
|
||||||
static qreal elevation(const Coordinates &c);
|
static qreal elevation(const Coordinates &c);
|
||||||
|
|
||||||
friend HASH_T qHash(const Key &key);
|
private:
|
||||||
|
static QString fileName(const QString &baseName);
|
||||||
|
|
||||||
|
static QString _dir;
|
||||||
|
static QCache<Tile, QByteArray> _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline HASH_T qHash(const DEM::Key &key)
|
inline HASH_T qHash(const DEM::Tile &tile)
|
||||||
{
|
{
|
||||||
return (qHash(key.lon()) ^ qHash(key.lat()));
|
return (qHash(tile.lon()) ^ qHash(tile.lat()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
QDebug operator<<(QDebug dbg, const DEM::Tile &tile);
|
||||||
|
#endif // QT_NO_DEBUG
|
||||||
|
|
||||||
#endif // DEM_H
|
#endif // DEM_H
|
||||||
|
102
src/data/demloader.cpp
Normal file
102
src/data/demloader.cpp
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#include <QtMath>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include "common/rectc.h"
|
||||||
|
#include "demloader.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define DOWNLOAD_LIMIT 32
|
||||||
|
|
||||||
|
static QList<DEM::Tile> tiles(const RectC &rect)
|
||||||
|
{
|
||||||
|
QList<DEM::Tile> list;
|
||||||
|
|
||||||
|
if (!rect.isValid())
|
||||||
|
return list;
|
||||||
|
|
||||||
|
for (int i = qFloor(rect.top()); i >= qFloor(rect.bottom()); i--)
|
||||||
|
for (int j = qFloor(rect.left()); j <= qFloor(rect.right()); j++)
|
||||||
|
list.append(DEM::Tile(j, i));
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isZip(const QUrl &url)
|
||||||
|
{
|
||||||
|
QFileInfo fi(url.fileName());
|
||||||
|
return (fi.suffix().toLower() == "zip");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DEMLoader::DEMLoader(const QString &dir, QObject *parent)
|
||||||
|
: QObject(parent), _dir(dir)
|
||||||
|
{
|
||||||
|
_downloader = new Downloader(this);
|
||||||
|
connect(_downloader, &Downloader::finished, this, &DEMLoader::finished);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DEMLoader::loadTiles(const RectC &rect)
|
||||||
|
{
|
||||||
|
QList<DEM::Tile> tl(tiles(rect));
|
||||||
|
QList<Download> dl;
|
||||||
|
|
||||||
|
/* Create the user DEM dir only when a download is requested as it will
|
||||||
|
override the global DEM dir. */
|
||||||
|
if (!QDir().mkpath(_dir)) {
|
||||||
|
qWarning("%s: %s", qPrintable(_dir), "Error creating DEM directory");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* This also clears the DEM data cache which is necessary to use the data
|
||||||
|
from the downloaded DEM tiles. */
|
||||||
|
DEM::setDir(_dir);
|
||||||
|
|
||||||
|
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(zn).exists() || QFileInfo(fn).exists())) {
|
||||||
|
QUrl url(tileUrl(t));
|
||||||
|
dl.append(Download(url, isZip(url) ? zn : fn));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dl.size() > DOWNLOAD_LIMIT) {
|
||||||
|
qWarning("DEM download limit exceeded. Limit/requested: %u/%u.",
|
||||||
|
DOWNLOAD_LIMIT, dl.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _downloader->get(dl, _authorization);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DEMLoader::checkTiles(const RectC &rect) const
|
||||||
|
{
|
||||||
|
QList<DEM::Tile> tl(tiles(rect));
|
||||||
|
|
||||||
|
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(zn).exists() || QFileInfo(fn).exists()))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QUrl DEMLoader::tileUrl(const DEM::Tile &tile) const
|
||||||
|
{
|
||||||
|
QString url(_url);
|
||||||
|
|
||||||
|
url.replace("$lon", tile.lonStr());
|
||||||
|
url.replace("$lat", tile.latStr());
|
||||||
|
|
||||||
|
return QUrl(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString DEMLoader::tileFile(const DEM::Tile &tile) const
|
||||||
|
{
|
||||||
|
return _dir + QLatin1Char('/') + tile.baseName();
|
||||||
|
}
|
37
src/data/demloader.h
Normal file
37
src/data/demloader.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef DEMLOADER_H
|
||||||
|
#define DEMLOADER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "common/downloader.h"
|
||||||
|
#include "dem.h"
|
||||||
|
|
||||||
|
class RectC;
|
||||||
|
|
||||||
|
class DEMLoader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
DEMLoader(const QString &dir, QObject *parent = 0);
|
||||||
|
|
||||||
|
void setUrl(const QString &url) {_url = url;}
|
||||||
|
void setAuthorization(const Authorization &authorization)
|
||||||
|
{_authorization = authorization;}
|
||||||
|
|
||||||
|
bool loadTiles(const RectC &rect);
|
||||||
|
bool checkTiles(const RectC &rect) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QUrl tileUrl(const DEM::Tile &tile) const;
|
||||||
|
QString tileFile(const DEM::Tile &tile) const;
|
||||||
|
|
||||||
|
Downloader *_downloader;
|
||||||
|
QString _url;
|
||||||
|
QString _dir;
|
||||||
|
Authorization _authorization;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DEMLOADER_H
|
Loading…
Reference in New Issue
Block a user