version 2.21.1
Map download API mapviewer download feature
This commit is contained in:
@@ -7,8 +7,10 @@
|
||||
|
||||
#include <QGraphicsPixmapItem>
|
||||
#include <QGraphicsScene>
|
||||
#include <QMetaMethod>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QProgressDialog>
|
||||
#include <QScrollBar>
|
||||
#include <QWheelEvent>
|
||||
|
||||
@@ -19,7 +21,9 @@ MapView::MapView(QWidget * parent): QWidget(parent) {
|
||||
downloader = new OSMDownloader(this);
|
||||
cache = new OSMTileCache(this);
|
||||
setMouseTracking(true);
|
||||
connect(cache, &OSMTileCache::tileReady, this, [this]() { drawBackground(); });
|
||||
connect(cache, &OSMTileCache::tileReady, this, [this]() {
|
||||
if (!is_downloading) drawBackground();
|
||||
});
|
||||
int size = 16;
|
||||
QPixmap px(QSize(size, size) * 2);
|
||||
QPainter p(&px);
|
||||
@@ -77,6 +81,88 @@ void MapView::setZoom(double z) {
|
||||
}
|
||||
|
||||
|
||||
QString MapView::cachePath() const {
|
||||
return cache->cacheRoot();
|
||||
}
|
||||
|
||||
|
||||
void MapView::setCachePath(const QString & p) {
|
||||
cache->setCacheRoot(p);
|
||||
drawBackground();
|
||||
}
|
||||
|
||||
|
||||
void collectDownloadIndeces(QQueue<OSM::TileIndex> & indeces, OSM::TileIndex index, int target_zoom_level) {
|
||||
indeces << index;
|
||||
if (index.z >= target_zoom_level) return;
|
||||
int z = index.z + 1;
|
||||
int x = index.x * 2;
|
||||
int y = index.y * 2;
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
for (int j = 0; j < 2; ++j) {
|
||||
collectDownloadIndeces(indeces, (OSM::TileIndex){z, x + i, y + j}, target_zoom_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MapView::downloadCurrentView(int target_zoom_level) {
|
||||
int sx = qMax(0, (int)floor(view_rect.left() * tiles_side));
|
||||
int sy = qMax(0, (int)floor(view_rect.top() * tiles_side));
|
||||
int ex = qMin(tiles_side, (int)ceil(view_rect.right() * tiles_side));
|
||||
int ey = qMin(tiles_side, (int)ceil(view_rect.bottom() * tiles_side));
|
||||
target_zoom_level = qMin(target_zoom_level, max_level);
|
||||
QQueue<OSM::TileIndex> indeces;
|
||||
for (int ix = sx; ix < ex; ++ix) {
|
||||
for (int iy = sy; iy < ey; ++iy) {
|
||||
collectDownloadIndeces(indeces, (OSM::TileIndex){zoom_level, ix, iy}, target_zoom_level);
|
||||
}
|
||||
}
|
||||
if (indeces.size() < 4) return;
|
||||
QProgressDialog dialog;
|
||||
dialog.setWindowTitle(tr("MapView"));
|
||||
dialog.setLabelText(tr("Downloading ..."));
|
||||
dialog.setCancelButtonText(tr("Cancel"));
|
||||
dialog.setMaximum(indeces.size());
|
||||
dialog.setValue(0);
|
||||
downloader->clearQueue();
|
||||
std::atomic_int value(0);
|
||||
auto conn = connect(
|
||||
downloader,
|
||||
&OSMDownloader::tileDone,
|
||||
this,
|
||||
[this, &dialog, &indeces, &value]() {
|
||||
// qDebug() << "done";
|
||||
value++;
|
||||
int cv = value;
|
||||
dialog.setValue(cv);
|
||||
if (indeces.isEmpty())
|
||||
dialog.cancel();
|
||||
else {
|
||||
downloader->queueTile(indeces.dequeue(), true);
|
||||
}
|
||||
},
|
||||
Qt::DirectConnection);
|
||||
connect(&dialog, &QProgressDialog::canceled, this, [this, &dialog]() {
|
||||
dialog.cancel();
|
||||
downloader->clearQueue();
|
||||
});
|
||||
is_downloading = true;
|
||||
for (int i = 0; i < 1; ++i)
|
||||
downloader->queueTile(indeces.dequeue());
|
||||
// dialog.exec();
|
||||
dialog.setModal(true);
|
||||
dialog.show();
|
||||
while (!dialog.isHidden()) {
|
||||
QThread::msleep(1);
|
||||
QApplication::processEvents();
|
||||
}
|
||||
disconnect(conn);
|
||||
is_downloading = false;
|
||||
drawBackground();
|
||||
}
|
||||
|
||||
|
||||
void MapView::mousePressEvent(QMouseEvent * e) {
|
||||
is_pan = false;
|
||||
press_point = e->pos();
|
||||
|
||||
@@ -51,11 +51,18 @@ public:
|
||||
void setCenter(QPointF c);
|
||||
void setCenter(QGeoCoordinate c) { setCenter(QPointF(c.latitude(), c.longitude())); }
|
||||
|
||||
int getCurrentZoomLevel() const { return zoom_level; }
|
||||
int getMaximumZoomLevel() const { return max_level; }
|
||||
double getZoom() const { return zoom_; }
|
||||
void setZoom(double z);
|
||||
|
||||
QPointF clickedCoordinate() const { return last_click_coord; }
|
||||
|
||||
QString cachePath() const;
|
||||
void setCachePath(const QString & p);
|
||||
|
||||
void downloadCurrentView(int target_zoom_level = 17);
|
||||
|
||||
protected:
|
||||
QSize sizeHint() const override { return QSize(200, 200); }
|
||||
void mousePressEvent(QMouseEvent * e) override;
|
||||
@@ -90,7 +97,7 @@ private:
|
||||
QRectF view_rect;
|
||||
QVector<MapItemBase *> items_;
|
||||
QBrush brush_tr;
|
||||
bool is_pan = false;
|
||||
bool is_pan = false, is_downloading = false;
|
||||
double zoom_ = 1., scale_ = 1., px2m = 1.;
|
||||
int zoom_level = 0, tiles_side = 1, max_level = 19;
|
||||
|
||||
|
||||
@@ -20,14 +20,32 @@ OSMDownloader::~OSMDownloader() {
|
||||
}
|
||||
|
||||
|
||||
void OSMDownloader::queueTile(OSM::TileIndex index) {
|
||||
bool OSMDownloader::queueTile(OSM::TileIndex index, bool force) {
|
||||
// auto hash = tile.hash();
|
||||
bool ret = false;
|
||||
cond_mutex.lock();
|
||||
if (!queue.contains(index) && !in_progress.contains(index.hash())) {
|
||||
if ((!queue.contains(index) && !in_progress.contains(index.hash())) || force) {
|
||||
queue.enqueue(index);
|
||||
cond.wakeOne();
|
||||
ret = true;
|
||||
}
|
||||
cond_mutex.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void OSMDownloader::queueTiles(QList<OSM::TileIndex> indeces) {
|
||||
cond_mutex.lock();
|
||||
queue << indeces;
|
||||
cond.wakeOne();
|
||||
cond_mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
void OSMDownloader::clearQueue() {
|
||||
cond_mutex.lock();
|
||||
queue.clear();
|
||||
cond_mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +69,7 @@ void OSMDownloader::requestTile(OSM::TileIndex index) {
|
||||
cond_mutex.lock();
|
||||
in_progress.remove(index.hash());
|
||||
cond_mutex.unlock();
|
||||
emit tileDone();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,9 @@ public:
|
||||
explicit OSMDownloader(MapView * p);
|
||||
~OSMDownloader();
|
||||
|
||||
void queueTile(OSM::TileIndex index);
|
||||
|
||||
bool queueTile(OSM::TileIndex index, bool force = false);
|
||||
void queueTiles(QList<OSM::TileIndex> indeces);
|
||||
void clearQueue();
|
||||
|
||||
private:
|
||||
void run() override;
|
||||
@@ -60,6 +61,7 @@ public slots:
|
||||
private slots:
|
||||
|
||||
signals:
|
||||
void tileDone();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ QPointF OSMGeocodingResult::resultCoordinate() const {
|
||||
|
||||
|
||||
void OSMGeocodingResult::requestDone() {
|
||||
emit ready();
|
||||
emit ready(this);
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ private:
|
||||
QNetworkReply * reply = nullptr;
|
||||
|
||||
signals:
|
||||
void ready();
|
||||
void ready(OSMGeocodingResult *);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -7,11 +7,8 @@
|
||||
OSMTileCache::OSMTileCache(MapView * p): QThread() {
|
||||
qRegisterMetaType<OSM::TileIndex>();
|
||||
qRegisterMetaType<OSM::TilePixmap>();
|
||||
parent = p;
|
||||
cache_root = QAD::userPath(QAD::ltCache, "map_osm") + "/";
|
||||
cache_dir.setPath(cache_root);
|
||||
qDebug() << "[OSMTileCache] save cache to" << cache_root;
|
||||
if (!cache_dir.exists()) cache_dir.mkpath(".");
|
||||
parent = p;
|
||||
setCacheRoot(QAD::userPath(QAD::ltCache, "map_osm") + "/");
|
||||
setAdditionalCacheSize(64);
|
||||
start();
|
||||
}
|
||||
@@ -57,6 +54,14 @@ OSM::TilePixmap OSMTileCache::getTile(OSM::TileIndex index, QRectF & rect_src) {
|
||||
}
|
||||
|
||||
|
||||
void OSMTileCache::setCacheRoot(const QString & p) {
|
||||
cache_root = p;
|
||||
cache_dir.setPath(cache_root);
|
||||
qDebug() << "[OSMTileCache] Cache dir" << cache_root;
|
||||
if (!cache_dir.exists()) cache_dir.mkpath(".");
|
||||
}
|
||||
|
||||
|
||||
OSM::TilePixmap OSMTileCache::getTileFromCache(OSM::TileIndex index) {
|
||||
OSM::TilePixmap ret;
|
||||
ret.index = index;
|
||||
|
||||
@@ -50,6 +50,9 @@ public:
|
||||
void tileDownloaded(OSM::TileIndex index, const QPixmap & pixmap);
|
||||
OSM::TilePixmap getTile(OSM::TileIndex index, QRectF & rect_src);
|
||||
|
||||
QString cacheRoot() const { return cache_root; }
|
||||
void setCacheRoot(const QString & p);
|
||||
|
||||
private:
|
||||
OSM::TilePixmap getTileFromCache(OSM::TileIndex index);
|
||||
void updateCacheSize();
|
||||
|
||||
Reference in New Issue
Block a user