Offline Mapping
Unsolved
General and Desktop
-
@suslucoder
They are defining that string but never using it? You could always have told us in which file in the example code... -
@JonB on slippymap.cpp
#include <QtWidgets> #include <QtNetwork> #include "slippymap.h" #include "qmath.h" uint qHash(const QPoint& p) { return p.x() * 17 ^ p.y(); } // tile size in pixels const int tdim = 256; QPointF tileForCoordinate(qreal lat, qreal lng, int zoom) { qreal radianLat = qDegreesToRadians(lat); qreal zn = static_cast<qreal>(1 << zoom); qreal tx = (lng + 180.0) / 360.0; qreal ty = 0.5 - log(tan(radianLat) + 1.0 / cos(radianLat)) / M_PI / 2.0; return QPointF(tx * zn, ty * zn); } qreal longitudeFromTile(qreal tx, int zoom) { qreal zn = static_cast<qreal>(1 << zoom); qreal lat = tx / zn * 360.0 - 180.0; return lat; } qreal latitudeFromTile(qreal ty, int zoom) { qreal zn = static_cast<qreal>(1 << zoom); qreal n = M_PI - 2 * M_PI * ty / zn; return qRadiansToDegrees(atan(sinh(n))); } SlippyMap::SlippyMap(QObject *parent) : QObject(parent), width(400), height(300), zoom(15), latitude(59.9138204), longitude(10.7387413) { m_emptyTile = QPixmap(tdim, tdim); m_emptyTile.fill(Qt::lightGray); QNetworkDiskCache *cache = new QNetworkDiskCache; cache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); m_manager.setCache(cache); connect(&m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleNetworkData(QNetworkReply*))); } void SlippyMap::invalidate() { if (width <= 0 || height <= 0) return; QPointF ct = tileForCoordinate(latitude, longitude, zoom); qreal tx = ct.x(); qreal ty = ct.y(); // top-left corner of the center tile int xp = width / 2 - (tx - floor(tx)) * tdim; int yp = height / 2 - (ty - floor(ty)) * tdim; // first tile vertical and horizontal int xa = (xp + tdim - 1) / tdim; int ya = (yp + tdim - 1) / tdim; int xs = static_cast<int>(tx) - xa; int ys = static_cast<int>(ty) - ya; // offset for top-left tile m_offset = QPoint(xp - xa * tdim, yp - ya * tdim); // last tile vertical and horizontal int xe = static_cast<int>(tx) + (width - xp - 1) / tdim; int ye = static_cast<int>(ty) + (height - yp - 1) / tdim; // build a rect m_tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1); if (m_url.isEmpty()) download(); emit updated(QRect(0, 0, width, height)); } void SlippyMap::render(QPainter *p, const QRect &rect) { for (int x = 0; x <= m_tilesRect.width(); ++x) for (int y = 0; y <= m_tilesRect.height(); ++y) { QPoint tp(x + m_tilesRect.left(), y + m_tilesRect.top()); QRect box = tileRect(tp); if (rect.intersects(box)) { if (m_tilePixmaps.contains(tp)) p->drawPixmap(box, m_tilePixmaps.value(tp)); else p->drawPixmap(box, m_emptyTile); } } } void SlippyMap::pan(const QPoint &delta) { QPointF dx = QPointF(delta) / qreal(tdim); QPointF center = tileForCoordinate(latitude, longitude, zoom) - dx; latitude = latitudeFromTile(center.y(), zoom); longitude = longitudeFromTile(center.x(), zoom); invalidate(); } void SlippyMap::handleNetworkData(QNetworkReply *reply) { QImage img; QPoint tp = reply->request().attribute(QNetworkRequest::User).toPoint(); if (!reply->error()) if (!img.load(reply, 0)) img = QImage(); reply->deleteLater(); m_tilePixmaps[tp] = QPixmap::fromImage(img); if (img.isNull()) m_tilePixmaps[tp] = m_emptyTile; emit updated(tileRect(tp)); // purge unused spaces const QRect bound = m_tilesRect.adjusted(-2, -2, 2, 2); for (auto it = m_tilePixmaps.keyBegin(); it != m_tilePixmaps.keyEnd(); ++it) { const QPoint &tp = *it; if (!bound.contains(tp)) m_tilePixmaps.remove(tp); } download(); } void SlippyMap::download() { QPoint grab(0, 0); for (int x = 0; x <= m_tilesRect.width(); ++x) for (int y = 0; y <= m_tilesRect.height(); ++y) { QPoint tp = m_tilesRect.topLeft() + QPoint(x, y); if (!m_tilePixmaps.contains(tp)) { grab = tp; break; } } if (grab == QPoint(0, 0)) { m_url = QUrl(); return; } QString path = "http://tile.openstreetmap.org/%1/%2/%3.png"; m_url = QUrl(path.arg(zoom).arg(grab.x()).arg(grab.y())); QNetworkRequest request; request.setUrl(m_url); request.setRawHeader("User-Agent", "The Qt Company (Qt) Graphics Dojo 1.0"); request.setAttribute(QNetworkRequest::User, QVariant(grab)); m_manager.get(request); } QRect SlippyMap::tileRect(const QPoint &tp) { QPoint t = tp - m_tilesRect.topLeft(); int x = t.x() * tdim + m_offset.x(); int y = t.y() * tdim + m_offset.y(); return QRect(x, y, tdim, tdim); }
-
@suslucoder
So why do you say it does not use it, or it's doing something else??QString path = "http://tile.openstreetmap.org/%1/%2/%3.png"; m_url = QUrl(path.arg(zoom).arg(grab.x()).arg(grab.y()));
It's using it on the following line!
-
@suslucoder
OK, forget theQUrl
part on that second line.path
is aQString
. And it's usingpath.arg().arg()...
. Look up exactly what @jsulm referred you to:I post the link once more: https://doc.qt.io/qt-5/qstring.html#arg
That explains exactly why there are
%1
,%2
s etc. in the string and whatQString::arg()
does with them. He & I don't know how to explain any better! -
@suslucoder Maybe one example:
QString path = "http://tile.openstreetmap.org/%1/%2/%3.png"; qDebug() << path.arg("ONE").arg("TWO").arg("THREE");
Will output: http://tile.openstreetmap.org/ONE/TWO/THREE.png
-
-