#include "mapview.h" #include "osm_downloader_p.h" #include "osm_tile_cache_p.h" OSMDownloader::OSMDownloader(MapView * p): QThread() { qRegisterMetaType(); nam = new QNetworkAccessManager(); parent = p; provider = "http://tile.openstreetmap.org"; start(); } OSMDownloader::~OSMDownloader() { requestInterruption(); cond.wakeAll(); wait(); delete nam; } 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())) || force) { queue.enqueue(index); cond.wakeOne(); ret = true; } cond_mutex.unlock(); return ret; } void OSMDownloader::queueTiles(QList indeces) { cond_mutex.lock(); queue << indeces; cond.wakeOne(); cond_mutex.unlock(); } void OSMDownloader::clearQueue() { cond_mutex.lock(); queue.clear(); cond_mutex.unlock(); } void OSMDownloader::requestTile(OSM::TileIndex index) { QNetworkRequest req(provider + QString("/%1/%2/%3.png").arg(index.z).arg(index.x).arg(index.y)); req.setHeader(QNetworkRequest::UserAgentHeader, "Qt/5"); auto * r = nam->get(req); if (!r) return; connect(r, &QNetworkReply::finished, this, [this, r, index]() { r->deleteLater(); if (r->error() != QNetworkReply::NoError) { qDebug() << "Error:" << r->error(); } else { QByteArray data = r->readAll(); if (!data.isEmpty()) { QPixmap tim; tim.loadFromData(data, "png"); if (!tim.isNull()) parent->cache->tileDownloaded(index, tim); } } cond_mutex.lock(); in_progress.remove(index.hash()); cond_mutex.unlock(); emit tileDone(); }); } void OSMDownloader::run() { while (!isInterruptionRequested()) { cond_mutex.lock(); if (queue.isEmpty()) cond.wait(&cond_mutex); else { auto t = queue.dequeue(); in_progress.insert(t.hash()); QMetaObject::invokeMethod( parent, [this, t]() { requestTile(t); }, Qt::QueuedConnection); } cond_mutex.unlock(); } }