summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2018-04-18 14:34:25 +0200
committerJani Heikkinen <jani.heikkinen@qt.io>2018-04-22 06:34:13 +0000
commitecb6fbd235a8f23f0844bb2b926b78566c1aaa76 (patch)
treed26b0fca188570e72b9aaaaf8aabceedef923084
parente86a2f2a437a8c0e820e85ae4498a391c76bb823 (diff)
downloadqtlocation-ecb6fbd235a8f23f0844bb2b926b78566c1aaa76.tar.gz
Fix QGeoMapObject handling in reference implementation
setVisible was neither changing the visibility nor triggering repaint. Pimpls weren't removing themselves in their destructors when dynamically added/removed via QGeoMapObjectView add/removeMapObject. This patch also factors out the duplicated QGeoMapObject support from QGeoTiledMapLabs and QGeoMapObjectsOverlay and moves it into an own class, QGeoMapObjectQSGSupport. To properly flush the scene graph nodes upon object removal, a pointer to the QSGNode is added to the MapObject struct, now moved inside QGeoMapObjectQSGSupport. Change-Id: Ie8c6d54f8f340ba3867717d9620791d3fe8021cc Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem.cpp17
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem_p.h8
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp69
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem_p.h27
-rw-r--r--src/location/declarativemaps/qgeomapobject.cpp5
-rw-r--r--src/location/labs/qgeotiledmaplabs.cpp150
-rw-r--r--src/location/labs/qgeotiledmaplabs_p.h2
-rw-r--r--src/location/labs/qmapcircleobject.cpp3
-rw-r--r--src/location/labs/qmapiconobject.cpp3
-rw-r--r--src/location/labs/qmapobjectview.cpp62
-rw-r--r--src/location/labs/qmappolygonobject.cpp3
-rw-r--r--src/location/labs/qmappolylineobject.cpp3
-rw-r--r--src/location/labs/qmaprouteobject.cpp3
-rw-r--r--src/location/labs/qsg/qgeomapobjectqsgsupport.cpp224
-rw-r--r--src/location/labs/qsg/qgeomapobjectqsgsupport_p.h92
-rw-r--r--src/location/labs/qsg/qmapcircleobjectqsg.cpp10
-rw-r--r--src/location/labs/qsg/qmapcircleobjectqsg_p_p.h5
-rw-r--r--src/location/labs/qsg/qmapiconobjectqsg.cpp25
-rw-r--r--src/location/labs/qsg/qmapiconobjectqsg_p_p.h5
-rw-r--r--src/location/labs/qsg/qmappolygonobjectqsg.cpp10
-rw-r--r--src/location/labs/qsg/qmappolygonobjectqsg_p_p.h5
-rw-r--r--src/location/labs/qsg/qmappolylineobjectqsg.cpp10
-rw-r--r--src/location/labs/qsg/qmappolylineobjectqsg_p_p.h5
-rw-r--r--src/location/labs/qsg/qmaprouteobjectqsg.cpp10
-rw-r--r--src/location/labs/qsg/qmaprouteobjectqsg_p_p.h5
-rw-r--r--src/location/labs/qsg/qqsgmapobject.cpp6
-rw-r--r--src/location/labs/qsg/qqsgmapobject_p.h8
-rw-r--r--src/location/maps/qgeomap_p.h2
-rw-r--r--src/location/maps/qgeomap_p_p.h2
-rw-r--r--src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp156
-rw-r--r--src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h2
31 files changed, 568 insertions, 369 deletions
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
index 9e96f3c6..eab0f214 100644
--- a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
@@ -654,8 +654,7 @@ void QDeclarativePolygonMapItem::geometryChanged(const QRectF &newGeometry, cons
MapPolygonNode::MapPolygonNode() :
border_(new MapPolylineNode()),
- geometry_(QSGGeometry::defaultAttributes_Point2D(), 0),
- blocked_(true)
+ geometry_(QSGGeometry::defaultAttributes_Point2D(), 0)
{
geometry_.setDrawingMode(QSGGeometry::DrawTriangles);
QSGGeometryNode::setMaterial(&fill_material_);
@@ -671,14 +670,6 @@ MapPolygonNode::~MapPolygonNode()
/*!
\internal
*/
-bool MapPolygonNode::isSubtreeBlocked() const
-{
- return blocked_;
-}
-
-/*!
- \internal
-*/
void MapPolygonNode::update(const QColor &fillColor, const QColor &borderColor,
const QGeoMapItemGeometry *fillShape,
const QGeoMapItemGeometry *borderShape)
@@ -692,13 +683,13 @@ void MapPolygonNode::update(const QColor &fillColor, const QColor &borderColor,
* accuracy) */
if (fillShape->size() == 0) {
if (borderShape->size() == 0) {
- blocked_ = true;
+ setSubtreeBlocked(true);
return;
} else {
- blocked_ = false;
+ setSubtreeBlocked(false);
}
} else {
- blocked_ = false;
+ setSubtreeBlocked(false);
}
QSGGeometry *fill = QSGGeometryNode::geometry();
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
index febeb751..83983651 100644
--- a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
@@ -137,24 +137,20 @@ private:
//////////////////////////////////////////////////////////////////////
-class Q_LOCATION_PRIVATE_EXPORT MapPolygonNode : public QSGGeometryNode
+class Q_LOCATION_PRIVATE_EXPORT MapPolygonNode : public MapItemGeometryNode
{
public:
MapPolygonNode();
- ~MapPolygonNode();
+ ~MapPolygonNode() override;
void update(const QColor &fillColor, const QColor &borderColor,
const QGeoMapItemGeometry *fillShape,
const QGeoMapItemGeometry *borderShape);
-
- bool isSubtreeBlocked() const override;
-
private:
QSGFlatColorMaterial fill_material_;
MapPolylineNode *border_;
QSGGeometry geometry_;
- bool blocked_;
};
QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
index dffec4d5..620ed14e 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
@@ -1014,29 +1014,76 @@ QGeoMap::ItemType QDeclarativePolylineMapItem::itemType() const
/*!
\internal
*/
-MapPolylineNode::MapPolylineNode() :
- geometry_(QSGGeometry::defaultAttributes_Point2D(),0),
- blocked_(true)
+VisibleNode::VisibleNode() : m_blocked{true}, m_visible{true}
{
- geometry_.setDrawingMode(QSGGeometry::DrawTriangleStrip);
- QSGGeometryNode::setMaterial(&fill_material_);
- QSGGeometryNode::setGeometry(&geometry_);
+
}
+VisibleNode::~VisibleNode()
+{
+
+}
/*!
\internal
*/
-MapPolylineNode::~MapPolylineNode()
+bool VisibleNode::subtreeBlocked() const
+{
+ return m_blocked || !m_visible;
+}
+
+/*!
+ \internal
+*/
+void VisibleNode::setSubtreeBlocked(bool blocked)
+{
+ m_blocked = blocked;
+}
+
+bool VisibleNode::visible() const
+{
+ return m_visible;
+}
+
+/*!
+ \internal
+*/
+void VisibleNode::setVisible(bool visible)
{
+ m_visible = visible;
}
/*!
\internal
*/
-bool MapPolylineNode::isSubtreeBlocked() const
+MapItemGeometryNode::~MapItemGeometryNode()
+{
+
+}
+
+bool MapItemGeometryNode::isSubtreeBlocked() const
+{
+ return subtreeBlocked();
+}
+
+
+/*!
+ \internal
+*/
+MapPolylineNode::MapPolylineNode() :
+ geometry_(QSGGeometry::defaultAttributes_Point2D(),0)
+{
+ geometry_.setDrawingMode(QSGGeometry::DrawTriangleStrip);
+ QSGGeometryNode::setMaterial(&fill_material_);
+ QSGGeometryNode::setGeometry(&geometry_);
+}
+
+
+/*!
+ \internal
+*/
+MapPolylineNode::~MapPolylineNode()
{
- return blocked_;
}
/*!
@@ -1046,10 +1093,10 @@ void MapPolylineNode::update(const QColor &fillColor,
const QGeoMapItemGeometry *shape)
{
if (shape->size() == 0) {
- blocked_ = true;
+ setSubtreeBlocked(true);
return;
} else {
- blocked_ = false;
+ setSubtreeBlocked(false);
}
QSGGeometry *fill = QSGGeometryNode::geometry();
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
index ca01de12..225f21d9 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
@@ -181,20 +181,39 @@ private:
//////////////////////////////////////////////////////////////////////
-class Q_LOCATION_PRIVATE_EXPORT MapPolylineNode : public QSGGeometryNode
+class Q_LOCATION_PRIVATE_EXPORT VisibleNode
{
+public:
+ VisibleNode();
+ virtual ~VisibleNode();
+
+ bool subtreeBlocked() const;
+ void setSubtreeBlocked(bool blocked);
+ bool visible() const;
+ void setVisible(bool visible);
+
+ bool m_blocked : 1;
+ bool m_visible : 1;
+};
+class Q_LOCATION_PRIVATE_EXPORT MapItemGeometryNode : public QSGGeometryNode, public VisibleNode
+{
+public:
+ ~MapItemGeometryNode() override;
+ bool isSubtreeBlocked() const override;
+};
+
+class Q_LOCATION_PRIVATE_EXPORT MapPolylineNode : public MapItemGeometryNode
+{
public:
MapPolylineNode();
- ~MapPolylineNode();
+ ~MapPolylineNode() override;
void update(const QColor &fillColor, const QGeoMapItemGeometry *shape);
- bool isSubtreeBlocked() const override;
private:
QSGFlatColorMaterial fill_material_;
QSGGeometry geometry_;
- bool blocked_;
};
QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qgeomapobject.cpp b/src/location/declarativemaps/qgeomapobject.cpp
index 391ac04c..9a2e37bd 100644
--- a/src/location/declarativemaps/qgeomapobject.cpp
+++ b/src/location/declarativemaps/qgeomapobject.cpp
@@ -198,8 +198,8 @@ void QGeoMapObject::setMap(QGeoMap *map)
// old implementation gets destroyed if/when d_ptr gets replaced
d_ptr->m_componentCompleted = oldCmponentCompleted;
d_ptr->setVisible(oldVisible);
+ d_ptr->setMap(map);
}
- d_ptr->setMap(map);
const QList<QGeoMapObject *> kids = geoMapObjectChildren();
for (auto kid : kids)
@@ -207,7 +207,8 @@ void QGeoMapObject::setMap(QGeoMap *map)
// Each subclass is in charge to do the equivalent of
// if (!map) {
- // // Map was set, now it has ben re-set to NULL
+ // // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
+ // // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
// d_ptr = new QMapCircleObjectPrivateDefault(*d);
// // Old pimpl deleted implicitly by QExplicitlySharedDataPointer
// }
diff --git a/src/location/labs/qgeotiledmaplabs.cpp b/src/location/labs/qgeotiledmaplabs.cpp
index 2e4b2c16..22d582c0 100644
--- a/src/location/labs/qgeotiledmaplabs.cpp
+++ b/src/location/labs/qgeotiledmaplabs.cpp
@@ -42,26 +42,20 @@
#include <QtLocation/private/qmapcircleobjectqsg_p_p.h>
#include <QtLocation/private/qmaprouteobjectqsg_p_p.h>
#include <QtLocation/private/qmapiconobjectqsg_p_p.h>
+#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
+#include <QtLocation/private/qgeomapobjectqsgsupport_p.h>
QT_BEGIN_NAMESPACE
-struct MapObject {
- MapObject(QPointer<QGeoMapObject> &o, QQSGMapObject *sgo)
- : object(o), sgObject(sgo) {}
- QPointer<QGeoMapObject> object;
- QQSGMapObject *sgObject = nullptr;
-};
-
class QGeoTiledMapLabsPrivate : public QGeoTiledMapPrivate
{
Q_DECLARE_PUBLIC(QGeoTiledMapLabs)
public:
- QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine);
+ QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine, QGeoTiledMapLabs *map);
virtual ~QGeoTiledMapLabsPrivate();
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);
@@ -72,14 +66,13 @@ protected:
void changeCameraData(const QGeoCameraData &oldCameraData) override;
void changeActiveMapType(const QGeoMapType mapType) override;
- QList<MapObject> m_mapObjects;
- QList<MapObject> m_pendingMapObjects;
+ QGeoMapObjectQSGSupport m_qsgSupport;
};
-QGeoTiledMapLabsPrivate::QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine)
+QGeoTiledMapLabsPrivate::QGeoTiledMapLabsPrivate(QGeoTiledMappingManagerEngine *engine, QGeoTiledMapLabs *map)
: QGeoTiledMapPrivate(engine)
{
-
+ m_qsgSupport.m_map = map;
}
QGeoTiledMapLabsPrivate::~QGeoTiledMapLabsPrivate()
@@ -89,136 +82,27 @@ QGeoTiledMapLabsPrivate::~QGeoTiledMapLabsPrivate()
QGeoMapObjectPrivate *QGeoTiledMapLabsPrivate::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;
+ return m_qsgSupport.createMapObjectImplementationPrivate(obj);
}
QList<QGeoMapObject *> QGeoTiledMapLabsPrivate::mapObjects() const
{
- return QList<QGeoMapObject *>();
-}
-
-int QGeoTiledMapLabsPrivate::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;
+ return m_qsgSupport.mapObjects();
}
void QGeoTiledMapLabsPrivate::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.
- }
- }
+ m_qsgSupport.removeMapObject(obj);
}
void QGeoTiledMapLabsPrivate::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);
+ m_qsgSupport.updateMapObjects(root, window);
}
void QGeoTiledMapLabsPrivate::updateObjectsGeometry()
{
- Q_Q(QGeoTiledMapLabs);
- 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();
+ m_qsgSupport.updateObjectsGeometry();
}
void QGeoTiledMapLabsPrivate::changeViewportSize(const QSize &size)
@@ -247,7 +131,7 @@ void QGeoTiledMapLabsPrivate::changeActiveMapType(const QGeoMapType mapType)
QGeoTiledMapLabs::QGeoTiledMapLabs(QGeoTiledMappingManagerEngine *engine, QObject *parent)
- : QGeoTiledMap(*new QGeoTiledMapLabsPrivate(engine), engine, parent)
+ : QGeoTiledMap(*new QGeoTiledMapLabsPrivate(engine, this), engine, parent)
{
}
@@ -260,15 +144,7 @@ QGeoTiledMapLabs::~QGeoTiledMapLabs()
bool QGeoTiledMapLabs::createMapObjectImplementation(QGeoMapObject *obj)
{
Q_D(QGeoTiledMapLabs);
- QExplicitlySharedDataPointer<QGeoMapObjectPrivate> pimpl =
- QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(d->createMapObjectImplementation(obj));
- if (pimpl.constData()) {
- bool res = obj->setImplementation(pimpl);
- if (res)
- emit sgNodeChanged();
- return res;
- }
- return false;
+ return d->m_qsgSupport.createMapObjectImplementation(obj, d);
}
QSGNode *QGeoTiledMapLabs::updateSceneGraph(QSGNode *node, QQuickWindow *window)
diff --git a/src/location/labs/qgeotiledmaplabs_p.h b/src/location/labs/qgeotiledmaplabs_p.h
index f6499784..4f179028 100644
--- a/src/location/labs/qgeotiledmaplabs_p.h
+++ b/src/location/labs/qgeotiledmaplabs_p.h
@@ -71,10 +71,10 @@ public:
virtual ~QGeoTiledMapLabs();
bool createMapObjectImplementation(QGeoMapObject *obj) override;
+ void removeMapObject(QGeoMapObject *obj) override;
protected:
QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) override;
- void removeMapObject(QGeoMapObject *obj) override;
QSGClipNode *m_clip = nullptr;
QSGSimpleRectNode *m_simpleRectNode = nullptr;
diff --git a/src/location/labs/qmapcircleobject.cpp b/src/location/labs/qmapcircleobject.cpp
index 735ece5c..d7f1d58f 100644
--- a/src/location/labs/qmapcircleobject.cpp
+++ b/src/location/labs/qmapcircleobject.cpp
@@ -278,7 +278,8 @@ void QMapCircleObject::setMap(QGeoMap *map)
QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
if (!map) {
- // Map was set, now it has ben re-set to NULL
+ // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
+ // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
d_ptr = new QMapCircleObjectPrivateDefault(*d);
// Old pimpl deleted implicitly by QExplicitlySharedDataPointer
}
diff --git a/src/location/labs/qmapiconobject.cpp b/src/location/labs/qmapiconobject.cpp
index 507492d2..be82ebbf 100644
--- a/src/location/labs/qmapiconobject.cpp
+++ b/src/location/labs/qmapiconobject.cpp
@@ -236,7 +236,8 @@ void QMapIconObject::setMap(QGeoMap *map)
QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
if (!map) {
- // Map was set, now it has ben re-set to NULL
+ // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
+ // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
d_ptr = new QMapIconObjectPrivateDefault(*d);
// Old pimpl deleted implicitly by QExplicitlySharedDataPointer
}
diff --git a/src/location/labs/qmapobjectview.cpp b/src/location/labs/qmapobjectview.cpp
index e1161acd..175e7cc4 100644
--- a/src/location/labs/qmapobjectview.cpp
+++ b/src/location/labs/qmapobjectview.cpp
@@ -144,37 +144,6 @@ QList<QGeoMapObject *> QMapObjectView::geoMapObjectChildren() const
return kids;
}
-void QMapObjectView::setMap(QGeoMap *map)
-{
- QMapObjectViewPrivate *d = static_cast<QMapObjectViewPrivate *>(d_ptr.data());
- if (d->m_map == map)
- return;
-
- QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
-
- for (int i = 0; i < m_userAddedMapObjects.size(); ++i) {
- auto obj = m_userAddedMapObjects.at(i);
- if (obj && obj->map() != map)
- obj->setMap(map);
- }
-
- if (!map) {
- // Map was set, now it has ben re-set to NULL
- flushDelegateModel();
- flushUserAddedMapObjects();
- d_ptr = new QMapObjectViewPrivateDefault(*d);
- } else if (d->m_componentCompleted) {
- // Map was null, now it's set AND delegateModel is already complete.
- // some delegates may have been incubated but not added to the map.
- for (int i = 0; i < m_pendingMapObjects.size(); ++i) {
- auto obj = m_pendingMapObjects.at(i);
- if (obj && obj->map() != map)
- obj->setMap(map);
- }
- m_pendingMapObjects.clear();
- }
-}
-
void QMapObjectView::classBegin()
{
QQmlContext *ctx = qmlContext(this);
@@ -381,5 +350,36 @@ void QMapObjectView::flushUserAddedMapObjects()
}
}
+void QMapObjectView::setMap(QGeoMap *map)
+{
+ QMapObjectViewPrivate *d = static_cast<QMapObjectViewPrivate *>(d_ptr.data());
+ if (d->m_map == map)
+ return;
+
+ QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
+
+ for (int i = 0; i < m_userAddedMapObjects.size(); ++i) {
+ auto obj = m_userAddedMapObjects.at(i);
+ if (obj && obj->map() != map)
+ obj->setMap(map);
+ }
+
+ if (!map) {
+ // Map was set, now it has ben re-set to NULL
+ flushDelegateModel();
+ flushUserAddedMapObjects();
+ d_ptr = new QMapObjectViewPrivateDefault(*d);
+ } else if (d->m_componentCompleted) {
+ // Map was null, now it's set AND delegateModel is already complete.
+ // some delegates may have been incubated but not added to the map.
+ for (int i = 0; i < m_pendingMapObjects.size(); ++i) {
+ auto obj = m_pendingMapObjects.at(i);
+ if (obj && obj->map() != map)
+ obj->setMap(map);
+ }
+ m_pendingMapObjects.clear();
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/location/labs/qmappolygonobject.cpp b/src/location/labs/qmappolygonobject.cpp
index adc3259f..1d495899 100644
--- a/src/location/labs/qmappolygonobject.cpp
+++ b/src/location/labs/qmappolygonobject.cpp
@@ -246,7 +246,8 @@ void QMapPolygonObject::setMap(QGeoMap *map)
QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
if (!map) {
- // Map was set, now it has ben re-set to NULL
+ // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
+ // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
d_ptr = new QMapPolygonObjectPrivateDefault(*d);
// Old pimpl deleted implicitly by QExplicitlySharedDataPointer
}
diff --git a/src/location/labs/qmappolylineobject.cpp b/src/location/labs/qmappolylineobject.cpp
index bea79327..1c351962 100644
--- a/src/location/labs/qmappolylineobject.cpp
+++ b/src/location/labs/qmappolylineobject.cpp
@@ -209,7 +209,8 @@ void QMapPolylineObject::setMap(QGeoMap *map)
QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
if (!map) {
- // Map was set, now it has ben re-set to NULL
+ // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
+ // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
d_ptr = new QMapPolylineObjectPrivateDefault(*d);
// Old pimpl deleted implicitly by QExplicitlySharedDataPointer
}
diff --git a/src/location/labs/qmaprouteobject.cpp b/src/location/labs/qmaprouteobject.cpp
index 7e36322c..c3365d30 100644
--- a/src/location/labs/qmaprouteobject.cpp
+++ b/src/location/labs/qmaprouteobject.cpp
@@ -170,7 +170,8 @@ void QMapRouteObject::setMap(QGeoMap *map)
QGeoMapObject::setMap(map); // This is where the specialized pimpl gets created and injected
if (!map) {
- // Map was set, now it has ben re-set to NULL
+ // Map was set, now it has ben re-set to NULL, but not inside d_ptr.
+ // so m_map inside d_ptr can still be used to remove itself, inside the destructor.
d_ptr = new QMapRouteObjectPrivate(*d);
// Old pimpl deleted implicitly by QExplicitlySharedDataPointer
}
diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
new file mode 100644
index 00000000..e0e3a6d7
--- /dev/null
+++ b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgeomapobjectqsgsupport_p.h"
+#include <QtLocation/private/qgeomap_p_p.h>
+
+QT_BEGIN_NAMESPACE
+
+static int 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;
+}
+
+bool QGeoMapObjectQSGSupport::createMapObjectImplementation(QGeoMapObject *obj, QGeoMapPrivate *d)
+{
+ QExplicitlySharedDataPointer<QGeoMapObjectPrivate> pimpl =
+ QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(d->createMapObjectImplementation(obj));
+ if (pimpl.constData()) {
+ bool res = obj->setImplementation(pimpl);
+ if (res)
+ emit m_map->sgNodeChanged();
+ return res;
+ }
+ return false;
+}
+
+QGeoMapObjectPrivate *QGeoMapObjectQSGSupport::createMapObjectImplementationPrivate(QGeoMapObject *obj)
+{
+ QGeoMapObjectPrivate *res = nullptr;
+
+ {
+ QQSGMapObject *sgo = nullptr;
+ switch (obj->type()) {
+ case QGeoMapObject::PolylineType: {
+ QMapPolylineObjectPrivate &oldImpl = static_cast<QMapPolylineObjectPrivate &>(*obj->implementation());
+ QMapPolylineObjectPrivateQSG *pimpl =
+ new QMapPolylineObjectPrivateQSG(oldImpl);
+ sgo = pimpl;
+ res = pimpl;
+ break;
+ }
+ case QGeoMapObject::PolygonType: {
+ QMapPolygonObjectPrivate &oldImpl = static_cast<QMapPolygonObjectPrivate &>(*obj->implementation());
+ QMapPolygonObjectPrivateQSG *pimpl =
+ new QMapPolygonObjectPrivateQSG(oldImpl);
+ sgo = pimpl;
+ res = pimpl;
+ break;
+ }
+ case QGeoMapObject::CircleType: {
+ QMapCircleObjectPrivate &oldImpl = static_cast<QMapCircleObjectPrivate &>(*obj->implementation());
+ QMapCircleObjectPrivateQSG *pimpl =
+ new QMapCircleObjectPrivateQSG(oldImpl);
+ sgo = pimpl;
+ res = pimpl;
+ break;
+ }
+ case QGeoMapObject::RouteType: {
+ QMapRouteObjectPrivate &oldImpl = static_cast<QMapRouteObjectPrivate &>(*obj->implementation());
+ QMapRouteObjectPrivateQSG *pimpl =
+ new QMapRouteObjectPrivateQSG(oldImpl);
+ sgo = pimpl;
+ res = pimpl;
+ break;
+ }
+ case QGeoMapObject::IconType: {
+ QMapIconObjectPrivate &oldImpl = static_cast<QMapIconObjectPrivate &>(*obj->implementation());
+ QMapIconObjectPrivateQSG *pimpl =
+ new QMapIconObjectPrivateQSG(oldImpl);
+ sgo = pimpl;
+ res = pimpl;
+ break;
+ }
+ default:
+ // Use the following warning only for debugging purposes.
+ // qWarning() << "QGeoMapObjectQSGSupport::createMapObjectImplementationPrivate: not instantiating pimpl for unsupported object type " << obj->type();
+ break;
+ }
+
+ if (res) {
+ QPointer<QGeoMapObject> p(obj);
+ MapObject mo(p, sgo);
+ m_pendingMapObjects << mo;
+ }
+ }
+ return res;
+}
+
+QList<QGeoMapObject *> QGeoMapObjectQSGSupport::mapObjects() const
+{
+ return QList<QGeoMapObject *>();
+}
+
+void QGeoMapObjectQSGSupport::removeMapObject(QGeoMapObject *obj)
+{
+ int idx = findMapObject(obj, m_mapObjects);
+ if (idx >= 0) {
+ const MapObject &mo = m_mapObjects.takeAt(idx);
+ obj->disconnect(m_map);
+ m_removedMapObjects << mo;
+ emit m_map->sgNodeChanged();
+ } else {
+ idx = findMapObject(obj, m_pendingMapObjects);
+ if (idx >= 0) {
+ m_pendingMapObjects.removeAt(idx);
+ obj->disconnect(m_map);
+ } else {
+ // obj not here.
+ }
+ }
+}
+
+void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *window)
+{
+ for (int i = 0; i < m_removedMapObjects.size(); ++i) {
+ MapObject mo = m_removedMapObjects[i];
+ if (mo.qsgNode) {
+ root->removeChildNode(mo.qsgNode);
+ delete mo.qsgNode;
+ mo.qsgNode = nullptr;
+ // mo.sgObject is now invalid as it is destroyed right after appending
+ // mo to m_removedMapObjects
+ }
+ }
+ m_removedMapObjects.clear();
+
+ for (int i = 0; i < m_mapObjects.size(); ++i) {
+ // already added as node
+ if (Q_UNLIKELY(!m_mapObjects.at(i).object)) {
+ qWarning() << "unexpected NULL pointer in m_mapObjects at "<<i;
+ continue;
+ }
+
+ MapObject &mo = m_mapObjects[i];
+ QQSGMapObject *sgo = mo.sgObject;
+ QSGNode *oldNode = mo.qsgNode;
+ mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, root, window);
+ if (Q_UNLIKELY(!mo.qsgNode)) {
+ qWarning() << "updateMapObjectNode for "<<mo.object->type() << " returned NULL";
+ } else if (mo.visibleNode && (mo.visibleNode->visible() != mo.object->visible())) {
+ mo.visibleNode->setVisible(mo.object->visible());
+ mo.qsgNode->markDirty(QSGNode::DirtySubtreeBlocked);
+ }
+ }
+
+ QList<int> toRemove;
+ for (int i = 0; i < m_pendingMapObjects.size(); ++i) {
+ // already added as node
+ MapObject &mo = m_pendingMapObjects[i];
+ QQSGMapObject *sgo = mo.sgObject;
+ QSGNode *oldNode = mo.qsgNode;
+ sgo->updateGeometry(); // or subtree will be blocked
+ mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, root, window);
+ if (mo.qsgNode) {
+ if (mo.visibleNode && (mo.visibleNode->visible() != mo.object->visible())) {
+ mo.visibleNode->setVisible(mo.object->visible());
+ mo.qsgNode->markDirty(QSGNode::DirtySubtreeBlocked);
+ }
+ m_mapObjects << mo;
+ toRemove.push_front(i);
+ QObject::connect(mo.object, SIGNAL(visibleChanged()), m_map, SIGNAL(sgNodeChanged()));
+ } else {
+ // leave it to be processed, don't spit warnings
+ }
+ }
+
+ for (int i: qAsConst(toRemove))
+ m_pendingMapObjects.removeAt(i);
+}
+
+void QGeoMapObjectQSGSupport::updateObjectsGeometry()
+{
+ for (int i = 0; i < m_mapObjects.size(); ++i) {
+ // already added as node
+ if (Q_UNLIKELY(!m_mapObjects.at(i).object)) {
+ qWarning() << "unexpected NULL pointer in m_mapObjects at "<<i;
+ continue;
+ }
+
+ QQSGMapObject *sgo = m_mapObjects.at(i).sgObject;
+ sgo->updateGeometry();
+ }
+ emit m_map->sgNodeChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h b/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h
new file mode 100644
index 00000000..bb0477c5
--- /dev/null
+++ b/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGEOMAPOBJECTQSGSUPPORT_P_H
+#define QGEOMAPOBJECTQSGSUPPORT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtLocation/private/qlocationglobal_p.h>
+#include <QtLocation/private/qgeomapobject_p.h>
+#include <QtLocation/private/qgeomapobject_p_p.h>
+#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>
+#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
+#include <QtCore/qpointer.h>
+
+QT_BEGIN_NAMESPACE
+
+struct Q_LOCATION_PRIVATE_EXPORT MapObject {
+ MapObject(QPointer<QGeoMapObject> &o, QQSGMapObject *sgo)
+ : object(o), sgObject(sgo) {}
+
+ QPointer<QGeoMapObject> object;
+ QQSGMapObject *sgObject = nullptr; // this is a QMap*ObjectPrivateQSG. it becomes invalid when the pimpl is destroyed
+ VisibleNode *visibleNode = nullptr; // This is a Map*Node (like a MapPolygonNode) that is a QSGNode. This doesn't disappear by itself
+ QSGNode *qsgNode = nullptr;
+};
+
+class Q_LOCATION_PRIVATE_EXPORT QGeoMapObjectQSGSupport
+{
+public:
+ bool createMapObjectImplementation(QGeoMapObject *obj, QGeoMapPrivate *d);
+ QGeoMapObjectPrivate *createMapObjectImplementationPrivate(QGeoMapObject *obj);
+ QList<QGeoMapObject *> mapObjects() const;
+ void removeMapObject(QGeoMapObject *obj);
+ void updateMapObjects(QSGNode *root, QQuickWindow *window);
+ void updateObjectsGeometry();
+
+ QList<MapObject> m_mapObjects;
+ QList<MapObject> m_pendingMapObjects;
+ QList<MapObject> m_removedMapObjects;
+ QGeoMap *m_map = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOMAPOBJECTQSGSUPPORT_P_H
diff --git a/src/location/labs/qsg/qmapcircleobjectqsg.cpp b/src/location/labs/qsg/qmapcircleobjectqsg.cpp
index 9fe3ee0a..775016b9 100644
--- a/src/location/labs/qsg/qmapcircleobjectqsg.cpp
+++ b/src/location/labs/qsg/qmapcircleobjectqsg.cpp
@@ -60,7 +60,8 @@ QMapCircleObjectPrivateQSG::QMapCircleObjectPrivateQSG(const QMapCircleObjectPri
QMapCircleObjectPrivateQSG::~QMapCircleObjectPrivateQSG()
{
-
+ if (m_map)
+ m_map->removeMapObject(q);
}
void QMapCircleObjectPrivateQSG::updateCirclePath()
@@ -147,13 +148,18 @@ QGeoMapObjectPrivate *QMapCircleObjectPrivateQSG::clone()
return new QMapCircleObjectPrivateQSG(static_cast<QMapCircleObjectPrivate &>(*this));
}
-QSGNode *QMapCircleObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * /*window*/)
+QSGNode *QMapCircleObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow * /*window*/)
{
+// Q_UNUSED(visibleNode) // coz of -Werror=unused-but-set-parameter
MapPolygonNode *node = static_cast<MapPolygonNode *>(oldNode);
bool created = false;
if (!node) {
node = new MapPolygonNode();
+ *visibleNode = static_cast<VisibleNode *>(node);
created = true;
}
diff --git a/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h b/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h
index 17d8568a..4e8162fa 100644
--- a/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmapcircleobjectqsg_p_p.h
@@ -72,7 +72,10 @@ public:
// QQSGMapObject
void updateGeometry() override;
- QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override;
+ QSGNode *updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window) override;
// QGeoMapCirclePrivate interface
void setCenter(const QGeoCoordinate &center) override;
diff --git a/src/location/labs/qsg/qmapiconobjectqsg.cpp b/src/location/labs/qsg/qmapiconobjectqsg.cpp
index 53d16179..47c39695 100644
--- a/src/location/labs/qsg/qmapiconobjectqsg.cpp
+++ b/src/location/labs/qsg/qmapiconobjectqsg.cpp
@@ -43,26 +43,19 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqml.h>
#include <QtNetwork/qnetworkaccessmanager.h>
+#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
QT_BEGIN_NAMESPACE
-class RootNode : public QSGTransformNode
+class RootNode : public QSGTransformNode, public VisibleNode
{
public:
- RootNode() : QSGTransformNode()
- { }
+ RootNode() { }
bool isSubtreeBlocked() const override
{
- return m_blocked;
+ return subtreeBlocked();
}
-
- void setSubtreeBlocked(bool blocked)
- {
- m_blocked = blocked;
- }
-
- bool m_blocked = false;
};
QMapIconObjectPrivateQSG::QMapIconObjectPrivateQSG(QGeoMapObject *q)
@@ -80,7 +73,8 @@ QMapIconObjectPrivateQSG::QMapIconObjectPrivateQSG(const QMapIconObjectPrivate &
QMapIconObjectPrivateQSG::~QMapIconObjectPrivateQSG()
{
-
+ if (m_map)
+ m_map->removeMapObject(q);
}
void QMapIconObjectPrivateQSG::updateGeometry()
@@ -100,8 +94,12 @@ void QMapIconObjectPrivateQSG::updateGeometry()
// TODO: support and test for zoomLevel
}
-QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode * root, QQuickWindow *window)
+QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window)
{
+ Q_UNUSED(visibleNode)
bool created = false;
RootNode *node = static_cast<RootNode *>(oldNode);
if (!node) {
@@ -109,6 +107,7 @@ QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode
m_imageNode = window->createImageNode();
m_imageNode->setOwnsTexture(true);
node->appendChildNode(m_imageNode);
+ *visibleNode = static_cast<VisibleNode *>(node);
created = true;
}
diff --git a/src/location/labs/qsg/qmapiconobjectqsg_p_p.h b/src/location/labs/qsg/qmapiconobjectqsg_p_p.h
index a2f7cf40..c57828af 100644
--- a/src/location/labs/qsg/qmapiconobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmapiconobjectqsg_p_p.h
@@ -69,7 +69,10 @@ public:
// QQSGMapObject
void updateGeometry() override;
- QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override;
+ QSGNode *updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window) override;
// QGeoMapIconPrivate interface
void setCoordinate(const QGeoCoordinate &coordinate) override;
diff --git a/src/location/labs/qsg/qmappolygonobjectqsg.cpp b/src/location/labs/qsg/qmappolygonobjectqsg.cpp
index 27dcc80f..b9602a3a 100644
--- a/src/location/labs/qsg/qmappolygonobjectqsg.cpp
+++ b/src/location/labs/qsg/qmappolygonobjectqsg.cpp
@@ -57,7 +57,8 @@ QMapPolygonObjectPrivateQSG::QMapPolygonObjectPrivateQSG(const QMapPolygonObject
QMapPolygonObjectPrivateQSG::~QMapPolygonObjectPrivateQSG()
{
-
+ if (m_map)
+ m_map->removeMapObject(q);
}
QList<QDoubleVector2D> QMapPolygonObjectPrivateQSG::projectPath()
@@ -74,13 +75,18 @@ QList<QDoubleVector2D> QMapPolygonObjectPrivateQSG::projectPath()
return geopathProjected_;
}
-QSGNode *QMapPolygonObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * /*window*/)
+QSGNode *QMapPolygonObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow */*window*/)
{
+ Q_UNUSED(visibleNode)
MapPolygonNode *node = static_cast<MapPolygonNode *>(oldNode);
bool created = false;
if (!node) {
node = new MapPolygonNode();
+ *visibleNode = static_cast<VisibleNode *>(node);
created = true;
}
diff --git a/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h b/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h
index bd5efcff..b288528a 100644
--- a/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h
@@ -68,7 +68,10 @@ public:
// QQSGMapObject
void updateGeometry() override;
- QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override;
+ QSGNode *updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window) override;
// QGeoMapPolylinePrivate interface
QList<QGeoCoordinate> path() const override;
diff --git a/src/location/labs/qsg/qmappolylineobjectqsg.cpp b/src/location/labs/qsg/qmappolylineobjectqsg.cpp
index c0c3854e..6b782c77 100644
--- a/src/location/labs/qsg/qmappolylineobjectqsg.cpp
+++ b/src/location/labs/qsg/qmappolylineobjectqsg.cpp
@@ -61,7 +61,8 @@ QMapPolylineObjectPrivateQSG::QMapPolylineObjectPrivateQSG(const QMapPolylineObj
QMapPolylineObjectPrivateQSG::~QMapPolylineObjectPrivateQSG()
{
-
+ if (m_map)
+ m_map->removeMapObject(q);
}
QList<QDoubleVector2D> QMapPolylineObjectPrivateQSG::projectPath()
@@ -96,13 +97,18 @@ void QMapPolylineObjectPrivateQSG::updateGeometry()
m_geometry.translate(origin - m_geometry.firstPointOffset());
}
-QSGNode *QMapPolylineObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * /*window*/)
+QSGNode *QMapPolylineObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow */*window*/)
{
+ Q_UNUSED(visibleNode)
MapPolylineNode *node = static_cast<MapPolylineNode *>(oldNode);
bool created = false;
if (!node) {
node = new MapPolylineNode();
+ *visibleNode = static_cast<VisibleNode *>(node);
created = true;
}
diff --git a/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h b/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h
index 52b5e89a..792413e5 100644
--- a/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h
@@ -68,7 +68,10 @@ public:
// QQSGMapObject
void updateGeometry() override;
- QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override;
+ QSGNode *updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window) override;
// QGeoMapPolylinePrivate interface
QList<QGeoCoordinate> path() const override;
diff --git a/src/location/labs/qsg/qmaprouteobjectqsg.cpp b/src/location/labs/qsg/qmaprouteobjectqsg.cpp
index a8728e08..eaea64f3 100644
--- a/src/location/labs/qsg/qmaprouteobjectqsg.cpp
+++ b/src/location/labs/qsg/qmaprouteobjectqsg.cpp
@@ -57,7 +57,8 @@ QMapRouteObjectPrivateQSG::QMapRouteObjectPrivateQSG(const QMapRouteObjectPrivat
QMapRouteObjectPrivateQSG::~QMapRouteObjectPrivateQSG()
{
-
+ if (m_map)
+ m_map->removeMapObject(q);
}
void QMapRouteObjectPrivateQSG::updateGeometry()
@@ -65,9 +66,12 @@ void QMapRouteObjectPrivateQSG::updateGeometry()
m_polyline->updateGeometry();
}
-QSGNode *QMapRouteObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow * window)
+QSGNode *QMapRouteObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window)
{
- return m_polyline->updateMapObjectNode(oldNode, root, window);
+ return m_polyline->updateMapObjectNode(oldNode, visibleNode, root, window);
}
void QMapRouteObjectPrivateQSG::setRoute(const QDeclarativeGeoRoute *route)
diff --git a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h
index 1c612532..0c946259 100644
--- a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h
@@ -68,7 +68,10 @@ public:
// QQSGMapObject
void updateGeometry() override;
- QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window) override;
+ QSGNode *updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window) override;
// QMapRouteObjectPrivate interface
void setRoute(const QDeclarativeGeoRoute *route) override;
diff --git a/src/location/labs/qsg/qqsgmapobject.cpp b/src/location/labs/qsg/qqsgmapobject.cpp
index 5b4f7dbf..ccda12d8 100644
--- a/src/location/labs/qsg/qqsgmapobject.cpp
+++ b/src/location/labs/qsg/qqsgmapobject.cpp
@@ -35,6 +35,7 @@
****************************************************************************/
#include "qqsgmapobject_p.h"
+#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -48,7 +49,10 @@ QQSGMapObject::~QQSGMapObject()
}
-QSGNode *QQSGMapObject::updateMapObjectNode(QSGNode *oldNode, QSGNode * /*root*/, QQuickWindow * /*window*/)
+QSGNode *QQSGMapObject::updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **/*visibleNode*/,
+ QSGNode * /*root*/,
+ QQuickWindow * /*window*/)
{
delete oldNode;
return 0;
diff --git a/src/location/labs/qsg/qqsgmapobject_p.h b/src/location/labs/qsg/qqsgmapobject_p.h
index d3e54a68..1aecc990 100644
--- a/src/location/labs/qsg/qqsgmapobject_p.h
+++ b/src/location/labs/qsg/qqsgmapobject_p.h
@@ -40,6 +40,7 @@
#include <QtLocation/private/qlocationglobal_p.h>
#include <QtQuick/QSGOpacityNode>
#include <QtLocation/private/qgeomapobject_p.h>
+#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
QT_BEGIN_NAMESPACE
@@ -50,10 +51,11 @@ public:
QQSGMapObject();
virtual ~QQSGMapObject();
- virtual QSGNode *updateMapObjectNode(QSGNode *oldNode, QSGNode *root, QQuickWindow *window);
+ virtual QSGNode *updateMapObjectNode(QSGNode *oldNode,
+ VisibleNode **visibleNode,
+ QSGNode *root,
+ QQuickWindow *window);
virtual void updateGeometry();
-
- QSGNode *node = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index e67340be..f6be5cae 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -151,13 +151,13 @@ public:
virtual bool fitViewportToGeoRectangle(const QGeoRectangle &rectangle);
virtual void setCopyrightVisible(bool visible);
+ virtual void removeMapObject(QGeoMapObject *obj);
protected:
QGeoMap(QGeoMapPrivate &dd, QObject *parent = 0);
void setCameraData(const QGeoCameraData &cameraData);
void setCameraCapabilities(const QGeoCameraCapabilities &cameraCapabilities);
virtual QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) = 0;
- virtual void removeMapObject(QGeoMapObject *obj);
Q_SIGNALS:
void cameraDataChanged(const QGeoCameraData &cameraData);
diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h
index 18c72202..47780c47 100644
--- a/src/location/maps/qgeomap_p_p.h
+++ b/src/location/maps/qgeomap_p_p.h
@@ -80,6 +80,7 @@ public:
const QGeoCameraCapabilities &cameraCapabilities() const;
static const QGeoMapPrivate *get(const QGeoMap &map);
+ virtual QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj);
protected:
/* Hooks into the actual map implementations */
@@ -90,7 +91,6 @@ protected:
virtual void addMapItem(QDeclarativeGeoMapItemBase *item);
virtual void removeMapItem(QDeclarativeGeoMapItemBase *item);
- virtual QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj);
virtual QList<QGeoMapObject *> mapObjects() const;
virtual void changeViewportSize(const QSize &size) = 0; // called by QGeoMap::setSize()
diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp
index 99146801..af0e263b 100644
--- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp
+++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.cpp
@@ -47,12 +47,8 @@
#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;
-};
+#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
+#include <QtLocation/private/qgeomapobjectqsgsupport_p.h>
#endif
QT_BEGIN_NAMESPACE
@@ -61,18 +57,16 @@ class QGeoMapItemsOverlayPrivate : public QGeoMapPrivate
{
Q_DECLARE_PUBLIC(QGeoMapItemsOverlay)
public:
- QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine);
+ QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine, QGeoMapItemsOverlay *map);
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;
+ QGeoMapObjectQSGSupport m_qsgSupport;
#endif
void updateObjectsGeometry();
@@ -83,7 +77,7 @@ protected:
};
QGeoMapItemsOverlay::QGeoMapItemsOverlay(QGeoMappingManagerEngineItemsOverlay *engine, QObject *parent)
- : QGeoMap(*(new QGeoMapItemsOverlayPrivate(engine)), parent)
+ : QGeoMap(*(new QGeoMapItemsOverlayPrivate(engine, this)), parent)
{
}
@@ -99,6 +93,16 @@ QGeoMap::Capabilities QGeoMapItemsOverlay::capabilities() const
| SupportsAnchoringCoordinate);
}
+bool QGeoMapItemsOverlay::createMapObjectImplementation(QGeoMapObject *obj)
+{
+#ifndef LOCATIONLABS
+ return false;
+#else
+ Q_D(QGeoMapItemsOverlay);
+ return d->m_qsgSupport.createMapObjectImplementation(obj, d);
+#endif
+}
+
QSGNode *QGeoMapItemsOverlay::updateSceneGraph(QSGNode *node, QQuickWindow *window)
{
#ifndef LOCATIONLABS
@@ -119,9 +123,18 @@ QSGNode *QGeoMapItemsOverlay::updateSceneGraph(QSGNode *node, QQuickWindow *wind
#endif
}
-QGeoMapItemsOverlayPrivate::QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine)
+void QGeoMapItemsOverlay::removeMapObject(QGeoMapObject *obj)
+{
+#ifdef LOCATIONLABS
+ Q_D(QGeoMapItemsOverlay);
+ d->removeMapObject(obj);
+#endif
+}
+
+QGeoMapItemsOverlayPrivate::QGeoMapItemsOverlayPrivate(QGeoMappingManagerEngineItemsOverlay *engine, QGeoMapItemsOverlay *map)
: QGeoMapPrivate(engine, new QGeoProjectionWebMercator)
{
+ m_qsgSupport.m_map = map;
}
QGeoMapItemsOverlayPrivate::~QGeoMapItemsOverlayPrivate()
@@ -131,138 +144,29 @@ QGeoMapItemsOverlayPrivate::~QGeoMapItemsOverlayPrivate()
#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;
+ return m_qsgSupport.createMapObjectImplementationPrivate(obj);
}
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;
+ return m_qsgSupport.mapObjects();
}
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.
- }
- }
+ m_qsgSupport.removeMapObject(obj);
}
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);
+ m_qsgSupport.updateMapObjects(root, window);
}
#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();
+ m_qsgSupport.updateObjectsGeometry();
#endif
}
diff --git a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h
index 42a59f06..1594ffb3 100644
--- a/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h
+++ b/src/plugins/geoservices/itemsoverlay/qgeomapitemsoverlay.h
@@ -54,6 +54,8 @@ public:
virtual ~QGeoMapItemsOverlay();
QGeoMap::Capabilities capabilities() const override;
+ bool createMapObjectImplementation(QGeoMapObject *obj) override;
+ void removeMapObject(QGeoMapObject *obj) override;
protected:
QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) override;