diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2018-02-14 18:20:15 +0100 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2018-04-17 13:02:53 +0000 |
commit | 2782765e20ba3bc6af92375574456fd54d4243f7 (patch) | |
tree | 9a70096fdddcc7d28224d6749dd0c7b0da5bcdbb /src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp | |
parent | 05edc644337a33e3e72d993b8114efc755a4320a (diff) | |
download | qtlocation-2782765e20ba3bc6af92375574456fd54d4243f7.tar.gz |
Introduce map objects reference implementation
This patch introduces a reference implementation for
the QGeoMapObject subclasses in the locationlabs module.
If this module is built, all current plugins, with
the exception of mapboxgl, will also be able to render
map objects.
The current reference implementation of map objects
is not optimized, but it can be useful for both testing
and feature parity (so that switching between plugins
will give the same result).
Change-Id: I830ebb3813f219e42c085f450952a2b4327361cd
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp')
-rw-r--r-- | src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp | 200 |
1 files changed, 193 insertions, 7 deletions
diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp index 29b84408..99146801 100644 --- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp +++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp @@ -38,6 +38,22 @@ #include "qgeomappingmanagerengineitemsoverlay.h" #include <QtLocation/private/qgeomap_p_p.h> #include <QtQuick/qsgnode.h> +#include <QtQuick/qsgrectanglenode.h> +#include <QtQuick/qquickwindow.h> + +#ifdef LOCATIONLABS +#include <QtLocation/private/qmappolylineobjectqsg_p_p.h> +#include <QtLocation/private/qmappolygonobjectqsg_p_p.h> +#include <QtLocation/private/qmapcircleobjectqsg_p_p.h> +#include <QtLocation/private/qmaprouteobjectqsg_p_p.h> +#include <QtLocation/private/qmapiconobjectqsg_p_p.h> +struct MapObject { + MapObject(QPointer<QGeoMapObject> &o, QQSGMapObject *sgo) + : object(o), sgObject(sgo) {} + QPointer<QGeoMapObject> object; + QQSGMapObject *sgObject = nullptr; +}; +#endif QT_BEGIN_NAMESPACE @@ -46,9 +62,20 @@ class QGeoMapItemsOverlayPrivate : public QGeoMapPrivate Q_DECLARE_PUBLIC(QGeoMapItemsOverlay) public: QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine); - virtual ~QGeoMapItemsOverlayPrivate(); +#ifdef LOCATIONLABS + QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj) override; + virtual QList<QGeoMapObject *> mapObjects() const override; + static int findMapObject(QGeoMapObject *o, const QList<MapObject> &list); + void removeMapObject(QGeoMapObject *obj); + void updateMapObjects(QSGNode *root, QQuickWindow *window); + + QList<MapObject> m_mapObjects; + QList<MapObject> m_pendingMapObjects; +#endif + + void updateObjectsGeometry(); protected: void changeViewportSize(const QSize &size) override; void changeCameraData(const QGeoCameraData &oldCameraData) override; @@ -65,10 +92,31 @@ QGeoMapItemsOverlay::~QGeoMapItemsOverlay() { } +QGeoMap::Capabilities QGeoMapItemsOverlay::capabilities() const +{ + return Capabilities(SupportsVisibleRegion + | SupportsSetBearing + | SupportsAnchoringCoordinate); +} + QSGNode *QGeoMapItemsOverlay::updateSceneGraph(QSGNode *node, QQuickWindow *window) { +#ifndef LOCATIONLABS Q_UNUSED(window) return node; +#else + Q_D(QGeoMapItemsOverlay); + + QSGRectangleNode *mapRoot = static_cast<QSGRectangleNode *>(node); + if (!mapRoot) + mapRoot = window->createRectangleNode(); + + mapRoot->setRect(QRect(0, 0, viewportWidth(), viewportHeight())); + mapRoot->setColor(QColor(0,0,0,0)); + + d->updateMapObjects(mapRoot, window); + return mapRoot; +#endif } QGeoMapItemsOverlayPrivate::QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine) @@ -80,19 +128,157 @@ QGeoMapItemsOverlayPrivate::~QGeoMapItemsOverlayPrivate() { } -void QGeoMapItemsOverlayPrivate::changeViewportSize(const QSize &size) +#ifdef LOCATIONLABS +QGeoMapObjectPrivate *QGeoMapItemsOverlayPrivate::createMapObjectImplementation(QGeoMapObject *obj) +{ + switch (obj->type()) { + case QGeoMapObject::PolylineType: { + QMapPolylineObjectPrivate &oldImpl = static_cast<QMapPolylineObjectPrivate &>(*obj->implementation()); + QMapPolylineObjectPrivateQSG *pimpl = + new QMapPolylineObjectPrivateQSG(oldImpl); + QPointer<QGeoMapObject> p(obj); + MapObject mo(p, pimpl); + m_pendingMapObjects << mo; + return pimpl; + } + case QGeoMapObject::PolygonType: { + QMapPolygonObjectPrivate &oldImpl = static_cast<QMapPolygonObjectPrivate &>(*obj->implementation()); + QMapPolygonObjectPrivateQSG *pimpl = + new QMapPolygonObjectPrivateQSG(oldImpl); + QPointer<QGeoMapObject> p(obj); + MapObject mo(p, pimpl); + m_pendingMapObjects << mo; + return pimpl; + } + case QGeoMapObject::CircleType: { + QMapCircleObjectPrivate &oldImpl = static_cast<QMapCircleObjectPrivate &>(*obj->implementation()); + QMapCircleObjectPrivateQSG *pimpl = + new QMapCircleObjectPrivateQSG(oldImpl); + QPointer<QGeoMapObject> p(obj); + MapObject mo(p, pimpl); + m_pendingMapObjects << mo; + return pimpl; + } + case QGeoMapObject::RouteType: { + QMapRouteObjectPrivate &oldImpl = static_cast<QMapRouteObjectPrivate &>(*obj->implementation()); + QMapRouteObjectPrivateQSG *pimpl = + new QMapRouteObjectPrivateQSG(oldImpl); + QPointer<QGeoMapObject> p(obj); + MapObject mo(p, pimpl); + m_pendingMapObjects << mo; + return pimpl; + } + case QGeoMapObject::IconType: { + QMapIconObjectPrivate &oldImpl = static_cast<QMapIconObjectPrivate &>(*obj->implementation()); + QMapIconObjectPrivateQSG *pimpl = + new QMapIconObjectPrivateQSG(oldImpl); + QPointer<QGeoMapObject> p(obj); + MapObject mo(p, pimpl); + m_pendingMapObjects << mo; + return pimpl; + } + default: + qWarning() << "Unsupported object type: " << obj->type(); + break; + } + return nullptr; +} + +QList<QGeoMapObject *> QGeoMapItemsOverlayPrivate::mapObjects() const +{ + return QList<QGeoMapObject *>(); +} + +int QGeoMapItemsOverlayPrivate::findMapObject(QGeoMapObject *o, const QList<MapObject> &list) +{ + for (int i = 0; i < list.size(); ++i) + { + if (list.at(i).object.data() == o) + return i; + } + return -1; +} + +void QGeoMapItemsOverlayPrivate::removeMapObject(QGeoMapObject *obj) +{ + int idx = findMapObject(obj, m_mapObjects); + if (idx >= 0) { + m_mapObjects.removeAt(idx); + } else { + idx = findMapObject(obj, m_pendingMapObjects); + if (idx >= 0) { + m_pendingMapObjects.removeAt(idx); + } else { + // obj not here. + } + } +} + +void QGeoMapItemsOverlayPrivate::updateMapObjects(QSGNode *root, QQuickWindow *window) +{ + for (int i = 0; i < m_mapObjects.size(); ++i) { + // already added as node + if (!m_mapObjects.at(i).object) { + qWarning() << "m_mapObjects at "<<i<< " NULLed!!"; + continue; + } + + QQSGMapObject *sgo = m_mapObjects.at(i).sgObject; + QSGNode *oldNode = sgo->node; + sgo->node = sgo->updateMapObjectNode(oldNode, root, window); + } + + QList<int> toRemove; + for (int i = 0; i < m_pendingMapObjects.size(); ++i) { + // already added as node + QQSGMapObject *sgo = m_pendingMapObjects.at(i).sgObject; + QSGNode *oldNode = sgo->node; + sgo->updateGeometry(); // or subtree will be blocked + sgo->node = sgo->updateMapObjectNode(oldNode, root, window); + if (sgo->node) { + m_mapObjects << m_pendingMapObjects.at(i); + toRemove.push_front(i); + } else { + // leave it to be processed + } + } + + for (int i: qAsConst(toRemove)) + m_pendingMapObjects.removeAt(i); +} +#endif + +void QGeoMapItemsOverlayPrivate::updateObjectsGeometry() +{ +#ifdef LOCATIONLABS + Q_Q(QGeoMapItemsOverlay); + for (int i = 0; i < m_mapObjects.size(); ++i) { + // already added as node + if (!m_mapObjects.at(i).object) { + qWarning() << "m_mapObjects at "<<i<< " NULLed!!"; + continue; + } + + QQSGMapObject *sgo = m_mapObjects.at(i).sgObject; + sgo->updateGeometry(); + } + emit q->sgNodeChanged(); +#endif +} + +void QGeoMapItemsOverlayPrivate::changeViewportSize(const QSize &/*size*/) { - Q_UNUSED(size) + updateObjectsGeometry(); } -void QGeoMapItemsOverlayPrivate::changeCameraData(const QGeoCameraData &oldCameraData) +void QGeoMapItemsOverlayPrivate::changeCameraData(const QGeoCameraData &/*oldCameraData*/) { - Q_UNUSED(oldCameraData) + updateObjectsGeometry(); } -void QGeoMapItemsOverlayPrivate::changeActiveMapType(const QGeoMapType mapType) +void QGeoMapItemsOverlayPrivate::changeActiveMapType(const QGeoMapType /*mapType*/) { - Q_UNUSED(mapType) + updateObjectsGeometry(); } QT_END_NAMESPACE |