1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 03:35:53 +01:00

Compare commits

...

8 Commits

Author SHA1 Message Date
ca1c576562 Fixed Android build 2022-06-02 22:08:40 +02:00
feb1650ed0 Allow tile cache sizes up to 2GB 2022-06-02 19:14:34 +02:00
e6e41c846c Increase the default tile image cache size
On big IMG maps that are "digitaly" zoomed out, the tile memory may not be
sufficient for the whole display area which leads to "cache ping-pong", image
artefacts and 100% CPU usage. 512MB RAM should be available for everyone on
the desktop these days...
2022-06-02 19:03:12 +02:00
20adecec89 Code cleanup 2022-06-02 19:02:46 +02:00
8cb08d05ca Version++ 2022-06-02 18:35:44 +02:00
7bd03494db Code cleanup 2022-06-02 18:35:27 +02:00
7ba19b8c0a Use asynchronous tiles rendering in IMG maps
On Android devices, the rendering is very slow so use the same approach as
already used in Mapsforge maps.
2022-06-02 18:31:40 +02:00
25869200db Fixed broken map zooming using the mouse wheel
(introduced in 11.0)
2022-06-02 18:30:19 +02:00
15 changed files with 147 additions and 30 deletions

View File

@ -1,4 +1,4 @@
version: 11.0.{build}
version: 11.1.{build}
configuration:
- Release

View File

@ -3,7 +3,7 @@ unix:!macx:!android {
} else {
TARGET = GPXSee
}
VERSION = 11.0
VERSION = 11.1
QT += core \
gui \

View File

@ -37,7 +37,7 @@ Unicode true
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "11.0"
!define VERSION "11.1"
; The file to write
OutFile "GPXSee-${VERSION}_x64.exe"

View File

@ -2477,8 +2477,8 @@ void GUI::writeSettings()
settings.setValue(SHOW_TICKS_SETTING,
_showTicksAction->isChecked());
bool sm = _showMarkersAction->isChecked()
| _showMarkerDateAction->isChecked()
| _showMarkerCoordinatesAction->isChecked();
|| _showMarkerDateAction->isChecked()
|| _showMarkerCoordinatesAction->isChecked();
if (sm != SHOW_MARKERS_DEFAULT)
settings.setValue(SHOW_MARKERS_SETTING, sm);
if (_showMarkerDateAction->isChecked()

View File

@ -663,7 +663,8 @@ void MapView::wheelEvent(QWheelEvent *event)
zoom((delta > 0) ? 1 : -1, event->position().toPoint(), shift);
#endif // QT 5.15
QGraphicsView::wheelEvent(event);
/* Do not call QGraphicsView::wheelEvent() here as this would shift the
view ! */
}
void MapView::keyPressEvent(QKeyEvent *event)

View File

@ -1,7 +1,8 @@
#include "navigationwidget.h"
#include <QEvent>
#include <QResizeEvent>
#include <QPainter>
#include "mapview.h"
#include "navigationwidget.h"
#define MARGIN 5
#define SIZE 40

View File

@ -2,7 +2,8 @@
#define NAVIGATIONWIDGET_H
#include <QWidget>
#include "mapview.h"
class MapView;
#ifdef Q_OS_ANDROID
class NavigationWidget : public QWidget

View File

@ -717,7 +717,7 @@ QWidget *OptionsDialog::createSystemPage()
_pixmapCache = new QSpinBox();
_pixmapCache->setMinimum(16);
_pixmapCache->setMaximum(1024);
_pixmapCache->setMaximum(2048);
_pixmapCache->setSuffix(UNIT_SPACE + tr("MB"));
_pixmapCache->setValue(_options.pixmapCache);

View File

@ -217,7 +217,11 @@
#define ENABLE_HTTP2_SETTING "enableHTTP2"
#define ENABLE_HTTP2_DEFAULT true
#define PIXMAP_CACHE_SETTING "pixmapCache"
#ifdef Q_OS_ANDROID
#define PIXMAP_CACHE_DEFAULT 256 /* MB */
#else // Q_OS_ANDROID
#define PIXMAP_CACHE_DEFAULT 512 /* MB */
#endif // Q_OS_ANDROID
#define CONNECTION_TIMEOUT_SETTING "connectionTimeout"
#define CONNECTION_TIMEOUT_DEFAULT 30 /* s */
#define HIRES_PRINT_SETTING "hiresPrint"

View File

@ -174,6 +174,8 @@ void RasterTile::render()
qDeleteAll(textItems);
_valid = true;
//painter.setPen(Qt::red);
//painter.setRenderHint(QPainter::Antialiasing, false);
//painter.drawRect(QRect(_xy, _pixmap.size()));
@ -185,7 +187,7 @@ void RasterTile::ll2xy(QList<MapData::Poly> &polys)
MapData::Poly &poly = polys[i];
for (int j = 0; j < poly.points.size(); j++) {
QPointF &p = poly.points[j];
p = _map->ll2xy(Coordinates(p.x(), p.y()));
p = ll2xy(Coordinates(p.x(), p.y()));
}
}
}
@ -193,7 +195,7 @@ void RasterTile::ll2xy(QList<MapData::Poly> &polys)
void RasterTile::ll2xy(QList<MapData::Point> &points)
{
for (int i = 0; i < points.size(); i++) {
QPointF p(_map->ll2xy(points.at(i).coordinates));
QPointF p(ll2xy(points.at(i).coordinates));
points[i].coordinates = Coordinates(p.x(), p.y());
}
}
@ -210,8 +212,8 @@ void RasterTile::drawPolygons(QPainter *painter)
if (poly.raster.isValid()) {
RectC r(poly.raster.rect());
QPointF tl(_map->ll2xy(r.topLeft()));
QPointF br(_map->ll2xy(r.bottomRight()));
QPointF tl(ll2xy(r.topLeft()));
QPointF br(ll2xy(r.bottomRight()));
QSizeF size(QRectF(tl, br).size());
bool insert = false;

View File

@ -3,6 +3,8 @@
#include <QPixmap>
#include "mapdata.h"
#include "map/projection.h"
#include "map/transform.h"
class QPainter;
class IMGMap;
@ -15,20 +17,25 @@ class Style;
class RasterTile
{
public:
RasterTile(IMGMap *map, const Style *style, int zoom, const QRect &rect,
qreal ratio, const QString &key, const QList<MapData::Poly> &polygons,
RasterTile(const Projection &proj, const Transform &transform,
const Style *style, int zoom, const QRect &rect, qreal ratio,
const QString &key, const QList<MapData::Poly> &polygons,
const QList<MapData::Poly> &lines, QList<MapData::Point> &points)
: _map(map), _style(style), _zoom(zoom), _rect(rect), _ratio(ratio),
_key(key), _pixmap(rect.width() * ratio, rect.height() * ratio),
_polygons(polygons), _lines(lines), _points(points) {}
: _proj(proj), _transform(transform), _style(style), _zoom(zoom),
_rect(rect), _ratio(ratio), _key(key),
_pixmap(rect.width() * ratio, rect.height() * ratio), _polygons(polygons),
_lines(lines), _points(points), _valid(false) {}
const QString &key() const {return _key;}
QPoint xy() const {return _rect.topLeft();}
const QPixmap &pixmap() const {return _pixmap;}
bool isValid() const {return _valid;}
void render();
private:
QPointF ll2xy(const Coordinates &c) const
{return _transform.proj2img(_proj.ll2xy(c));}
void ll2xy(QList<MapData::Poly> &polys);
void ll2xy(QList<MapData::Point> &points);
@ -42,7 +49,8 @@ private:
void processShields(QList<TextItem*> &textItems);
void processStreetNames(QList<TextItem*> &textItems);
IMGMap *_map;
Projection _proj;
Transform _transform;
const Style *_style;
int _zoom;
QRect _rect;
@ -52,6 +60,7 @@ private:
QList<MapData::Poly> _polygons;
QList<MapData::Poly> _lines;
QList<MapData::Point> _points;
bool _valid;
};
}

View File

@ -100,6 +100,8 @@ int IMGMap::zoomFit(const QSize &size, const RectC &rect)
int IMGMap::zoomIn()
{
cancelJobs();
_zoom = qMin(_zoom + 1, _data.first()->zooms().max());
updateTransform();
return _zoom;
@ -107,6 +109,8 @@ int IMGMap::zoomIn()
int IMGMap::zoomOut()
{
cancelJobs();
_zoom = qMax(_zoom - 1, _data.first()->zooms().min());
updateTransform();
return _zoom;
@ -139,10 +143,55 @@ void IMGMap::updateTransform()
_bounds.adjust(0.5, 0, -0.5, 0);
}
bool IMGMap::isRunning(const QString &key) const
{
for (int i = 0; i < _jobs.size(); i++) {
const QList<IMG::RasterTile> &tiles = _jobs.at(i)->tiles();
for (int j = 0; j < tiles.size(); j++)
if (tiles.at(j).key() == key)
return true;
}
return false;
}
void IMGMap::runJob(IMGMapJob *job)
{
_jobs.append(job);
connect(job, &IMGMapJob::finished, this, &IMGMap::jobFinished);
job->run();
}
void IMGMap::removeJob(IMGMapJob *job)
{
_jobs.removeOne(job);
job->deleteLater();
}
void IMGMap::jobFinished(IMGMapJob *job)
{
const QList<IMG::RasterTile> &tiles = job->tiles();
for (int i = 0; i < tiles.size(); i++) {
const IMG::RasterTile &mt = tiles.at(i);
if (mt.isValid())
QPixmapCache::insert(mt.key(), mt.pixmap());
}
removeJob(job);
emit tilesLoaded();
}
void IMGMap::cancelJobs()
{
for (int i = 0; i < _jobs.size(); i++)
_jobs.at(i)->cancel();
}
void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{
Q_UNUSED(flags);
QPointF tl(floor(rect.left() / TILE_SIZE)
* TILE_SIZE, floor(rect.top() / TILE_SIZE) * TILE_SIZE);
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
@ -159,6 +208,9 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
QString key(_data.at(n)->fileName() + "-" + QString::number(_zoom)
+ "_" + QString::number(ttl.x()) + "_" + QString::number(ttl.y()));
if (isRunning(key))
continue;
if (QPixmapCache::find(key, &pm))
painter->drawPixmap(ttl, pm);
else {
@ -182,7 +234,8 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
_data.at(n)->points(pointRectD.toRectC(_projection, 20),
_zoom, &points);
tiles.append(RasterTile(this, _data.at(n)->style(), _zoom,
tiles.append(RasterTile(_projection, _transform,
_data.at(n)->style(), _zoom,
QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio, key,
polygons, lines, points));
}
@ -190,14 +243,19 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
}
}
QFuture<void> future = QtConcurrent::map(tiles, &RasterTile::render);
future.waitForFinished();
if (!tiles.isEmpty()) {
if (flags & Map::Block) {
QFuture<void> future = QtConcurrent::map(tiles, &RasterTile::render);
future.waitForFinished();
for (int i = 0; i < tiles.size(); i++) {
const RasterTile &mt = tiles.at(i);
const QPixmap &pm = mt.pixmap();
painter->drawPixmap(mt.xy(), pm);
QPixmapCache::insert(mt.key(), pm);
for (int i = 0; i < tiles.size(); i++) {
const RasterTile &mt = tiles.at(i);
const QPixmap &pm = mt.pixmap();
painter->drawPixmap(mt.xy(), pm);
QPixmapCache::insert(mt.key(), pm);
}
} else
runJob(new IMGMapJob(tiles));
}
}

View File

@ -1,12 +1,44 @@
#ifndef IMGMAP_H
#define IMGMAP_H
#include <QtConcurrent>
#include "map.h"
#include "projection.h"
#include "transform.h"
#include "IMG/mapdata.h"
#include "IMG/rastertile.h"
class IMGMapJob : public QObject
{
Q_OBJECT
public:
IMGMapJob(const QList<IMG::RasterTile> &tiles)
: _tiles(tiles) {}
void run()
{
connect(&_watcher, &QFutureWatcher<void>::finished, this,
&IMGMapJob::handleFinished);
_future = QtConcurrent::map(_tiles, &IMG::RasterTile::render);
_watcher.setFuture(_future);
}
void cancel() {_future.cancel();}
const QList<IMG::RasterTile> &tiles() const {return _tiles;}
signals:
void finished(IMGMapJob *job);
private slots:
void handleFinished() {emit finished(this);}
private:
QFutureWatcher<void> _watcher;
QFuture<void> _future;
QList<IMG::RasterTile> _tiles;
};
class IMGMap : public Map
{
Q_OBJECT
@ -44,9 +76,16 @@ public:
static Map* create(const QString &path, const Projection &, bool *isDir);
private slots:
void jobFinished(IMGMapJob *job);
private:
Transform transform(int zoom) const;
void updateTransform();
bool isRunning(const QString &key) const;
void runJob(IMGMapJob *job);
void removeJob(IMGMapJob *job);
void cancelJobs();
QList<IMG::MapData *> _data;
int _zoom;
@ -56,6 +95,8 @@ private:
RectC _dataBounds;
qreal _tileRatio;
QList<IMGMapJob*> _jobs;
bool _valid;
QString _errorString;
};

View File

@ -1,4 +1,5 @@
#include <QPainter>
#include <QPixmapCache>
#include "common/wgs84.h"
#include "pcs.h"
#include "rectd.h"

View File

@ -2,7 +2,6 @@
#define MAPSFORGEMAP_H
#include <QtConcurrent>
#include <QPixmapCache>
#include "mapsforge/mapdata.h"
#include "mapsforge/rastertile.h"
#include "projection.h"