Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Offline Mapping
Qt 6.11 is out! See what's new in the release blog

Offline Mapping

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt5osmmaptiles
14 Posts 4 Posters 3.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • jsulmJ jsulm

    @suslucoder In another thread I told you what it does and gave you a link - did you check that?
    I post the link once more: https://doc.qt.io/qt-5/qstring.html#arg

    D Offline
    D Offline
    deleted286
    wrote on last edited by deleted286
    #4

    @jsulm I've checked. I couldnt find the same thing on that example.
    It gives an osm link, I dont think they are used QString i which refers to %1, or anything like that.

    There is just one line which include QString. It is the one I asked.

    JonBJ 1 Reply Last reply
    0
    • D deleted286

      @jsulm I've checked. I couldnt find the same thing on that example.
      It gives an osm link, I dont think they are used QString i which refers to %1, or anything like that.

      There is just one line which include QString. It is the one I asked.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by
      #5

      @suslucoder
      They are defining that string but never using it? You could always have told us in which file in the example code...

      D 1 Reply Last reply
      0
      • JonBJ JonB

        @suslucoder
        They are defining that string but never using it? You could always have told us in which file in the example code...

        D Offline
        D Offline
        deleted286
        wrote on last edited by
        #6

        @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);
        }
        
        JonBJ 1 Reply Last reply
        0
        • D deleted286

          @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);
          }
          
          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #7

          @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!

          D 1 Reply Last reply
          2
          • JonBJ JonB

            @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!

            D Offline
            D Offline
            deleted286
            wrote on last edited by deleted286
            #8

            @JonB you are so clear!
            I wouldn't ask such a question if I understood what they were doing

            JonBJ jsulmJ 2 Replies Last reply
            0
            • D deleted286

              @JonB you are so clear!
              I wouldn't ask such a question if I understood what they were doing

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #9

              @suslucoder
              OK, forget the QUrl part on that second line. path is a QString. And it's using path.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, %2s etc. in the string and what QString::arg() does with them. He & I don't know how to explain any better!

              1 Reply Last reply
              2
              • D deleted286

                @JonB you are so clear!
                I wouldn't ask such a question if I understood what they were doing

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #10

                @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

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                D 2 Replies Last reply
                2
                • jsulmJ jsulm

                  @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

                  D Offline
                  D Offline
                  deleted286
                  wrote on last edited by
                  #11

                  @jsulm understand now. Thank you

                  1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @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

                    D Offline
                    D Offline
                    deleted286
                    wrote on last edited by
                    #12

                    @jsulm I understand it. You locked my question, but it was another question.
                    Im trying to find a way for tile a map.

                    jsulmJ 1 Reply Last reply
                    0
                    • D deleted286

                      @jsulm I understand it. You locked my question, but it was another question.
                      Im trying to find a way for tile a map.

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #13

                      @suslucoder said in Offline Mapping:

                      You locked my question

                      Which one?

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      Christian EhrlicherC 1 Reply Last reply
                      0
                      • jsulmJ jsulm

                        @suslucoder said in Offline Mapping:

                        You locked my question

                        Which one?

                        Christian EhrlicherC Offline
                        Christian EhrlicherC Offline
                        Christian Ehrlicher
                        Lifetime Qt Champion
                        wrote on last edited by
                        #14

                        @jsulm said in Offline Mapping:

                        Which one?

                        It was me. The question was to similar.

                        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                        Visit the Qt Academy at https://academy.qt.io/catalog

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved