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
Forum Updated to NodeBB v4.3 + New Features

Offline Mapping

Scheduled Pinned Locked Moved Unsolved General and Desktop
qt5osmmaptiles
14 Posts 4 Posters 1.9k 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