diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2017-01-26 17:53:23 +0200 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-01-31 18:29:06 +0000 |
commit | 0f035d991b2f94cf9bb3c592fb38e56f6bd058ee (patch) | |
tree | 3af46a2a090e45ec3e708a7197d784174a1b4058 /src/plugins/geoservices/mapboxgl | |
parent | ae02d4c70a95dc40aeb4be41950930847c640cef (diff) | |
download | qtlocation-0f035d991b2f94cf9bb3c592fb38e56f6bd058ee.tar.gz |
Add support for native polylines in Mapbox GL plugin
Change-Id: I14240e095bb6260d56925c026cf78fc1a3ceacdb
Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
Diffstat (limited to 'src/plugins/geoservices/mapboxgl')
4 files changed, 188 insertions, 0 deletions
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp index a675f528..6cbab7a2 100644 --- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp +++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp @@ -45,6 +45,11 @@ #include <QtGui/QOpenGLFramebufferObject> #include <QtLocation/private/qgeomap_p_p.h> #include <QtLocation/private/qgeoprojection_p.h> +#include <QtLocation/private/qdeclarativegeomapitembase_p.h> +#include <QtLocation/private/qdeclarativepolylinemapitem_p.h> + +#include "qgeopath.h" + #include <QtQuick/QQuickWindow> #include <QtQuick/QSGImageNode> #include <QtQuick/private/qsgtexture_p.h> @@ -78,6 +83,10 @@ public: QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window); + QGeoMap::ItemTypes supportedMapItemTypes() const Q_DECL_OVERRIDE; + void addMapItem(QDeclarativeGeoMapItemBase *item) Q_DECL_OVERRIDE; + void removeMapItem(QDeclarativeGeoMapItemBase *item) Q_DECL_OVERRIDE; + /* Data members */ enum SyncState : int { NoSync = 0, @@ -93,6 +102,11 @@ public: bool m_shouldRefresh = true; bool m_warned = false; + QHash<QDeclarativeGeoMapItemBase *, QMapbox::AnnotationID> m_managedMapItems; + QList<QDeclarativeGeoMapItemBase *> m_mapItemsToAdd; + QList<QDeclarativeGeoMapItemBase *> m_mapItemsToUpdate; + QList<QDeclarativeGeoMapItemBase *> m_mapItemsToRemove; + SyncStates m_syncState = NoSync; protected: @@ -140,6 +154,73 @@ QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow map->setStyleUrl(m_activeMapType.name()); } + for (QDeclarativeGeoMapItemBase *mapItem : m_mapItemsToRemove) { + Q_ASSERT(m_managedMapItems.contains(mapItem)); + q->disconnect(mapItem); + + QDeclarativePolylineMapItem *polyline = qobject_cast<QDeclarativePolylineMapItem *>(mapItem); + QDeclarativeMapLineProperties *lineStyle = polyline->line(); + q->disconnect(lineStyle); + + map->removeAnnotation(m_managedMapItems.take(mapItem)); + if (m_mapItemsToUpdate.contains(mapItem)) { + m_mapItemsToUpdate.removeAll(mapItem); + } + } + m_mapItemsToRemove.clear(); + + for (QDeclarativeGeoMapItemBase *mapItem : m_mapItemsToAdd) { + Q_ASSERT(!m_managedMapItems.contains(mapItem)); + + QMapbox::Coordinates coordinates; + const QGeoPath *path = static_cast<const QGeoPath *>(&mapItem->geoShape()); + for (const QGeoCoordinate &coordinate : path->path()) { + coordinates << QMapbox::Coordinate { coordinate.latitude(), coordinate.longitude() }; + } + + QDeclarativePolylineMapItem *polyline = qobject_cast<QDeclarativePolylineMapItem *>(mapItem); + QObject::connect(polyline, &QDeclarativePolylineMapItem::pathChanged, q, &QGeoMapMapboxGL::onMapItemLinePathChange); + QObject::connect(polyline, &QDeclarativeGeoMapItemBase::mapItemOpacityChanged, q, &QGeoMapMapboxGL::onMapItemLineOpacityChange); + + QDeclarativeMapLineProperties *lineStyle = polyline->line(); + QObject::connect(lineStyle, &QDeclarativeMapLineProperties::widthChanged, q, &QGeoMapMapboxGL::onMapItemLineWidthChange); + QObject::connect(lineStyle, &QDeclarativeMapLineProperties::colorChanged, q, &QGeoMapMapboxGL::onMapItemLineColorChange); + + const float opacity = mapItem->mapItemOpacity(); + const float width = lineStyle->width(); + const QColor color = lineStyle->color(); + + QMapbox::CoordinatesCollections geometry { { coordinates } }; + QMapbox::LineAnnotation lineAnnotation { { QMapbox::ShapeAnnotationGeometry::Type::LineStringType, geometry }, opacity, width, color }; + QMapbox::Annotation annotation { QVariant::fromValue<QMapbox::LineAnnotation>(lineAnnotation) }; + + m_managedMapItems.insert(mapItem, map->addAnnotation(annotation)); + } + m_mapItemsToAdd.clear(); + + for (QDeclarativeGeoMapItemBase *mapItem: m_mapItemsToUpdate) { + Q_ASSERT(m_managedMapItems.contains(mapItem)); + QMapbox::Coordinates coordinates; + const QGeoPath *path = static_cast<const QGeoPath *>(&mapItem->geoShape()); + for (const QGeoCoordinate &coordinate : path->path()) { + coordinates << QMapbox::Coordinate { coordinate.latitude(), coordinate.longitude() }; + } + + QDeclarativePolylineMapItem *polyline = qobject_cast<QDeclarativePolylineMapItem *>(mapItem); + QDeclarativeMapLineProperties *lineStyle = polyline->line(); + + const float opacity = mapItem->mapItemOpacity(); + const float width = lineStyle->width(); + const QColor color = lineStyle->color(); + + QMapbox::CoordinatesCollections geometry { { coordinates } }; + QMapbox::LineAnnotation lineAnnotation { { QMapbox::ShapeAnnotationGeometry::Type::LineStringType, geometry }, opacity, width, color }; + QMapbox::Annotation annotation { QVariant::fromValue<QMapbox::LineAnnotation>(lineAnnotation) }; + + map->updateAnnotation(m_managedMapItems.value(mapItem), annotation); + } + m_mapItemsToUpdate.clear(); + if (m_syncState & CameraDataSync) { map->setZoom(zoomLevelFrom256(m_cameraData.zoomLevel() , MBGL_TILE_SIZE)); map->setBearing(m_cameraData.bearing()); @@ -160,6 +241,51 @@ QSGNode *QGeoMapMapboxGLPrivate::updateSceneGraph(QSGNode *oldNode, QQuickWindow return mbglNode; } +QGeoMap::ItemTypes QGeoMapMapboxGLPrivate::supportedMapItemTypes() const +{ + return QGeoMap::MapPolyline; +} + +void QGeoMapMapboxGLPrivate::addMapItem(QDeclarativeGeoMapItemBase *item) +{ + Q_Q(QGeoMapMapboxGL); + + switch (item->itemType()) { + case QGeoMap::NoItem: + case QGeoMap::MapRectangle: + case QGeoMap::MapCircle: + case QGeoMap::MapPolygon: + case QGeoMap::MapQuickItem: + case QGeoMap::CustomMapItem: + return; + case QGeoMap::MapPolyline: + m_mapItemsToAdd << item; + break; + } + + emit q->sgNodeChanged(); +} + +void QGeoMapMapboxGLPrivate::removeMapItem(QDeclarativeGeoMapItemBase *item) +{ + Q_Q(QGeoMapMapboxGL); + + switch (item->itemType()) { + case QGeoMap::NoItem: + case QGeoMap::MapRectangle: + case QGeoMap::MapCircle: + case QGeoMap::MapPolygon: + case QGeoMap::MapQuickItem: + case QGeoMap::CustomMapItem: + return; + case QGeoMap::MapPolyline: + m_mapItemsToRemove << item; + break; + } + + emit q->sgNodeChanged(); +} + void QGeoMapMapboxGLPrivate::changeViewportSize(const QSize &) { Q_Q(QGeoMapMapboxGL); @@ -213,3 +339,39 @@ QSGNode *QGeoMapMapboxGL::updateSceneGraph(QSGNode *oldNode, QQuickWindow *windo Q_D(QGeoMapMapboxGL); return d->updateSceneGraph(oldNode, window); } + +void QGeoMapMapboxGL::onMapItemLinePathChange() +{ + Q_D(QGeoMapMapboxGL); + QDeclarativeGeoMapItemBase *mapItem = static_cast<QDeclarativeGeoMapItemBase *>(sender()); + if (mapItem && !d->m_mapItemsToUpdate.contains(mapItem)) { + d->m_mapItemsToUpdate << mapItem; + } +} + +void QGeoMapMapboxGL::onMapItemLineOpacityChange() +{ + Q_D(QGeoMapMapboxGL); + QDeclarativeGeoMapItemBase *mapItem = static_cast<QDeclarativeGeoMapItemBase *>(sender()); + if (mapItem && !d->m_mapItemsToUpdate.contains(mapItem)) { + d->m_mapItemsToUpdate << mapItem; + } +} + +void QGeoMapMapboxGL::onMapItemLineWidthChange(qreal) +{ + Q_D(QGeoMapMapboxGL); + QDeclarativeGeoMapItemBase *mapItem = static_cast<QDeclarativeGeoMapItemBase *>(sender()->parent()); + if (mapItem && !d->m_mapItemsToUpdate.contains(mapItem)) { + d->m_mapItemsToUpdate << mapItem; + } +} + +void QGeoMapMapboxGL::onMapItemLineColorChange(const QColor &) +{ + Q_D(QGeoMapMapboxGL); + QDeclarativeGeoMapItemBase *mapItem = static_cast<QDeclarativeGeoMapItemBase *>(sender()->parent()); + if (mapItem && !d->m_mapItemsToUpdate.contains(mapItem)) { + d->m_mapItemsToUpdate << mapItem; + } +} diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h index 4c29be5f..2d601c42 100644 --- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h +++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h @@ -53,6 +53,12 @@ public: void setMapboxGLSettings(const QMapboxGLSettings &); +private Q_SLOTS: + void onMapItemLinePathChange(); + void onMapItemLineOpacityChange(); + void onMapItemLineWidthChange(qreal); + void onMapItemLineColorChange(const QColor &); + protected: QSGNode *updateSceneGraph(QSGNode *oldNode, QQuickWindow *window) Q_DECL_OVERRIDE; diff --git a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp index 67e67504..f4e8a264 100644 --- a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp +++ b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.cpp @@ -92,3 +92,19 @@ QMapboxGL* QSGMapboxGLNode::map() const { return m_map.data(); } + +QMapbox::AnnotationID QSGMapboxGLNode::addAnnotation(const QMapbox::Annotation &annotation) +{ + return m_map->addAnnotation(annotation); +} + +void QSGMapboxGLNode::updateAnnotation(QMapbox::AnnotationID id,const QMapbox::Annotation &annotation) +{ + m_map->updateAnnotation(id, annotation); +} + +void QSGMapboxGLNode::removeAnnotation(QMapbox::AnnotationID annotationId) +{ + m_map->removeAnnotation(annotationId); +} + diff --git a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h index bd7cc4b3..08d8f21b 100644 --- a/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h +++ b/src/plugins/geoservices/mapboxgl/qsgmapboxglnode.h @@ -56,6 +56,10 @@ public: QMapboxGL* map() const; + QMapbox::AnnotationID addAnnotation(const QMapbox::Annotation &); + void updateAnnotation(QMapbox::AnnotationID, const QMapbox::Annotation &); + void removeAnnotation(QMapbox::AnnotationID); + private: QScopedPointer<QMapboxGL> m_map; QScopedPointer<QOpenGLFramebufferObject> m_fbo; |