mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-28 13:41:16 +01:00
QPixmap is not thread safe, do the parallel computations on QImage
This commit is contained in:
parent
409ce889cd
commit
c1a217847f
@ -15,25 +15,34 @@
|
|||||||
#include "mbtilesmap.h"
|
#include "mbtilesmap.h"
|
||||||
|
|
||||||
|
|
||||||
struct MBTile
|
class MBTile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MBTile() {}
|
MBTile(int zoom, const QPoint &xy, const QByteArray &data,
|
||||||
MBTile(const QPoint &xy) : xy(xy) {}
|
const QString &key) : _zoom(zoom), _xy(xy), _data(data), _key(key) {}
|
||||||
|
|
||||||
QPixmap pixmap;
|
const QPoint &xy() const {return _xy;}
|
||||||
QByteArray data;
|
const QString &key() const {return _key;}
|
||||||
QString key;
|
QPixmap pixmap() const {return QPixmap::fromImage(_image);}
|
||||||
int zoom;
|
|
||||||
QPoint xy;
|
void load() {
|
||||||
|
QByteArray z(QString::number(_zoom).toLatin1());
|
||||||
|
_image.loadFromData(_data, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int _zoom;
|
||||||
|
QPoint _xy;
|
||||||
|
QByteArray _data;
|
||||||
|
QString _key;
|
||||||
|
QImage _image;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define META_TYPE(type) static_cast<QMetaType::Type>(type)
|
#define META_TYPE(type) static_cast<QMetaType::Type>(type)
|
||||||
|
|
||||||
static void render(MBTile *tile)
|
static void render(MBTile &tile)
|
||||||
{
|
{
|
||||||
tile->pixmap.loadFromData(tile->data, QString::number(tile->zoom)
|
tile.load();
|
||||||
.toLatin1());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static double index2mercator(int index, int zoom)
|
static double index2mercator(int index, int zoom)
|
||||||
@ -249,43 +258,48 @@ void MBTilesMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
int width = ceil(s.width() / tileSize());
|
int width = ceil(s.width() / tileSize());
|
||||||
int height = ceil(s.height() / tileSize());
|
int height = ceil(s.height() / tileSize());
|
||||||
|
|
||||||
QList<MBTile*> jobs;
|
|
||||||
QVector<MBTile> tiles;
|
QList<MBTile> tiles;
|
||||||
tiles.reserve(width * height);
|
|
||||||
|
|
||||||
for (int i = 0; i < width; i++) {
|
for (int i = 0; i < width; i++) {
|
||||||
for (int j = 0; j < height; j++) {
|
for (int j = 0; j < height; j++) {
|
||||||
|
QPixmap pm;
|
||||||
QPoint t(tile.x() + i, tile.y() + j);
|
QPoint t(tile.x() + i, tile.y() + j);
|
||||||
QString key = _fileName + "-" + QString::number(_zoom) + "_"
|
QString key = _fileName + "-" + QString::number(_zoom) + "_"
|
||||||
+ QString::number(t.x()) + "_" + QString::number(t.y());
|
+ QString::number(t.x()) + "_" + QString::number(t.y());
|
||||||
|
|
||||||
tiles.append(MBTile(t));
|
if (QPixmapCache::find(key, pm)) {
|
||||||
MBTile &mt = tiles.last();
|
QPointF tp(qMax(tl.x(), b.left()) + (t.x() - tile.x())
|
||||||
if (!QPixmapCache::find(key, &(mt.pixmap))) {
|
* tileSize(), qMax(tl.y(), b.top()) + (t.y() - tile.y())
|
||||||
mt.data = tileData(_zoom, t);
|
* tileSize());
|
||||||
mt.key = key;
|
drawTile(painter, pm, tp);
|
||||||
mt.zoom = _zoom;
|
} else
|
||||||
jobs.append(&mt);
|
tiles.append(MBTile(_zoom, t, tileData(_zoom, t), key));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<void> future = QtConcurrent::map(jobs, render);
|
QFuture<void> future = QtConcurrent::map(tiles, render);
|
||||||
future.waitForFinished();
|
future.waitForFinished();
|
||||||
|
|
||||||
for (int i = 0; i < tiles.size(); i++) {
|
for (int i = 0; i < tiles.size(); i++) {
|
||||||
MBTile &mt = tiles[i];
|
const MBTile &mt = tiles.at(i);
|
||||||
if (!mt.pixmap.isNull() && !mt.data.isNull())
|
QPixmap pm(mt.pixmap());
|
||||||
QPixmapCache::insert(mt.key, mt.pixmap);
|
if (!pm.isNull())
|
||||||
|
QPixmapCache::insert(mt.key(), pm);
|
||||||
|
|
||||||
QPointF tp(qMax(tl.x(), b.left()) + (mt.xy.x() - tile.x()) * tileSize(),
|
QPointF tp(qMax(tl.x(), b.left()) + (mt.xy().x() - tile.x()) * tileSize(),
|
||||||
qMax(tl.y(), b.top()) + (mt.xy.y() - tile.y()) * tileSize());
|
qMax(tl.y(), b.top()) + (mt.xy().y() - tile.y()) * tileSize());
|
||||||
if (!mt.pixmap.isNull()) {
|
drawTile(painter, pm, tp);
|
||||||
#ifdef ENABLE_HIDPI
|
|
||||||
mt.pixmap.setDevicePixelRatio(imageRatio());
|
|
||||||
#endif // ENABLE_HIDPI
|
|
||||||
painter->drawPixmap(tp, mt.pixmap);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MBTilesMap::drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp)
|
||||||
|
{
|
||||||
|
if (!pixmap.isNull()) {
|
||||||
|
#ifdef ENABLE_HIDPI
|
||||||
|
pixmap.setDevicePixelRatio(imageRatio());
|
||||||
|
#endif // ENABLE_HIDPI
|
||||||
|
painter->drawPixmap(tp, pixmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ private:
|
|||||||
qreal coordinatesRatio() const;
|
qreal coordinatesRatio() const;
|
||||||
qreal imageRatio() const;
|
qreal imageRatio() const;
|
||||||
QByteArray tileData(int zoom, const QPoint &tile) const;
|
QByteArray tileData(int zoom, const QPoint &tile) const;
|
||||||
|
void drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp);
|
||||||
|
|
||||||
QSqlDatabase _db;
|
QSqlDatabase _db;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user