summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-07-22 14:12:34 +0300
committerThiago Marcos P. Santos <thiago@mapbox.com>2016-04-20 20:55:51 +0300
commit854b3bc39b2a84656ca2c120865bf926d7a4b47d (patch)
treebe6f82db23adf0a00d3b22c2332ecc79eeb7b72b /platform
parenta0146e372fe2a44d7eebe7bad9c1f65e18eac785 (diff)
downloadqtlocation-mapboxgl-854b3bc39b2a84656ca2c120865bf926d7a4b47d.tar.gz
[Qt] Add a Qt wrapper aroung mbgl::Map
Signed-off-by: Bruno Abinader <bruno@mapbox.com> Signed-off-by: Thiago Marcos P. Santos <thiago@mapbox.com>
Diffstat (limited to 'platform')
-rw-r--r--platform/qt/include/QMapboxGL1
-rw-r--r--platform/qt/include/qmapboxgl.hpp111
-rw-r--r--platform/qt/src/qmapboxgl.cpp314
-rw-r--r--platform/qt/src/qmapboxgl_p.hpp50
4 files changed, 476 insertions, 0 deletions
diff --git a/platform/qt/include/QMapboxGL b/platform/qt/include/QMapboxGL
new file mode 100644
index 0000000000..15b55a9abe
--- /dev/null
+++ b/platform/qt/include/QMapboxGL
@@ -0,0 +1 @@
+#include "qmapboxgl.hpp"
diff --git a/platform/qt/include/qmapboxgl.hpp b/platform/qt/include/qmapboxgl.hpp
new file mode 100644
index 0000000000..09537963c0
--- /dev/null
+++ b/platform/qt/include/qmapboxgl.hpp
@@ -0,0 +1,111 @@
+#ifndef QMAPBOXGL_H
+#define QMAPBOXGL_H
+
+#include <QObject>
+#include <QPair>
+#include <QPointF>
+
+class QImage;
+class QSize;
+class QString;
+
+class QMapboxGLPrivate;
+
+// This header follows the Qt coding style: https://wiki.qt.io/Qt_Coding_Style
+
+class Q_DECL_EXPORT QMapboxGLSettings
+{
+public:
+ QMapboxGLSettings();
+
+ unsigned cacheDatabaseMaximumSize() const;
+ void setCacheDatabaseMaximumSize(unsigned);
+
+ QString cacheDatabasePath() const;
+ void setCacheDatabasePath(const QString &);
+
+ QString assetPath() const;
+ void setAssetPath(const QString &);
+
+ QString accessToken() const;
+ void setAccessToken(const QString &);
+
+private:
+ unsigned m_cacheMaximumSize;
+ QString m_cacheDatabasePath;
+ QString m_assetPath;
+ QString m_accessToken;
+};
+
+class Q_DECL_EXPORT QMapboxGL : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(double latitude READ latitude WRITE setLatitude)
+ Q_PROPERTY(double longitude READ longitude WRITE setLongitude)
+ Q_PROPERTY(double zoom READ zoom WRITE setZoom)
+ Q_PROPERTY(double bearing READ bearing WRITE setBearing)
+
+public:
+ typedef QPair<double, double> Coordinate;
+
+ QMapboxGL(QObject *parent = 0, const QMapboxGLSettings& = QMapboxGLSettings());
+ virtual ~QMapboxGL();
+
+ void setStyleJSON(const QString &);
+ void setStyleURL(const QString &);
+
+ double latitude() const;
+ void setLatitude(double latitude);
+
+ double longitude() const;
+ void setLongitude(double longitude);
+
+ double zoom() const;
+ void setZoom(double zoom, int milliseconds = 0);
+
+ double minimumZoom() const;
+ double maximumZoom() const;
+
+ double bearing() const;
+ void setBearing(double degrees, int milliseconds = 0);
+ void setBearing(double degrees, const QPointF &center);
+
+ double pitch() const;
+ void setPitch(double pitch, int milliseconds = 0);
+
+ Coordinate coordinate() const;
+ void setCoordinate(const Coordinate &, int milliseconds = 0);
+ void setCoordinateZoom(const Coordinate &, double zoom, int milliseconds = 0);
+
+ void setGestureInProgress(bool inProgress);
+
+ bool isRotating() const;
+ bool isScaling() const;
+ bool isPanning() const;
+ bool isFullyLoaded() const;
+
+ void moveBy(const QPointF &offset);
+ void scaleBy(double scale, const QPointF &center = QPointF(), int milliseconds = 0);
+ void rotateBy(const QPointF &first, const QPointF &second);
+
+ void resize(const QSize &size);
+
+ void addAnnotationIcon(const QString &name, const QImage &sprite);
+
+ QPointF pixelForCoordinate(const Coordinate &) const;
+ Coordinate coordinateForPixel(const QPointF &) const;
+
+public slots:
+ void render();
+
+signals:
+ void needsRendering();
+ void mapRegionDidChange();
+
+private:
+ Q_DISABLE_COPY(QMapboxGL)
+
+ QMapboxGLPrivate *d_ptr;
+};
+
+#endif // QMAPBOXGL_H
diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp
new file mode 100644
index 0000000000..e648354e54
--- /dev/null
+++ b/platform/qt/src/qmapboxgl.cpp
@@ -0,0 +1,314 @@
+#include "qmapboxgl_p.hpp"
+
+#include <mbgl/annotation/point_annotation.hpp>
+#include <mbgl/gl/gl.hpp>
+#include <mbgl/map/map.hpp>
+#include <mbgl/sprite/sprite_image.hpp>
+#include <mbgl/util/geo.hpp>
+#include <mbgl/util/vec.hpp>
+
+#include <QCoreApplication>
+#include <QImage>
+#include <QMapboxGL>
+#include <QString>
+
+#include <memory>
+
+QMapboxGLSettings::QMapboxGLSettings()
+ : m_cacheMaximumSize(mbgl::util::DEFAULT_MAX_CACHE_SIZE)
+ , m_cacheDatabasePath(":memory:")
+ , m_assetPath(QCoreApplication::applicationDirPath())
+{
+}
+
+unsigned QMapboxGLSettings::cacheDatabaseMaximumSize() const
+{
+ return m_cacheMaximumSize;
+}
+
+void QMapboxGLSettings::setCacheDatabaseMaximumSize(unsigned size)
+{
+ m_cacheMaximumSize = size;
+}
+
+QString QMapboxGLSettings::cacheDatabasePath() const
+{
+ return m_cacheDatabasePath;
+}
+
+void QMapboxGLSettings::setCacheDatabasePath(const QString &path)
+{
+ m_cacheDatabasePath = path;
+}
+
+QString QMapboxGLSettings::assetPath() const
+{
+ return m_assetPath;
+}
+
+void QMapboxGLSettings::setAssetPath(const QString &path)
+{
+ m_assetPath = path;
+}
+
+QString QMapboxGLSettings::accessToken() const {
+ return m_accessToken;
+}
+
+void QMapboxGLSettings::setAccessToken(const QString &token)
+{
+ m_accessToken = token;
+}
+
+QMapboxGL::QMapboxGL(QObject *parent_, const QMapboxGLSettings &settings)
+ : QObject(parent_)
+ , d_ptr(new QMapboxGLPrivate(this, settings))
+{
+ d_ptr->fileSourceObj->setAccessToken(settings.accessToken().toStdString());
+
+ d_ptr->mapObj = std::make_unique<mbgl::Map>(*d_ptr, *d_ptr->fileSourceObj,
+ mbgl::MapMode::Continuous, mbgl::GLContextMode::Shared);
+}
+
+QMapboxGL::~QMapboxGL()
+{
+ delete d_ptr;
+}
+
+void QMapboxGL::setStyleJSON(const QString &style)
+{
+ d_ptr->mapObj->setStyleJSON(style.toUtf8().constData());
+}
+
+void QMapboxGL::setStyleURL(const QString &url)
+{
+ d_ptr->mapObj->setStyleURL(url.toUtf8().constData());
+}
+
+double QMapboxGL::latitude() const
+{
+ return d_ptr->mapObj->getLatLng().latitude;
+}
+
+void QMapboxGL::setLatitude(double latitude_)
+{
+ d_ptr->mapObj->setLatLng(mbgl::LatLng { latitude_, longitude() });
+}
+
+double QMapboxGL::longitude() const
+{
+ return d_ptr->mapObj->getLatLng().longitude;
+}
+
+void QMapboxGL::setLongitude(double longitude_)
+{
+ d_ptr->mapObj->setLatLng(mbgl::LatLng { latitude(), longitude_ });
+}
+
+double QMapboxGL::zoom() const
+{
+ return d_ptr->mapObj->getZoom();
+}
+
+void QMapboxGL::setZoom(double zoom_, int milliseconds)
+{
+ d_ptr->mapObj->setZoom(zoom_, std::chrono::milliseconds(milliseconds));
+}
+
+double QMapboxGL::minimumZoom() const
+{
+ return d_ptr->mapObj->getMinZoom();
+}
+
+double QMapboxGL::maximumZoom() const
+{
+ return d_ptr->mapObj->getMaxZoom();
+}
+
+QMapboxGL::Coordinate QMapboxGL::coordinate() const
+{
+ const mbgl::LatLng& latLng = d_ptr->mapObj->getLatLng();
+ return Coordinate(latLng.latitude, latLng.longitude);
+}
+
+void QMapboxGL::setCoordinate(const Coordinate &coordinate_, int milliseconds)
+{
+ d_ptr->mapObj->setLatLng(
+ mbgl::LatLng { coordinate_.first, coordinate_.second },
+ std::chrono::milliseconds(milliseconds));
+}
+
+void QMapboxGL::setCoordinateZoom(const Coordinate &coordinate_, double zoom_, int milliseconds)
+{
+ d_ptr->mapObj->setLatLngZoom(
+ mbgl::LatLng { coordinate_.first, coordinate_.second }, zoom_,
+ std::chrono::milliseconds(milliseconds));
+}
+
+double QMapboxGL::bearing() const
+{
+ return d_ptr->mapObj->getBearing();
+}
+
+void QMapboxGL::setBearing(double degrees, int milliseconds)
+{
+ d_ptr->mapObj->setBearing(degrees, std::chrono::milliseconds(milliseconds));
+}
+
+void QMapboxGL::setBearing(double degrees, const QPointF &center)
+{
+ d_ptr->mapObj->setBearing(degrees, mbgl::ScreenCoordinate { center.x(), center.y() });
+}
+
+double QMapboxGL::pitch() const
+{
+ return d_ptr->mapObj->getPitch();
+}
+
+void QMapboxGL::setPitch(double pitch_, int milliseconds)
+{
+ d_ptr->mapObj->setPitch(pitch_, std::chrono::milliseconds(milliseconds));
+}
+
+void QMapboxGL::setGestureInProgress(bool inProgress)
+{
+ d_ptr->mapObj->setGestureInProgress(inProgress);
+}
+
+bool QMapboxGL::isRotating() const
+{
+ return d_ptr->mapObj->isRotating();
+}
+
+bool QMapboxGL::isScaling() const
+{
+ return d_ptr->mapObj->isScaling();
+}
+
+bool QMapboxGL::isPanning() const
+{
+ return d_ptr->mapObj->isPanning();
+}
+
+bool QMapboxGL::isFullyLoaded() const
+{
+ return d_ptr->mapObj->isFullyLoaded();
+}
+
+void QMapboxGL::moveBy(const QPointF &offset)
+{
+ d_ptr->mapObj->moveBy(mbgl::ScreenCoordinate { offset.x(), offset.y() });
+}
+
+void QMapboxGL::scaleBy(double scale_, const QPointF &center, int milliseconds) {
+ d_ptr->mapObj->scaleBy(
+ scale_, mbgl::ScreenCoordinate { center.x(), center.y() },
+ std::chrono::milliseconds(milliseconds));
+}
+
+void QMapboxGL::rotateBy(const QPointF &first, const QPointF &second)
+{
+ d_ptr->mapObj->rotateBy(
+ mbgl::ScreenCoordinate { first.x(), first.y() },
+ mbgl::ScreenCoordinate { second.x(), second.y() });
+}
+
+void QMapboxGL::resize(const QSize& size)
+{
+ if (d_ptr->size == size) return;
+
+ d_ptr->size = size;
+ d_ptr->mapObj->update(mbgl::Update::Dimensions);
+}
+
+void QMapboxGL::addAnnotationIcon(const QString &name, const QImage &sprite)
+{
+ if (sprite.isNull()) return;
+
+ const QImage swapped = sprite
+ .rgbSwapped()
+ .convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ auto img = std::make_unique<uint8_t[]>(swapped.byteCount());
+ memcpy(img.get(), swapped.constBits(), swapped.byteCount());
+
+ d_ptr->mapObj->addAnnotationIcon(name.toStdString(), std::make_shared<mbgl::SpriteImage>(
+ mbgl::PremultipliedImage { size_t(swapped.width()), size_t(swapped.height()), std::move(img) }, 1.0));
+}
+
+QPointF QMapboxGL::pixelForCoordinate(const Coordinate &coordinate_) const
+{
+ const mbgl::vec2<double> pixel =
+ d_ptr->mapObj->pixelForLatLng(mbgl::LatLng { coordinate_.first, coordinate_.second });
+
+ return QPointF(pixel.x, pixel.y);
+}
+
+QMapboxGL::Coordinate QMapboxGL::coordinateForPixel(const QPointF &pixel) const
+{
+ const mbgl::LatLng latLng =
+ d_ptr->mapObj->latLngForPixel(mbgl::ScreenCoordinate { pixel.x(), pixel.y() });
+
+ return Coordinate(latLng.latitude, latLng.longitude);
+}
+
+void QMapboxGL::render()
+{
+ d_ptr->mapObj->render();
+}
+
+QMapboxGLPrivate::QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &settings)
+ : QObject(q)
+ , size(0, 0)
+ , q_ptr(q)
+ , fileSourceObj(std::make_unique<mbgl::DefaultFileSource>(
+ settings.cacheDatabasePath().toStdString(),
+ settings.assetPath().toStdString(),
+ settings.cacheDatabaseMaximumSize()))
+ , mapObj(std::make_unique<mbgl::Map>(
+ *this, *fileSourceObj,
+ mbgl::MapMode::Continuous,
+ mbgl::GLContextMode::Shared))
+{
+ connect(this, SIGNAL(needsRendering()), q_ptr, SIGNAL(needsRendering()));
+ connect(this, SIGNAL(mapRegionDidChange()), q_ptr, SIGNAL(mapRegionDidChange()));
+}
+
+QMapboxGLPrivate::~QMapboxGLPrivate()
+{
+}
+
+float QMapboxGLPrivate::getPixelRatio() const
+{
+ // FIXME: Should handle pixel ratio.
+ return 1.0;
+}
+
+std::array<uint16_t, 2> QMapboxGLPrivate::getSize() const
+{
+ return {{ static_cast<uint16_t>(size.width()), static_cast<uint16_t>(size.height()) }};
+}
+
+std::array<uint16_t, 2> QMapboxGLPrivate::getFramebufferSize() const
+{
+ return getSize();
+}
+
+void QMapboxGLPrivate::invalidate()
+{
+ emit needsRendering();
+}
+
+void QMapboxGLPrivate::notifyMapChange(mbgl::MapChange change)
+{
+ // Map thread.
+ switch (change) {
+ case mbgl::MapChangeRegionDidChange:
+ case mbgl::MapChangeRegionDidChangeAnimated:
+ case mbgl::MapChangeRegionIsChanging:
+ emit mapRegionDidChange();
+ break;
+ default:
+ break;
+ }
+}
diff --git a/platform/qt/src/qmapboxgl_p.hpp b/platform/qt/src/qmapboxgl_p.hpp
new file mode 100644
index 0000000000..4b2b5b5252
--- /dev/null
+++ b/platform/qt/src/qmapboxgl_p.hpp
@@ -0,0 +1,50 @@
+#ifndef QMAPBOXGL_P_H
+#define QMAPBOXGL_P_H
+
+#include <mbgl/map/map.hpp>
+#include <mbgl/map/view.hpp>
+#include <mbgl/storage/default_file_source.hpp>
+#include <mbgl/util/run_loop.hpp>
+
+#include <QMapboxGL>
+#include <QObject>
+#include <QSize>
+
+#include <memory>
+
+class QMapboxGL;
+class QMapboxGLSettings;
+
+class QMapboxGLPrivate : public QObject, public mbgl::View
+{
+ Q_OBJECT
+
+public:
+ explicit QMapboxGLPrivate(QMapboxGL *q, const QMapboxGLSettings &);
+ virtual ~QMapboxGLPrivate();
+
+ // mbgl::View implementation.
+ float getPixelRatio() const final;
+ std::array<uint16_t, 2> getSize() const final;
+ std::array<uint16_t, 2> getFramebufferSize() const final;
+
+ void activate() final {}
+ void deactivate() final {}
+ void invalidate() final;
+ void notifyMapChange(mbgl::MapChange change) final;
+
+ QSize size;
+
+ QMapboxGL *q_ptr = nullptr;
+
+ mbgl::util::RunLoop loop;
+
+ std::unique_ptr<mbgl::DefaultFileSource> fileSourceObj;
+ std::unique_ptr<mbgl::Map> mapObj;
+
+signals:
+ void mapRegionDidChange();
+ void needsRendering();
+};
+
+#endif // QMAPBOXGL_P_H