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 Update on Monday, May 27th 2025

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.
  • D Offline
    D Offline
    deleted286
    wrote on 20 Jan 2021, 13:48 last edited by deleted286
    #1

    Hi everyone. Im trying to do offline map. There is an example called lightmaps. I did not understand one thing. There are too many tiles according to zoom level. Even we have zoom level 2, there were 16 tiles. How can we declare all of them ?

    QString path = "http://tile.openstreetmap.org/%1/%2/%3.png";
    

    In the example, it was doing in that way. What refers %1, %2 and %3 i didnt understand it.
    Can anybody help me in this issue?

    https://doc.qt.io/archives/qt-4.8/qt-demos-embedded-lightmaps-example.html

    J J 2 Replies Last reply 20 Jan 2021, 14:10
    0
    • D deleted286
      20 Jan 2021, 13:48

      Hi everyone. Im trying to do offline map. There is an example called lightmaps. I did not understand one thing. There are too many tiles according to zoom level. Even we have zoom level 2, there were 16 tiles. How can we declare all of them ?

      QString path = "http://tile.openstreetmap.org/%1/%2/%3.png";
      

      In the example, it was doing in that way. What refers %1, %2 and %3 i didnt understand it.
      Can anybody help me in this issue?

      https://doc.qt.io/archives/qt-4.8/qt-demos-embedded-lightmaps-example.html

      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 20 Jan 2021, 14:10 last edited by
      #2

      @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

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

      D 1 Reply Last reply 20 Jan 2021, 14:18
      2
      • D deleted286
        20 Jan 2021, 13:48

        Hi everyone. Im trying to do offline map. There is an example called lightmaps. I did not understand one thing. There are too many tiles according to zoom level. Even we have zoom level 2, there were 16 tiles. How can we declare all of them ?

        QString path = "http://tile.openstreetmap.org/%1/%2/%3.png";
        

        In the example, it was doing in that way. What refers %1, %2 and %3 i didnt understand it.
        Can anybody help me in this issue?

        https://doc.qt.io/archives/qt-4.8/qt-demos-embedded-lightmaps-example.html

        J Offline
        J Offline
        JonB
        wrote on 20 Jan 2021, 14:16 last edited by JonB
        #3

        @suslucoder
        And in addition to @jsulm, if you are taking this from that example code look at how they use the string in their code?

        1 Reply Last reply
        2
        • J jsulm
          20 Jan 2021, 14:10

          @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 20 Jan 2021, 14:18 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.

          J 1 Reply Last reply 20 Jan 2021, 14:29
          0
          • D deleted286
            20 Jan 2021, 14:18

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

            J Offline
            J Offline
            JonB
            wrote on 20 Jan 2021, 14:29 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 20 Jan 2021, 14:31
            0
            • J JonB
              20 Jan 2021, 14:29

              @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 20 Jan 2021, 14:31 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);
              }
              
              J 1 Reply Last reply 20 Jan 2021, 14:51
              0
              • D deleted286
                20 Jan 2021, 14:31

                @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);
                }
                
                J Offline
                J Offline
                JonB
                wrote on 20 Jan 2021, 14:51 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 20 Jan 2021, 14:54
                2
                • J JonB
                  20 Jan 2021, 14:51

                  @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 20 Jan 2021, 14:54 last edited by deleted286
                  #8

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

                  J J 2 Replies Last reply 20 Jan 2021, 14:57
                  0
                  • D deleted286
                    20 Jan 2021, 14:54

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

                    J Offline
                    J Offline
                    JonB
                    wrote on 20 Jan 2021, 14:57 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
                      20 Jan 2021, 14:54

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

                      J Offline
                      J Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on 20 Jan 2021, 15:05 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 20 Jan 2021, 15:13
                      2
                      • J jsulm
                        20 Jan 2021, 15:05

                        @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 20 Jan 2021, 15:13 last edited by
                        #11

                        @jsulm understand now. Thank you

                        1 Reply Last reply
                        0
                        • J jsulm
                          20 Jan 2021, 15:05

                          @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 21 Jan 2021, 06:49 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.

                          J 1 Reply Last reply 21 Jan 2021, 07:52
                          0
                          • D deleted286
                            21 Jan 2021, 06:49

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

                            J Offline
                            J Offline
                            jsulm
                            Lifetime Qt Champion
                            wrote on 21 Jan 2021, 07:52 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 21 Jan 2021, 08:08
                            0
                            • J jsulm
                              21 Jan 2021, 07:52

                              @suslucoder said in Offline Mapping:

                              You locked my question

                              Which one?

                              Christian EhrlicherC Offline
                              Christian EhrlicherC Offline
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on 21 Jan 2021, 08:08 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

                              2/14

                              20 Jan 2021, 14:10

                              topic:navigator.unread, 12
                              • Login

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