diff --git a/gpxsee.qrc b/gpxsee.qrc
index 90a57df4..a96a5601 100644
--- a/gpxsee.qrc
+++ b/gpxsee.qrc
@@ -1,24 +1,44 @@
-
- icons/dialog-close.png
- icons/document-open.png
- icons/document-print.png
- icons/document-export.png
- icons/flag.png
- icons/gpxsee.png
- icons/application-exit.png
- icons/applications-internet.png
- icons/view-refresh.png
- icons/arrow-left.png
- icons/arrow-right.png
- icons/arrow-left-double.png
- icons/arrow-right-double.png
- icons/view-fullscreen.png
- icons/office-chart-line.png
- icons/preferences-desktop-display.png
- icons/flag_48.png
- icons/system-run.png
- icons/document-print-preview.png
- icons/view-filter.png
-
+
+ icons/dialog-close.png
+ icons/dialog-close@2x.png
+ icons/document-open.png
+ icons/document-open@2x.png
+ icons/document-print.png
+ icons/document-print@2x.png
+ icons/document-export.png
+ icons/document-export@2x.png
+ icons/flag.png
+ icons/flag@2x.png
+ icons/gpxsee.png
+ icons/gpxsee@2x.png
+ icons/application-exit.png
+ icons/application-exit@2x.png
+ icons/applications-internet.png
+ icons/applications-internet@2x.png
+ icons/view-refresh.png
+ icons/view-refresh@2x.png
+ icons/arrow-left.png
+ icons/arrow-left@2x.png
+ icons/arrow-right.png
+ icons/arrow-right@2x.png
+ icons/arrow-left-double.png
+ icons/arrow-left-double@2x.png
+ icons/arrow-right-double.png
+ icons/arrow-right-double@2x.png
+ icons/view-fullscreen.png
+ icons/view-fullscreen@2x.png
+ icons/office-chart-line.png
+ icons/office-chart-line@2x.png
+ icons/format-stroke-color.png
+ icons/format-stroke-color@2x.png
+ icons/flag_32.png
+ icons/flag_32@2x.png
+ icons/preferences-system.png
+ icons/preferences-system@2x.png
+ icons/document-print_32.png
+ icons/document-print_32@2x.png
+ icons/view-filter.png
+ icons/view-filter@2x.png
+
diff --git a/icons/application-exit@2x.png b/icons/application-exit@2x.png
new file mode 100644
index 00000000..294f8fd5
Binary files /dev/null and b/icons/application-exit@2x.png differ
diff --git a/icons/applications-internet@2x.png b/icons/applications-internet@2x.png
new file mode 100644
index 00000000..e47b65a4
Binary files /dev/null and b/icons/applications-internet@2x.png differ
diff --git a/icons/arrow-left-double@2x.png b/icons/arrow-left-double@2x.png
new file mode 100644
index 00000000..95324cdb
Binary files /dev/null and b/icons/arrow-left-double@2x.png differ
diff --git a/icons/arrow-left@2x.png b/icons/arrow-left@2x.png
new file mode 100644
index 00000000..a8f1ff49
Binary files /dev/null and b/icons/arrow-left@2x.png differ
diff --git a/icons/arrow-right-double@2x.png b/icons/arrow-right-double@2x.png
new file mode 100644
index 00000000..1729db7d
Binary files /dev/null and b/icons/arrow-right-double@2x.png differ
diff --git a/icons/arrow-right@2x.png b/icons/arrow-right@2x.png
new file mode 100644
index 00000000..4c77710c
Binary files /dev/null and b/icons/arrow-right@2x.png differ
diff --git a/icons/dialog-close@2x.png b/icons/dialog-close@2x.png
new file mode 100644
index 00000000..acc22a5c
Binary files /dev/null and b/icons/dialog-close@2x.png differ
diff --git a/icons/document-export@2x.png b/icons/document-export@2x.png
new file mode 100644
index 00000000..13814cf8
Binary files /dev/null and b/icons/document-export@2x.png differ
diff --git a/icons/document-open.png b/icons/document-open.png
index bc8cface..317a3577 100644
Binary files a/icons/document-open.png and b/icons/document-open.png differ
diff --git a/icons/document-open@2x.png b/icons/document-open@2x.png
new file mode 100644
index 00000000..0300ab3d
Binary files /dev/null and b/icons/document-open@2x.png differ
diff --git a/icons/document-print-preview.png b/icons/document-print-preview.png
deleted file mode 100644
index 614ffc46..00000000
Binary files a/icons/document-print-preview.png and /dev/null differ
diff --git a/icons/document-print@2x.png b/icons/document-print@2x.png
new file mode 100644
index 00000000..ada04cd4
Binary files /dev/null and b/icons/document-print@2x.png differ
diff --git a/icons/document-print_32.png b/icons/document-print_32.png
new file mode 100644
index 00000000..d6555042
Binary files /dev/null and b/icons/document-print_32.png differ
diff --git a/icons/document-print_32@2x.png b/icons/document-print_32@2x.png
new file mode 100644
index 00000000..8dc77a8d
Binary files /dev/null and b/icons/document-print_32@2x.png differ
diff --git a/icons/flag@2x.png b/icons/flag@2x.png
new file mode 100644
index 00000000..5ee8f729
Binary files /dev/null and b/icons/flag@2x.png differ
diff --git a/icons/flag_32.png b/icons/flag_32.png
new file mode 100644
index 00000000..51e1c8f8
Binary files /dev/null and b/icons/flag_32.png differ
diff --git a/icons/flag_32@2x.png b/icons/flag_32@2x.png
new file mode 100644
index 00000000..fa889df2
Binary files /dev/null and b/icons/flag_32@2x.png differ
diff --git a/icons/flag_48.png b/icons/flag_48.png
deleted file mode 100644
index 8d450bf2..00000000
Binary files a/icons/flag_48.png and /dev/null differ
diff --git a/icons/format-stroke-color.png b/icons/format-stroke-color.png
new file mode 100644
index 00000000..05c34b9a
Binary files /dev/null and b/icons/format-stroke-color.png differ
diff --git a/icons/format-stroke-color@2x.png b/icons/format-stroke-color@2x.png
new file mode 100644
index 00000000..7274212d
Binary files /dev/null and b/icons/format-stroke-color@2x.png differ
diff --git a/icons/gpxsee@2x.png b/icons/gpxsee@2x.png
new file mode 100644
index 00000000..6a4bf228
Binary files /dev/null and b/icons/gpxsee@2x.png differ
diff --git a/icons/office-chart-line@2x.png b/icons/office-chart-line@2x.png
new file mode 100644
index 00000000..0cbf5994
Binary files /dev/null and b/icons/office-chart-line@2x.png differ
diff --git a/icons/preferences-desktop-display.png b/icons/preferences-desktop-display.png
deleted file mode 100644
index 3334a429..00000000
Binary files a/icons/preferences-desktop-display.png and /dev/null differ
diff --git a/icons/preferences-system.png b/icons/preferences-system.png
new file mode 100644
index 00000000..2afbd23c
Binary files /dev/null and b/icons/preferences-system.png differ
diff --git a/icons/preferences-system@2x.png b/icons/preferences-system@2x.png
new file mode 100644
index 00000000..9ea5cec4
Binary files /dev/null and b/icons/preferences-system@2x.png differ
diff --git a/icons/system-run.png b/icons/system-run.png
deleted file mode 100644
index e3f93dd4..00000000
Binary files a/icons/system-run.png and /dev/null differ
diff --git a/icons/view-filter.png b/icons/view-filter.png
index abcb39de..d20f31d8 100644
Binary files a/icons/view-filter.png and b/icons/view-filter.png differ
diff --git a/icons/view-filter@2x.png b/icons/view-filter@2x.png
new file mode 100644
index 00000000..c10ccc05
Binary files /dev/null and b/icons/view-filter@2x.png differ
diff --git a/icons/view-fullscreen@2x.png b/icons/view-fullscreen@2x.png
new file mode 100644
index 00000000..b6d16076
Binary files /dev/null and b/icons/view-fullscreen@2x.png differ
diff --git a/icons/view-refresh@2x.png b/icons/view-refresh@2x.png
new file mode 100644
index 00000000..1db3e742
Binary files /dev/null and b/icons/view-refresh@2x.png differ
diff --git a/src/GUI/axisitem.cpp b/src/GUI/axisitem.cpp
index a2c487f4..9eedfe87 100644
--- a/src/GUI/axisitem.cpp
+++ b/src/GUI/axisitem.cpp
@@ -43,10 +43,6 @@ AxisItem::AxisItem(Type type, QGraphicsItem *parent) : QGraphicsItem(parent)
_font.setPixelSize(FONT_SIZE);
_font.setFamily(FONT_FAMILY);
-
-#ifndef Q_OS_MAC
- setCacheMode(QGraphicsItem::DeviceCoordinateCache);
-#endif // Q_OS_MAC
}
void AxisItem::setRange(const RangeF &range)
diff --git a/src/GUI/gui.cpp b/src/GUI/gui.cpp
index dd4072e8..94476564 100644
--- a/src/GUI/gui.cpp
+++ b/src/GUI/gui.cpp
@@ -1,3 +1,4 @@
+#include "config.h"
#include
#include
#include
@@ -22,12 +23,16 @@
#include
#include
#include
+#ifdef ENABLE_HIDPI
+#include
+#include
+#endif // ENABLE_HIDPI
+#include
#include "data/data.h"
#include "data/poi.h"
#include "map/maplist.h"
#include "map/emptymap.h"
#include "map/downloader.h"
-#include "config.h"
#include "icons.h"
#include "keys.h"
#include "settings.h"
@@ -48,6 +53,8 @@
#include "gui.h"
+#define TOOLBAR_ICON_SIZE 22
+
GUI::GUI()
{
loadMaps();
@@ -72,7 +79,7 @@ GUI::GUI()
_splitter->setStretchFactor(1, 1);
setCentralWidget(_splitter);
- setWindowIcon(QIcon(QPixmap(APP_ICON)));
+ setWindowIcon(QIcon(APP_ICON));
setWindowTitle(APP_NAME);
setUnifiedTitleAndToolBarOnMac(true);
setAcceptDrops(true);
@@ -195,7 +202,7 @@ void GUI::createActions()
_navigationActionGroup->setEnabled(false);
// General actions
- _exitAction = new QAction(QIcon(QPixmap(QUIT_ICON)), tr("Quit"), this);
+ _exitAction = new QAction(QIcon(QUIT_ICON), tr("Quit"), this);
_exitAction->setShortcut(QUIT_SHORTCUT);
_exitAction->setMenuRole(QAction::QuitRole);
connect(_exitAction, SIGNAL(triggered()), this, SLOT(close()));
@@ -208,40 +215,37 @@ void GUI::createActions()
_keysAction = new QAction(tr("Keyboard controls"), this);
_keysAction->setMenuRole(QAction::NoRole);
connect(_keysAction, SIGNAL(triggered()), this, SLOT(keys()));
- _aboutAction = new QAction(QIcon(QPixmap(APP_ICON)),
- tr("About GPXSee"), this);
+ _aboutAction = new QAction(QIcon(APP_ICON), tr("About GPXSee"), this);
_aboutAction->setMenuRole(QAction::AboutRole);
connect(_aboutAction, SIGNAL(triggered()), this, SLOT(about()));
// File actions
- _openFileAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)),
- tr("Open..."), this);
+ _openFileAction = new QAction(QIcon(OPEN_FILE_ICON), tr("Open..."), this);
_openFileAction->setMenuRole(QAction::NoRole);
_openFileAction->setShortcut(OPEN_SHORTCUT);
connect(_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
addAction(_openFileAction);
- _printFileAction = new QAction(QIcon(QPixmap(PRINT_FILE_ICON)),
- tr("Print..."), this);
+ _printFileAction = new QAction(QIcon(PRINT_FILE_ICON), tr("Print..."),
+ this);
_printFileAction->setMenuRole(QAction::NoRole);
_printFileAction->setActionGroup(_fileActionGroup);
connect(_printFileAction, SIGNAL(triggered()), this, SLOT(printFile()));
addAction(_printFileAction);
- _exportFileAction = new QAction(QIcon(QPixmap(EXPORT_FILE_ICON)),
+ _exportFileAction = new QAction(QIcon(EXPORT_FILE_ICON),
tr("Export to PDF..."), this);
_exportFileAction->setMenuRole(QAction::NoRole);
_exportFileAction->setShortcut(EXPORT_SHORTCUT);
_exportFileAction->setActionGroup(_fileActionGroup);
connect(_exportFileAction, SIGNAL(triggered()), this, SLOT(exportFile()));
addAction(_exportFileAction);
- _closeFileAction = new QAction(QIcon(QPixmap(CLOSE_FILE_ICON)),
- tr("Close"), this);
+ _closeFileAction = new QAction(QIcon(CLOSE_FILE_ICON), tr("Close"), this);
_closeFileAction->setMenuRole(QAction::NoRole);
_closeFileAction->setShortcut(CLOSE_SHORTCUT);
_closeFileAction->setActionGroup(_fileActionGroup);
connect(_closeFileAction, SIGNAL(triggered()), this, SLOT(closeAll()));
addAction(_closeFileAction);
- _reloadFileAction = new QAction(QIcon(QPixmap(RELOAD_FILE_ICON)),
- tr("Reload"), this);
+ _reloadFileAction = new QAction(QIcon(RELOAD_FILE_ICON), tr("Reload"),
+ this);
_reloadFileAction->setMenuRole(QAction::NoRole);
_reloadFileAction->setShortcut(RELOAD_SHORTCUT);
_reloadFileAction->setActionGroup(_fileActionGroup);
@@ -255,12 +259,12 @@ void GUI::createActions()
addAction(_statisticsAction);
// POI actions
- _openPOIAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)),
- tr("Load POI file..."), this);
+ _openPOIAction = new QAction(QIcon(OPEN_FILE_ICON), tr("Load POI file..."),
+ this);
_openPOIAction->setMenuRole(QAction::NoRole);
connect(_openPOIAction, SIGNAL(triggered()), this, SLOT(openPOIFile()));
- _closePOIAction = new QAction(QIcon(QPixmap(CLOSE_FILE_ICON)),
- tr("Close POI files"), this);
+ _closePOIAction = new QAction(QIcon(CLOSE_FILE_ICON), tr("Close POI files"),
+ this);
_closePOIAction->setMenuRole(QAction::NoRole);
connect(_closePOIAction, SIGNAL(triggered()), this, SLOT(closePOIFiles()));
_overlapPOIAction = new QAction(tr("Overlap POIs"), this);
@@ -273,8 +277,7 @@ void GUI::createActions()
_showPOILabelsAction->setCheckable(true);
connect(_showPOILabelsAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showPOILabels(bool)));
- _showPOIAction = new QAction(QIcon(QPixmap(SHOW_POI_ICON)),
- tr("Show POIs"), this);
+ _showPOIAction = new QAction(QIcon(SHOW_POI_ICON), tr("Show POIs"), this);
_showPOIAction->setMenuRole(QAction::NoRole);
_showPOIAction->setCheckable(true);
_showPOIAction->setShortcut(SHOW_POI_SHORTCUT);
@@ -284,7 +287,7 @@ void GUI::createActions()
createPOIFilesActions();
// Map actions
- _showMapAction = new QAction(QIcon(QPixmap(SHOW_MAP_ICON)), tr("Show map"),
+ _showMapAction = new QAction(QIcon(SHOW_MAP_ICON), tr("Show map"),
this);
_showMapAction->setMenuRole(QAction::NoRole);
_showMapAction->setCheckable(true);
@@ -292,8 +295,8 @@ void GUI::createActions()
connect(_showMapAction, SIGNAL(triggered(bool)), _mapView,
SLOT(showMap(bool)));
addAction(_showMapAction);
- _loadMapAction = new QAction(QIcon(QPixmap(OPEN_FILE_ICON)),
- tr("Load map..."), this);
+ _loadMapAction = new QAction(QIcon(OPEN_FILE_ICON), tr("Load map..."),
+ this);
_loadMapAction->setMenuRole(QAction::NoRole);
connect(_loadMapAction, SIGNAL(triggered()), this, SLOT(loadMap()));
_clearMapCacheAction = new QAction(tr("Clear tile cache"), this);
@@ -344,8 +347,8 @@ void GUI::createActions()
SLOT(showRouteWaypoints(bool)));
// Graph actions
- _showGraphsAction = new QAction(QIcon(QPixmap(SHOW_GRAPHS_ICON)),
- tr("Show graphs"), this);
+ _showGraphsAction = new QAction(QIcon(SHOW_GRAPHS_ICON), tr("Show graphs"),
+ this);
_showGraphsAction->setMenuRole(QAction::NoRole);
_showGraphsAction->setCheckable(true);
_showGraphsAction->setShortcut(SHOW_GRAPHS_SHORTCUT);
@@ -439,7 +442,7 @@ void GUI::createActions()
_DMSAction->setCheckable(true);
_DMSAction->setActionGroup(ag);
connect(_DMSAction, SIGNAL(triggered()), this, SLOT(setDMS()));
- _fullscreenAction = new QAction(QIcon(QPixmap(FULLSCREEN_ICON)),
+ _fullscreenAction = new QAction(QIcon(FULLSCREEN_ICON),
tr("Fullscreen mode"), this);
_fullscreenAction->setMenuRole(QAction::NoRole);
_fullscreenAction->setCheckable(true);
@@ -453,21 +456,19 @@ void GUI::createActions()
SLOT(openOptions()));
// Navigation actions
- _nextAction = new QAction(QIcon(QPixmap(NEXT_FILE_ICON)), tr("Next"), this);
+ _nextAction = new QAction(QIcon(NEXT_FILE_ICON), tr("Next"), this);
_nextAction->setActionGroup(_navigationActionGroup);
_nextAction->setMenuRole(QAction::NoRole);
connect(_nextAction, SIGNAL(triggered()), this, SLOT(next()));
- _prevAction = new QAction(QIcon(QPixmap(PREV_FILE_ICON)), tr("Previous"),
- this);
+ _prevAction = new QAction(QIcon(PREV_FILE_ICON), tr("Previous"), this);
_prevAction->setMenuRole(QAction::NoRole);
_prevAction->setActionGroup(_navigationActionGroup);
connect(_prevAction, SIGNAL(triggered()), this, SLOT(prev()));
- _lastAction = new QAction(QIcon(QPixmap(LAST_FILE_ICON)), tr("Last"), this);
+ _lastAction = new QAction(QIcon(LAST_FILE_ICON), tr("Last"), this);
_lastAction->setMenuRole(QAction::NoRole);
_lastAction->setActionGroup(_navigationActionGroup);
connect(_lastAction, SIGNAL(triggered()), this, SLOT(last()));
- _firstAction = new QAction(QIcon(QPixmap(FIRST_FILE_ICON)), tr("First"),
- this);
+ _firstAction = new QAction(QIcon(FIRST_FILE_ICON), tr("First"), this);
_firstAction->setMenuRole(QAction::NoRole);
_firstAction->setActionGroup(_navigationActionGroup);
connect(_firstAction, SIGNAL(triggered()), this, SLOT(first()));
@@ -555,22 +556,28 @@ void GUI::createMenus()
void GUI::createToolBars()
{
+ int is = style()->pixelMetric(QStyle::PM_ToolBarIconSize);
+ QSize iconSize(qMin(is, TOOLBAR_ICON_SIZE), qMin(is, TOOLBAR_ICON_SIZE));
+
#ifdef Q_OS_MAC
setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
#endif // Q_OS_MAC
_fileToolBar = addToolBar(tr("File"));
+ _fileToolBar->setIconSize(iconSize);
_fileToolBar->addAction(_openFileAction);
_fileToolBar->addAction(_reloadFileAction);
_fileToolBar->addAction(_closeFileAction);
_fileToolBar->addAction(_printFileAction);
_showToolBar = addToolBar(tr("Show"));
+ _showToolBar->setIconSize(iconSize);
_showToolBar->addAction(_showPOIAction);
_showToolBar->addAction(_showMapAction);
_showToolBar->addAction(_showGraphsAction);
_navigationToolBar = addToolBar(tr("Navigation"));
+ _navigationToolBar->setIconSize(iconSize);
_navigationToolBar->addAction(_firstAction);
_navigationToolBar->addAction(_prevAction);
_navigationToolBar->addAction(_nextAction);
@@ -2107,3 +2114,39 @@ qreal GUI::movingTime() const
{
return (_showTracksAction->isChecked()) ? _movingTime : 0;
}
+
+void GUI::show()
+{
+ QMainWindow::show();
+
+#ifdef ENABLE_HIDPI
+ QWindow *w = windowHandle();
+ connect(w->screen(), SIGNAL(logicalDotsPerInchChanged(qreal)), this,
+ SLOT(logicalDotsPerInchChanged(qreal)));
+ connect(w, SIGNAL(screenChanged(QScreen*)), this,
+ SLOT(screenChanged(QScreen*)));
+#endif // ENABLE_HIDPI
+}
+
+void GUI::screenChanged(QScreen *screen)
+{
+#ifdef ENABLE_HIDPI
+ _mapView->updateDevicePixelRatio();
+
+ disconnect(SIGNAL(logicalDotsPerInchChanged(qreal)), this,
+ SLOT(logicalDotsPerInchChanged(qreal)));
+ connect(screen, SIGNAL(logicalDotsPerInchChanged(qreal)), this,
+ SLOT(logicalDotsPerInchChanged(qreal)));
+#else // ENABLE_HIDPI
+ Q_UNUSED(screen);
+#endif // ENABLE_HIDPI
+}
+
+void GUI::logicalDotsPerInchChanged(qreal dpi)
+{
+ Q_UNUSED(dpi)
+
+#ifdef ENABLE_HIDPI
+ _mapView->updateDevicePixelRatio();
+#endif // ENBLE_HIDPI
+}
diff --git a/src/GUI/gui.h b/src/GUI/gui.h
index 92a4f77d..acebc03e 100644
--- a/src/GUI/gui.h
+++ b/src/GUI/gui.h
@@ -28,6 +28,7 @@ class MapView;
class Map;
class MapList;
class POI;
+class QScreen;
class GUI : public QMainWindow
{
@@ -37,6 +38,7 @@ public:
GUI();
bool openFile(const QString &fileName);
+ void show();
private slots:
void about();
@@ -83,6 +85,8 @@ private slots:
void setDMS() {setCoordinatesFormat(DMS);}
void sliderPositionChanged(qreal pos);
+ void screenChanged(QScreen *screen);
+ void logicalDotsPerInchChanged(qreal dpi);
private:
typedef QPair DateRange;
diff --git a/src/GUI/icons.h b/src/GUI/icons.h
index e1b408f2..8e3086f0 100644
--- a/src/GUI/icons.h
+++ b/src/GUI/icons.h
@@ -20,10 +20,10 @@
#define FULLSCREEN_ICON ":/icons/view-fullscreen.png"
// Options dialog icons
-#define APPEARANCE_ICON ":/icons/preferences-desktop-display.png"
-#define POI_ICON ":/icons/flag_48.png"
-#define SYSTEM_ICON ":/icons/system-run.png"
-#define PRINT_EXPORT_ICON ":/icons/document-print-preview.png"
+#define APPEARANCE_ICON ":/icons/format-stroke-color.png"
+#define POI_ICON ":/icons/flag_32.png"
+#define SYSTEM_ICON ":/icons/preferences-system.png"
+#define PRINT_EXPORT_ICON ":/icons/document-print_32.png"
#define DATA_ICON ":/icons/view-filter.png"
#endif /* ICONS_H */
diff --git a/src/GUI/infoitem.cpp b/src/GUI/infoitem.cpp
index 9de666bd..ed8e3547 100644
--- a/src/GUI/infoitem.cpp
+++ b/src/GUI/infoitem.cpp
@@ -9,10 +9,6 @@ InfoItem::InfoItem(QGraphicsItem *parent) : QGraphicsItem(parent)
{
_font.setPixelSize(FONT_SIZE);
_font.setFamily(FONT_FAMILY);
-
-#ifndef Q_OS_MAC
- setCacheMode(QGraphicsItem::DeviceCoordinateCache);
-#endif // Q_OS_MAC
}
void InfoItem::updateBoundingRect()
diff --git a/src/GUI/mapview.cpp b/src/GUI/mapview.cpp
index 3fca1b1a..dc705580 100644
--- a/src/GUI/mapview.cpp
+++ b/src/GUI/mapview.cpp
@@ -29,7 +29,6 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
_scene = new QGraphicsScene(this);
setScene(_scene);
- setCacheMode(QGraphicsView::CacheBackground);
setDragMode(QGraphicsView::ScrollHandDrag);
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -42,6 +41,10 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
_scene->addItem(_mapScale);
_map = map;
+#ifdef ENABLE_HIDPI
+ _ratio = devicePixelRatioF();
+ _map->setDevicePixelRatio(_ratio);
+#endif // ENABLE_HIDPI
_map->load();
connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
@@ -228,7 +231,7 @@ void MapView::updatePOIVisibility()
void MapView::rescale()
{
_scene->setSceneRect(_map->bounds());
- resetCachedContent();
+ reloadMap();
for (int i = 0; i < _tracks.size(); i++)
_tracks.at(i)->setMap(_map);
@@ -265,6 +268,9 @@ void MapView::setMap(Map *map)
disconnect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
_map = map;
+#ifdef ENABLE_HIDPI
+ _map->setDevicePixelRatio(_ratio);
+#endif // ENABLE_HIDPI
_map->load();
connect(_map, SIGNAL(loaded()), this, SLOT(reloadMap()));
@@ -289,7 +295,7 @@ void MapView::setMap(Map *map)
_map->ll2xy(cr.bottomRight())).center();
centerOn(nc);
- resetCachedContent();
+ reloadMap();
QPixmapCache::clear();
}
@@ -498,6 +504,9 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
// Enter plot mode
setUpdatesEnabled(false);
_plot = true;
+#ifdef ENABLE_HIDPI
+ _map->setDevicePixelRatio(1.0);
+#endif // ENABLE_HIDPI
// Compute sizes & ratios
orig = viewport()->rect();
@@ -556,6 +565,9 @@ void MapView::plot(QPainter *painter, const QRectF &target, qreal scale,
_mapScale->setPos(origPos);
// Exit plot mode
+#ifdef ENABLE_HIDPI
+ _map->setDevicePixelRatio(_ratio);
+#endif // ENABLE_HIDPI
_plot = false;
setUpdatesEnabled(true);
}
@@ -635,7 +647,7 @@ void MapView::showRouteWaypoints(bool show)
void MapView::showMap(bool show)
{
_showMap = show;
- resetCachedContent();
+ reloadMap();
}
void MapView::showPOI(bool show)
@@ -738,13 +750,13 @@ void MapView::setPOIColor(const QColor &color)
void MapView::setMapOpacity(int opacity)
{
_opacity = opacity / 100.0;
- resetCachedContent();
+ reloadMap();
}
void MapView::setBackgroundColor(const QColor &color)
{
_backgroundColor = color;
- resetCachedContent();
+ reloadMap();
}
void MapView::drawBackground(QPainter *painter, const QRectF &rect)
@@ -819,5 +831,44 @@ void MapView::setMarkerColor(const QColor &color)
void MapView::reloadMap()
{
- resetCachedContent();
+ _scene->invalidate();
+}
+
+void MapView::updateDevicePixelRatio()
+{
+#ifdef ENABLE_HIDPI
+ if (_ratio == devicePixelRatioF())
+ return;
+
+ _ratio = devicePixelRatioF();
+
+ QRectF vr(mapToScene(viewport()->rect()).boundingRect()
+ .intersected(_map->bounds()));
+ RectC cr(_map->xy2ll(vr.topLeft()), _map->xy2ll(vr.bottomRight()));
+
+ _map->setDevicePixelRatio(_ratio);
+
+ digitalZoom(0);
+
+ _map->zoomFit(viewport()->rect().size(), cr);
+ _scene->setSceneRect(_map->bounds());
+
+ for (int i = 0; i < _tracks.size(); i++)
+ _tracks.at(i)->setMap(_map);
+ for (int i = 0; i < _routes.size(); i++)
+ _routes.at(i)->setMap(_map);
+ for (int i = 0; i < _waypoints.size(); i++)
+ _waypoints.at(i)->setMap(_map);
+
+ QHash, WaypointItem*>::const_iterator it;
+ for (it = _pois.constBegin(); it != _pois.constEnd(); it++)
+ it.value()->setMap(_map);
+ updatePOIVisibility();
+
+ QPointF nc = QRectF(_map->ll2xy(cr.topLeft()),
+ _map->ll2xy(cr.bottomRight())).center();
+ centerOn(nc);
+
+ reloadMap();
+#endif // ENABLE_HIDPI
}
diff --git a/src/GUI/mapview.h b/src/GUI/mapview.h
index a59c4f61..d8d9581a 100644
--- a/src/GUI/mapview.h
+++ b/src/GUI/mapview.h
@@ -11,6 +11,7 @@
#include "units.h"
#include "format.h"
#include "palette.h"
+#include "config.h"
class Data;
class POI;
@@ -68,6 +69,7 @@ public slots:
void showRouteWaypoints(bool show);
void clearMapCache();
void setCoordinatesFormat(CoordinatesFormat format);
+ void updateDevicePixelRatio();
private slots:
void updatePOI();
@@ -136,6 +138,10 @@ private:
int _digitalZoom;
bool _plot;
+
+#ifdef ENABLE_HIDPI
+ qreal _ratio;
+#endif // ENABLE_HIDPI
};
#endif // MAPVIEW_H
diff --git a/src/GUI/optionsdialog.cpp b/src/GUI/optionsdialog.cpp
index ad67c5b1..aa98b9d8 100644
--- a/src/GUI/optionsdialog.cpp
+++ b/src/GUI/optionsdialog.cpp
@@ -492,14 +492,14 @@ OptionsDialog::OptionsDialog(Options *options, QWidget *parent)
QListWidget *menu = new QListWidget();
menu->setIconSize(QSize(MENU_ICON_SIZE, MENU_ICON_SIZE));
- new QListWidgetItem(QIcon(QPixmap(APP_ICON)), tr("General"), menu);
- new QListWidgetItem(QIcon(QPixmap(APPEARANCE_ICON)), tr("Appearance"),
+ new QListWidgetItem(QIcon(APP_ICON), tr("General"), menu);
+ new QListWidgetItem(QIcon(APPEARANCE_ICON), tr("Appearance"),
menu);
- new QListWidgetItem(QIcon(QPixmap(DATA_ICON)), tr("Data"), menu);
- new QListWidgetItem(QIcon(QPixmap(POI_ICON)), tr("POI"), menu);
- new QListWidgetItem(QIcon(QPixmap(PRINT_EXPORT_ICON)), tr("Print & Export"),
+ new QListWidgetItem(QIcon(DATA_ICON), tr("Data"), menu);
+ new QListWidgetItem(QIcon(POI_ICON), tr("POI"), menu);
+ new QListWidgetItem(QIcon(PRINT_EXPORT_ICON), tr("Print & Export"),
menu);
- new QListWidgetItem(QIcon(QPixmap(SYSTEM_ICON)), tr("System"), menu);
+ new QListWidgetItem(QIcon(SYSTEM_ICON), tr("System"), menu);
QHBoxLayout *contentLayout = new QHBoxLayout();
contentLayout->addWidget(menu);
diff --git a/src/GUI/scaleitem.cpp b/src/GUI/scaleitem.cpp
index 94f0188c..573c95fc 100644
--- a/src/GUI/scaleitem.cpp
+++ b/src/GUI/scaleitem.cpp
@@ -20,10 +20,6 @@ ScaleItem::ScaleItem(QGraphicsItem *parent) : QGraphicsItem(parent)
_font.setPixelSize(FONT_SIZE);
_font.setFamily(FONT_FAMILY);
-
-#ifndef Q_OS_MAC
- setCacheMode(QGraphicsItem::DeviceCoordinateCache);
-#endif // Q_OS_MAC
}
void ScaleItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
diff --git a/src/config.h b/src/config.h
index 8b009d83..3f078f44 100644
--- a/src/config.h
+++ b/src/config.h
@@ -46,8 +46,13 @@
#define TILES_DIR USER_DIR + QString("/tiles")
#define TRANSLATIONS_DIR GLOBAL_DIR + QString("/translations")
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 1))
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 1)
#define ENABLE_HTTP2
#endif // QT >= 5.10.1
+#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
+#define ENABLE_HIDPI
+#endif // QT >= 5.6
+
#endif /* CONFIG_H */
diff --git a/src/main.cpp b/src/main.cpp
index 7854d2c5..45cd957f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,7 +1,13 @@
#include "GUI/app.h"
+#include "config.h"
int main(int argc, char *argv[])
{
+#ifdef ENABLE_HIDPI
+ QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+#endif // ENABLE_HIDPI
+
App app(argc, argv);
app.run();
diff --git a/src/map/atlas.cpp b/src/map/atlas.cpp
index 076b87b6..db0b914d 100644
--- a/src/map/atlas.cpp
+++ b/src/map/atlas.cpp
@@ -49,10 +49,7 @@ void Atlas::computeZooms()
void Atlas::computeBounds()
{
- QList offsets;
-
- for (int i = 0; i < _maps.count(); i++)
- offsets.append(QPointF());
+ QVector offsets(_maps.count());
for (int z = 0; z < _zooms.count(); z++) {
QList m;
@@ -62,21 +59,22 @@ void Atlas::computeBounds()
qSort(m.begin(), m.end(), xCmp);
offsets[_maps.indexOf(m.first())].setX(0);
for (int i = 1; i < m.size(); i++) {
- qreal w = round(m.first()->pp2xy(TL(m.at(i))).x());
+ qreal w = m.first()->pp2xy(TL(m.at(i))).x();
offsets[_maps.indexOf(m.at(i))].setX(w);
}
qSort(m.begin(), m.end(), yCmp);
offsets[_maps.indexOf(m.first())].setY(0);
for (int i = 1; i < m.size(); i++) {
- qreal h = round(m.first()->pp2xy(TL(m.at(i))).y());
+ qreal h = m.first()->pp2xy(TL(m.at(i))).y();
offsets[_maps.indexOf(m.at(i))].setY(h);
}
}
+ _bounds = QVector(_maps.count());
for (int i = 0; i < _maps.count(); i++)
- _bounds.append(Bounds(RectD(TL(_maps.at(i)), BR(_maps.at(i))),
- QRectF(offsets.at(i), _maps.at(i)->bounds().size())));
+ _bounds[i] = Bounds(RectD(TL(_maps.at(i)), BR(_maps.at(i))),
+ QRectF(offsets.at(i), _maps.at(i)->bounds().size()));
}
Atlas::Atlas(const QString &fileName, QObject *parent)
@@ -147,6 +145,14 @@ Atlas::Atlas(const QString &fileName, QObject *parent)
_valid = true;
}
+void Atlas::setDevicePixelRatio(qreal ratio)
+{
+ for (int i = 0; i < _maps.size(); i++)
+ _maps[i]->setDevicePixelRatio(ratio);
+
+ computeBounds();
+}
+
QRectF Atlas::bounds()
{
QSizeF s(0, 0);
diff --git a/src/map/atlas.h b/src/map/atlas.h
index fda52370..3008340d 100644
--- a/src/map/atlas.h
+++ b/src/map/atlas.h
@@ -28,6 +28,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, bool block);
+ void setDevicePixelRatio(qreal ratio);
void unload();
bool isValid() const {return _valid;}
diff --git a/src/map/jnxmap.cpp b/src/map/jnxmap.cpp
index 4c323509..35dbafa7 100644
--- a/src/map/jnxmap.cpp
+++ b/src/map/jnxmap.cpp
@@ -5,6 +5,7 @@
#include "rectd.h"
#include "gcs.h"
#include "pcs.h"
+#include "config.h"
#include "jnxmap.h"
@@ -19,8 +20,10 @@ struct Level {
struct Ctx {
QPainter *painter;
QFile *file;
+ qreal ratio;
- Ctx(QPainter *painter, QFile *file) : painter(painter), file(file) {}
+ Ctx(QPainter *painter, QFile *file, qreal ratio)
+ : painter(painter), file(file), ratio(ratio) {}
};
@@ -139,7 +142,7 @@ bool JNXMap::readTiles()
}
JNXMap::JNXMap(const QString &fileName, QObject *parent)
- : Map(parent), _file(fileName), _zoom(0), _valid(false)
+ : Map(parent), _file(fileName), _zoom(0), _ratio(1.0), _valid(false)
{
_name = QFileInfo(fileName).fileName();
@@ -159,13 +162,13 @@ JNXMap::JNXMap(const QString &fileName, QObject *parent)
QPointF JNXMap::ll2xy(const Coordinates &c)
{
const Zoom &z = _zooms.at(_zoom);
- return z.transform.proj2img(_projection.ll2xy(c));
+ return z.transform.proj2img(_projection.ll2xy(c)) / _ratio;
}
Coordinates JNXMap::xy2ll(const QPointF &p)
{
const Zoom &z = _zooms.at(_zoom);
- return _projection.xy2ll(z.transform.img2proj(p));
+ return _projection.xy2ll(z.transform.img2proj(p * _ratio));
}
QRectF JNXMap::bounds()
@@ -233,7 +236,11 @@ QPixmap JNXMap::pixmap(const Tile *tile, QFile *file)
bool JNXMap::cb(Tile *tile, void *context)
{
Ctx *ctx = static_cast(context);
- ctx->painter->drawPixmap(tile->pos, pixmap(tile, ctx->file));
+ QPixmap pm(pixmap(tile, ctx->file));
+#ifdef ENABLE_HIDPI
+ pm.setDevicePixelRatio(ctx->ratio);
+#endif // ENABLE_HIDPI
+ ctx->painter->drawPixmap(tile->pos / ctx->ratio, pm);
return true;
}
@@ -242,12 +249,13 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, bool block)
{
Q_UNUSED(block);
const RTree &tree = _zooms.at(_zoom).tree;
- Ctx ctx(painter, &_file);
+ Ctx ctx(painter, &_file, _ratio);
+ QRectF rr(rect.topLeft() * _ratio, rect.size() * _ratio);
qreal min[2], max[2];
- min[0] = rect.left();
- min[1] = rect.top();
- max[0] = rect.right();
- max[1] = rect.bottom();
+ min[0] = rr.left();
+ min[1] = rr.top();
+ max[0] = rr.right();
+ max[1] = rr.bottom();
tree.Search(min, max, cb, &ctx);
}
diff --git a/src/map/jnxmap.h b/src/map/jnxmap.h
index f616c5cb..c2bd16a3 100644
--- a/src/map/jnxmap.h
+++ b/src/map/jnxmap.h
@@ -32,6 +32,8 @@ public:
void draw(QPainter *painter, const QRectF &rect, bool block);
+ void setDevicePixelRatio(qreal ratio) {_ratio = ratio;}
+
bool isValid() const {return _valid;}
QString errorString() const {return _errorString;}
@@ -61,6 +63,7 @@ private:
int _zoom;
RectC _bounds;
Projection _projection;
+ qreal _ratio;
bool _valid;
QString _errorString;
diff --git a/src/map/map.h b/src/map/map.h
index 7c2bc476..3fe809e4 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -36,6 +36,7 @@ public:
virtual void clearCache() {}
virtual void load() {}
virtual void unload() {}
+ virtual void setDevicePixelRatio(qreal ratio) {Q_UNUSED(ratio);}
virtual bool isValid() const {return true;}
virtual QString errorString() const {return QString();}
diff --git a/src/map/mapsource.cpp b/src/map/mapsource.cpp
index 66b19da2..ac2796f4 100644
--- a/src/map/mapsource.cpp
+++ b/src/map/mapsource.cpp
@@ -15,7 +15,7 @@
MapSource::Config::Config() : type(OSM), zooms(ZOOM_MIN, ZOOM_MAX),
bounds(Coordinates(BOUNDS_LEFT, BOUNDS_TOP), Coordinates(BOUNDS_RIGHT,
- BOUNDS_BOTTOM)), format("image/png"), rest(false) {}
+ BOUNDS_BOTTOM)), format("image/png"), rest(false), tileRatio(1.0) {}
static CoordinateSystem coordinateSystem(QXmlStreamReader &reader)
@@ -159,6 +159,13 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
attr.value("username").toString(),
attr.value("password").toString());
reader.skipCurrentElement();
+ } else if (reader.name() == "tilePixelRatio") {
+ bool res;
+ qreal val = reader.readElementText().toDouble(&res);
+ if (!res)
+ reader.raiseError("Invalid tilePixelRatio");
+ else
+ config.tileRatio = val;
} else
reader.skipCurrentElement();
}
@@ -222,12 +229,13 @@ Map *MapSource::loadMap(const QString &path, QString &errorString)
if (config.type == WMTS)
return new WMTSMap(config.name, WMTS::Setup(config.url, config.layer,
config.set, config.style, config.format, config.rest,
- config.coordinateSystem, config.dimensions, config.authorization));
+ config.coordinateSystem, config.dimensions, config.authorization),
+ config.tileRatio);
else if (config.type == WMS)
return new WMSMap(config.name, WMS::Setup(config.url, config.layer,
config.style, config.format, config.crs, config.coordinateSystem,
config.dimensions, config.authorization));
else
return new OnlineMap(config.name, config.url, config.zooms,
- config.bounds, config.authorization);
+ config.bounds, config.tileRatio, config.authorization);
}
diff --git a/src/map/mapsource.h b/src/map/mapsource.h
index ee38e0bf..f01f7cbb 100644
--- a/src/map/mapsource.h
+++ b/src/map/mapsource.h
@@ -37,6 +37,7 @@ private:
bool rest;
QList > dimensions;
Authorization authorization;
+ qreal tileRatio;
Config();
};
diff --git a/src/map/offlinemap.cpp b/src/map/offlinemap.cpp
index a1f2f8e9..871a88f5 100644
--- a/src/map/offlinemap.cpp
+++ b/src/map/offlinemap.cpp
@@ -12,6 +12,7 @@
#include "ozf.h"
#include "mapfile.h"
#include "geotiff.h"
+#include "config.h"
#include "offlinemap.h"
@@ -94,7 +95,7 @@ bool OfflineMap::setTileInfo(const QStringList &tiles, const QString &path)
}
OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
- : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _valid(false)
+ : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false)
{
QFileInfo fi(fileName);
QString suffix = fi.suffix().toLower();
@@ -172,7 +173,7 @@ OfflineMap::OfflineMap(const QString &fileName, QObject *parent)
}
OfflineMap::OfflineMap(const QString &fileName, Tar &tar, QObject *parent)
- : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _valid(false)
+ : Map(parent), _img(0), _tar(0), _ozf(0), _zoom(0), _ratio(1.0), _valid(false)
{
QFileInfo fi(fileName);
QFileInfo map(fi.absolutePath());
@@ -224,8 +225,13 @@ void OfflineMap::load()
if (!_ozf && !_img && _map.isValid()) {
_img = new QImage(_map.path);
- if (_img->isNull())
+ if (!_img || _img->isNull()) {
qWarning("%s: error loading map image", qPrintable(_map.path));
+ return;
+ }
+#ifdef ENABLE_HIDPI
+ _img->setDevicePixelRatio(_ratio);
+#endif // ENABLE_HIDPI
}
}
@@ -237,15 +243,15 @@ void OfflineMap::unload()
void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect) const
{
- QPoint tl = QPoint((int)floor(rect.left() / (qreal)_tile.size.width())
- * _tile.size.width(), (int)floor(rect.top() / _tile.size.height())
- * _tile.size.height());
+ QSizeF ts(_tile.size.width() / _ratio, _tile.size.height() / _ratio);
+ QPointF tl(floor(rect.left() / ts.width()) * ts.width(),
+ floor(rect.top() / ts.height()) * ts.height());
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
- for (int i = 0; i < ceil(s.width() / _tile.size.width()); i++) {
- for (int j = 0; j < ceil(s.height() / _tile.size.height()); j++) {
- int x = tl.x() + i * _tile.size.width();
- int y = tl.y() + j * _tile.size.height();
+ for (int i = 0; i < ceil(s.width() / ts.width()); i++) {
+ for (int j = 0; j < ceil(s.height() / ts.height()); j++) {
+ int x = round(tl.x() * _ratio + i * _tile.size.width());
+ int y = round(tl.y() * _ratio + j * _tile.size.height());
QString tileName(_tile.path.arg(QString::number(x),
QString::number(y)));
@@ -265,23 +271,29 @@ void OfflineMap::drawTiled(QPainter *painter, const QRectF &rect) const
if (pixmap.isNull())
qWarning("%s: error loading tile image", qPrintable(
_tile.path.arg(QString::number(x), QString::number(y))));
- else
- painter->drawPixmap(QPoint(x, y), pixmap);
+ else {
+#ifdef ENABLE_HIDPI
+ pixmap.setDevicePixelRatio(_ratio);
+#endif // ENABLE_HIDPI
+ QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
+ painter->drawPixmap(tp, pixmap);
+ }
}
}
}
void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect) const
{
- QPoint tl = QPoint((int)floor(rect.left() / _ozf->tileSize().width())
- * _ozf->tileSize().width(), (int)floor(rect.top()
- / _ozf->tileSize().height()) * _ozf->tileSize().height());
+ QSizeF ts(_ozf->tileSize().width() / _ratio, _ozf->tileSize().height()
+ / _ratio);
+ QPointF tl(floor(rect.left() / ts.width()) * ts.width(),
+ floor(rect.top() / ts.height()) * ts.height());
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
- for (int i = 0; i < ceil(s.width() / _ozf->tileSize().width()); i++) {
- for (int j = 0; j < ceil(s.height() / _ozf->tileSize().height()); j++) {
- int x = tl.x() + i * _ozf->tileSize().width();
- int y = tl.y() + j * _ozf->tileSize().height();
+ for (int i = 0; i < ceil(s.width() / ts.width()); i++) {
+ for (int j = 0; j < ceil(s.height() / ts.height()); j++) {
+ int x = round(tl.x() * _ratio + i * _ozf->tileSize().width());
+ int y = round(tl.y() * _ratio + j * _ozf->tileSize().height());
QPixmap pixmap;
QString key = _ozf->fileName() + "/" + QString::number(_zoom) + "_"
@@ -294,17 +306,21 @@ void OfflineMap::drawOZF(QPainter *painter, const QRectF &rect) const
if (pixmap.isNull())
qWarning("%s: error loading tile image", qPrintable(key));
- else
- painter->drawPixmap(QPoint(x, y), pixmap);
+ else {
+#ifdef ENABLE_HIDPI
+ pixmap.setDevicePixelRatio(_ratio);
+#endif // ENABLE_HIDPI
+ QPointF tp(tl.x() + i * ts.width(), tl.y() + j * ts.height());
+ painter->drawPixmap(tp, pixmap);
+ }
}
}
}
void OfflineMap::drawImage(QPainter *painter, const QRectF &rect) const
{
- QRect r(rect.toRect());
- painter->drawImage(r.left(), r.top(), *_img, r.left(), r.top(),
- r.width(), r.height());
+ painter->drawImage(rect.topLeft(), *_img, QRectF(rect.topLeft() * _ratio,
+ rect.size() * _ratio));
}
void OfflineMap::draw(QPainter *painter, const QRectF &rect, bool block)
@@ -322,22 +338,24 @@ void OfflineMap::draw(QPainter *painter, const QRectF &rect, bool block)
QPointF OfflineMap::ll2xy(const Coordinates &c)
{
QPointF p(_transform.proj2img(_projection.ll2xy(c)));
- return _ozf ? QPointF(p.x() * _scale.x(), p.y() * _scale.y()) : p;
+ return _ozf
+ ? QPointF(p.x() * _scale.x(), p.y() * _scale.y()) / _ratio
+ : p / _ratio;
}
Coordinates OfflineMap::xy2ll(const QPointF &p)
{
return _ozf
? _projection.xy2ll(_transform.img2proj(QPointF(p.x() / _scale.x(),
- p.y() / _scale.y())))
- : _projection.xy2ll(_transform.img2proj(p));
+ p.y() / _scale.y()) * _ratio))
+ : _projection.xy2ll(_transform.img2proj(p * _ratio));
}
QRectF OfflineMap::bounds()
{
return _ozf
- ? QRectF(QPointF(0, 0), _ozf->size(_zoom))
- : QRectF(QPointF(0, 0), _map.size);
+ ? QRectF(QPointF(0, 0), _ozf->size(_zoom) / _ratio)
+ : QRectF(QPointF(0, 0), _map.size / _ratio);
}
int OfflineMap::zoomFit(const QSize &size, const RectC &rect)
diff --git a/src/map/offlinemap.h b/src/map/offlinemap.h
index 4b7abefd..604bfb62 100644
--- a/src/map/offlinemap.h
+++ b/src/map/offlinemap.h
@@ -33,6 +33,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, bool block);
+ void setDevicePixelRatio(qreal ratio) {_ratio = ratio;}
void load();
void unload();
@@ -42,9 +43,9 @@ public:
PointD ll2pp(const Coordinates &c) const
{return _projection.ll2xy(c);}
PointD xy2pp(const QPointF &p) const
- {return _transform.img2proj(p);}
+ {return _transform.img2proj(p * _ratio);}
QPointF pp2xy(const PointD &p) const
- {return _transform.proj2img(p);}
+ {return _transform.proj2img(p) / _ratio;}
private:
struct ImageInfo {
@@ -72,6 +73,7 @@ private:
ImageInfo _map, _tile;
int _zoom;
QPointF _scale;
+ qreal _ratio;
bool _valid;
QString _errorString;
diff --git a/src/map/onlinemap.cpp b/src/map/onlinemap.cpp
index bf8cc31a..52be8800 100644
--- a/src/map/onlinemap.cpp
+++ b/src/map/onlinemap.cpp
@@ -42,14 +42,13 @@ static int scale2zoom(qreal scale)
OnlineMap::OnlineMap(const QString &name, const QString &url,
- const Range &zooms, const RectC &bounds, const Authorization &authorization,
- QObject *parent) : Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
- _valid(false)
+ const Range &zooms, const RectC &bounds, qreal tileRatio,
+ const Authorization &authorization, QObject *parent)
+ : Map(parent), _name(name), _zooms(zooms), _bounds(bounds),
+ _zoom(_zooms.max()), _deviceRatio(1.0), _tileRatio(tileRatio), _valid(false)
{
QString dir(TILES_DIR + "/" + _name);
- _zoom = _zooms.max();
-
_tileLoader = new TileLoader(this);
_tileLoader->setUrl(url);
_tileLoader->setDir(dir);
@@ -86,7 +85,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect)
else {
QRectF tbr(ll2m(rect.topLeft()), ll2m(rect.bottomRight()));
QPointF sc(tbr.width() / size.width(), tbr.height() / size.height());
- _zoom = limitZoom(scale2zoom(qMax(sc.x(), -sc.y())));
+ _zoom = limitZoom(scale2zoom(qMax(sc.x(), -sc.y()) / coordinatesRatio()));
}
return _zoom;
@@ -112,19 +111,34 @@ int OnlineMap::zoomOut()
return _zoom;
}
+qreal OnlineMap::coordinatesRatio() const
+{
+ return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0;
+}
+
+qreal OnlineMap::imageRatio() const
+{
+ return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio;
+}
+
+qreal OnlineMap::tileSize() const
+{
+ return (TILE_SIZE / coordinatesRatio());
+}
+
void OnlineMap::draw(QPainter *painter, const QRectF &rect, bool block)
{
qreal scale = zoom2scale(_zoom);
QPoint tile = mercator2tile(QPointF(rect.topLeft().x() * scale,
- -rect.topLeft().y() * scale), _zoom);
- QPoint tl = QPoint((int)floor(rect.left() / (qreal)TILE_SIZE)
- * TILE_SIZE, (int)floor(rect.top() / TILE_SIZE) * TILE_SIZE);
+ -rect.topLeft().y() * scale) * coordinatesRatio(), _zoom);
+ QPointF tl(floor(rect.left() / tileSize())
+ * tileSize(), floor(rect.top() / tileSize()) * tileSize());
QList tiles;
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
- for (int i = 0; i < ceil(s.width() / TILE_SIZE); i++)
- for (int j = 0; j < ceil(s.height() / TILE_SIZE); j++)
+ for (int i = 0; i < ceil(s.width() / tileSize()); i++)
+ for (int j = 0; j < ceil(s.height() / tileSize()); j++)
tiles.append(Tile(QPoint(tile.x() + i, tile.y() + j), _zoom));
if (block)
@@ -134,10 +148,14 @@ void OnlineMap::draw(QPainter *painter, const QRectF &rect, bool block)
for (int i = 0; i < tiles.count(); i++) {
Tile &t = tiles[i];
- QPoint tp(tl.x() + (t.xy().x() - tile.x()) * TILE_SIZE,
- tl.y() + (t.xy().y() - tile.y()) * TILE_SIZE);
- if (!t.pixmap().isNull())
+ QPointF tp(tl.x() + (t.xy().x() - tile.x()) * tileSize(),
+ tl.y() + (t.xy().y() - tile.y()) * tileSize());
+ if (!t.pixmap().isNull()) {
+#ifdef ENABLE_HIDPI
+ t.pixmap().setDevicePixelRatio(imageRatio());
+#endif // ENABLE_HIDPI
painter->drawPixmap(tp, t.pixmap());
+ }
}
}
@@ -145,11 +163,11 @@ QPointF OnlineMap::ll2xy(const Coordinates &c)
{
qreal scale = zoom2scale(_zoom);
QPointF m = ll2m(c);
- return QPointF(m.x() / scale, m.y() / -scale);
+ return QPointF(m.x() / scale, m.y() / -scale) / coordinatesRatio();
}
Coordinates OnlineMap::xy2ll(const QPointF &p)
{
qreal scale = zoom2scale(_zoom);
- return m2ll(QPointF(p.x() * scale, -p.y() * scale));
+ return m2ll(QPointF(p.x() * scale, -p.y() * scale) * coordinatesRatio());
}
diff --git a/src/map/onlinemap.h b/src/map/onlinemap.h
index f87e5143..4620e5fb 100644
--- a/src/map/onlinemap.h
+++ b/src/map/onlinemap.h
@@ -12,7 +12,7 @@ class OnlineMap : public Map
public:
OnlineMap(const QString &name, const QString &url, const Range &zooms,
- const RectC &bounds, const Authorization &authorization,
+ const RectC &bounds, qreal tileRatio, const Authorization &authorization,
QObject *parent = 0);
QString name() const {return _name;}
@@ -31,6 +31,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, bool block);
+ void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;}
void clearCache() {_tileLoader->clearCache();}
bool isValid() const {return _valid;}
@@ -38,12 +39,16 @@ public:
private:
int limitZoom(int zoom) const;
+ qreal tileSize() const;
+ qreal coordinatesRatio() const;
+ qreal imageRatio() const;
TileLoader *_tileLoader;
QString _name;
Range _zooms;
RectC _bounds;
int _zoom;
+ qreal _deviceRatio, _tileRatio;
bool _valid;
QString _errorString;
diff --git a/src/map/wmsmap.cpp b/src/map/wmsmap.cpp
index 37ca585e..a92c1a20 100644
--- a/src/map/wmsmap.cpp
+++ b/src/map/wmsmap.cpp
@@ -103,7 +103,7 @@ bool WMSMap::loadWMS()
WMSMap::WMSMap(const QString &name, const WMS::Setup &setup, QObject *parent)
: Map(parent), _name(name), _setup(setup), _tileLoader(0), _zoom(0),
- _valid(false)
+ _ratio(1.0), _valid(false)
{
if (!QDir().mkpath(tilesDir())) {
_errorString = "Error creating tiles dir";
@@ -129,8 +129,8 @@ void WMSMap::clearCache()
QRectF WMSMap::bounds()
{
- return QRectF(_transform.proj2img(_bbox.topLeft()),
- _transform.proj2img(_bbox.bottomRight()));
+ return QRectF(_transform.proj2img(_bbox.topLeft()) / _ratio,
+ _transform.proj2img(_bbox.bottomRight()) / _ratio);
}
int WMSMap::zoomFit(const QSize &size, const RectC &rect)
@@ -146,7 +146,7 @@ int WMSMap::zoomFit(const QSize &size, const RectC &rect)
_zoom = 0;
for (int i = 0; i < _zooms.size(); i++) {
- if (sd2res(_zooms.at(i)) < resolution)
+ if (sd2res(_zooms.at(i)) < resolution / _ratio)
break;
_zoom = i;
}
@@ -179,20 +179,25 @@ int WMSMap::zoomOut()
QPointF WMSMap::ll2xy(const Coordinates &c)
{
- return _transform.proj2img(_projection.ll2xy(c));
+ return _transform.proj2img(_projection.ll2xy(c)) / _ratio;
}
Coordinates WMSMap::xy2ll(const QPointF &p)
{
- return _projection.xy2ll(_transform.img2proj(p));
+ return _projection.xy2ll(_transform.img2proj(p * _ratio));
+}
+
+qreal WMSMap::tileSize() const
+{
+ return (TILE_SIZE / _ratio);
}
void WMSMap::draw(QPainter *painter, const QRectF &rect, bool block)
{
- QPoint tl = QPoint((int)floor(rect.left() / (qreal)TILE_SIZE),
- (int)floor(rect.top() / (qreal)TILE_SIZE));
- QPoint br = QPoint((int)ceil(rect.right() / (qreal)TILE_SIZE),
- (int)ceil(rect.bottom() / (qreal)TILE_SIZE));
+ QPoint tl = QPoint((int)floor(rect.left() / tileSize()),
+ (int)floor(rect.top() / tileSize()));
+ QPoint br = QPoint((int)ceil(rect.right() / tileSize()),
+ (int)ceil(rect.bottom() / tileSize()));
QList tiles;
for (int i = tl.x(); i < br.x(); i++) {
@@ -216,8 +221,12 @@ void WMSMap::draw(QPainter *painter, const QRectF &rect, bool block)
for (int i = 0; i < tiles.count(); i++) {
Tile &t = tiles[i];
- QPoint tp(t.xy().x() * TILE_SIZE, t.xy().y() * TILE_SIZE);
- if (!t.pixmap().isNull())
+ QPointF tp(t.xy().x() * tileSize(), t.xy().y() * tileSize());
+ if (!t.pixmap().isNull()) {
+#ifdef ENABLE_HIDPI
+ t.pixmap().setDevicePixelRatio(_ratio);
+#endif // ENABLE_HIDPI
painter->drawPixmap(tp, t.pixmap());
+ }
}
}
diff --git a/src/map/wmsmap.h b/src/map/wmsmap.h
index 9e70b50a..d2d5e061 100644
--- a/src/map/wmsmap.h
+++ b/src/map/wmsmap.h
@@ -31,6 +31,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, bool block);
+ void setDevicePixelRatio(qreal ratio) {_ratio = ratio;}
void clearCache();
bool isValid() const {return _valid;}
@@ -43,6 +44,7 @@ private:
void computeZooms(const RangeF &scaleDenominator);
void updateTransform();
bool loadWMS();
+ qreal tileSize() const;
QString _name;
@@ -54,6 +56,7 @@ private:
QVector _zooms;
RectD _bbox;
int _zoom;
+ qreal _ratio;
bool _valid;
QString _errorString;
diff --git a/src/map/wmtsmap.cpp b/src/map/wmtsmap.cpp
index 611f7850..342509e5 100644
--- a/src/map/wmtsmap.cpp
+++ b/src/map/wmtsmap.cpp
@@ -35,9 +35,9 @@ bool WMTSMap::loadWMTS()
return true;
}
-WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent)
- : Map(parent), _name(name), _setup(setup), _tileLoader(0), _zoom(0),
- _valid(false)
+WMTSMap::WMTSMap(const QString &name, const WMTS::Setup &setup, qreal tileRatio,
+ QObject *parent) : Map(parent), _name(name), _setup(setup), _tileLoader(0),
+ _zoom(0), _deviceRatio(1.0), _tileRatio(tileRatio), _valid(false)
{
if (!QDir().mkpath(tilesDir())) {
_errorString = "Error creating tiles dir";
@@ -105,7 +105,6 @@ QRectF WMTSMap::bounds()
bounds = _bounds.isValid() ? QRectF(ll2xy(_bounds.topLeft()),
ll2xy(_bounds.bottomRight())) : QRectF();
-
return _bounds.isValid() ? tileBounds.intersected(bounds) : tileBounds;
}
@@ -122,7 +121,8 @@ int WMTSMap::zoomFit(const QSize &size, const RectC &rect)
_zoom = 0;
for (int i = 0; i < _zooms.size(); i++) {
- if (sd2res(_zooms.at(i).scaleDenominator()) < resolution)
+ if (sd2res(_zooms.at(i).scaleDenominator()) < resolution
+ / coordinatesRatio())
break;
_zoom = i;
}
@@ -153,13 +153,31 @@ int WMTSMap::zoomOut()
return _zoom;
}
+qreal WMTSMap::coordinatesRatio() const
+{
+ return _deviceRatio > 1.0 ? _deviceRatio / _tileRatio : 1.0;
+}
+
+qreal WMTSMap::imageRatio() const
+{
+ return _deviceRatio > 1.0 ? _deviceRatio : _tileRatio;
+}
+
+QSizeF WMTSMap::tileSize(const WMTS::Zoom &zoom) const
+{
+ return QSizeF(zoom.tile().width() / coordinatesRatio(),
+ zoom.tile().height() / coordinatesRatio());
+}
+
void WMTSMap::draw(QPainter *painter, const QRectF &rect, bool block)
{
const WMTS::Zoom &z = _zooms.at(_zoom);
- QPoint tl = QPoint((int)floor(rect.left() / (qreal)z.tile().width()),
- (int)floor(rect.top() / (qreal)z.tile().height()));
- QPoint br = QPoint((int)ceil(rect.right() / (qreal)z.tile().width()),
- (int)ceil(rect.bottom() / (qreal)z.tile().height()));
+ QSizeF ts(tileSize(z));
+
+ QPoint tl = QPoint((int)floor(rect.left() / ts.width()),
+ (int)floor(rect.top() / ts.height()));
+ QPoint br = QPoint((int)ceil(rect.right() / ts.width()),
+ (int)ceil(rect.bottom() / ts.height()));
QList tiles;
for (int i = tl.x(); i < br.x(); i++)
@@ -173,18 +191,22 @@ void WMTSMap::draw(QPainter *painter, const QRectF &rect, bool block)
for (int i = 0; i < tiles.count(); i++) {
Tile &t = tiles[i];
- QPoint tp(t.xy().x() * z.tile().width(), t.xy().y() * z.tile().height());
- if (!t.pixmap().isNull())
+ QPointF tp(t.xy().x() * ts.width(), t.xy().y() * ts.height());
+ if (!t.pixmap().isNull()) {
+#ifdef ENABLE_HIDPI
+ t.pixmap().setDevicePixelRatio(imageRatio());
+#endif // ENABLE_HIDPI
painter->drawPixmap(tp, t.pixmap());
+ }
}
}
QPointF WMTSMap::ll2xy(const Coordinates &c)
{
- return _transform.proj2img(_projection.ll2xy(c));
+ return _transform.proj2img(_projection.ll2xy(c)) / coordinatesRatio();
}
Coordinates WMTSMap::xy2ll(const QPointF &p)
{
- return _projection.xy2ll(_transform.img2proj(p));
+ return _projection.xy2ll(_transform.img2proj(p * coordinatesRatio()));
}
diff --git a/src/map/wmtsmap.h b/src/map/wmtsmap.h
index 8fd22a0b..b1db5ce3 100644
--- a/src/map/wmtsmap.h
+++ b/src/map/wmtsmap.h
@@ -13,7 +13,8 @@ class WMTSMap : public Map
Q_OBJECT
public:
- WMTSMap(const QString &name, const WMTS::Setup &setup, QObject *parent = 0);
+ WMTSMap(const QString &name, const WMTS::Setup &setup, qreal tileRatio,
+ QObject *parent = 0);
QString name() const {return _name;}
@@ -30,6 +31,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, bool block);
+ void setDevicePixelRatio(qreal ratio) {_deviceRatio = ratio;}
void clearCache();
bool isValid() const {return _valid;}
@@ -40,6 +42,9 @@ private:
double sd2res(double scaleDenominator) const;
QString tilesDir() const;
void updateTransform();
+ QSizeF tileSize(const WMTS::Zoom &zoom) const;
+ qreal coordinatesRatio() const;
+ qreal imageRatio() const;
QString _name;
WMTS::Setup _setup;
@@ -50,6 +55,7 @@ private:
Transform _transform;
CoordinateSystem _cs;
int _zoom;
+ qreal _deviceRatio, _tileRatio;
bool _valid;
QString _errorString;