summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2022-11-30 12:12:03 +0100
committerMatthias Rauter <matthias.rauter@qt.io>2023-02-08 09:28:10 +0100
commit34fccf47ecf8ab2db53b23013f4f402c175ce9de (patch)
tree48d3ad9eb9d7568e29f0877e8ed9d49da98b6ce1
parentcd4db512ae08836f5fa1d746000052215cf70a9c (diff)
downloadqtlocation-34fccf47ecf8ab2db53b23013f4f402c175ce9de.tar.gz
Implement all four map items with Shape
With a master switch in qdeclarativegeomapitembase_p.h, this is enabled by default. For now the old method is still available by just commenting out the define. The old path can be removed in follow-up patches; for now keeping both so one can compare and debug if further issues arise. Pick-to: 6.5 Change-Id: I01c44ee8a07d7d5f7eb018be33ac5d161ba90e2a Reviewed-by: Matthias Rauter <matthias.rauter@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--CMakeLists.txt2
-rw-r--r--src/location/CMakeLists.txt1
-rw-r--r--src/location/quickmapitems/qdeclarativecirclemapitem.cpp115
-rw-r--r--src/location/quickmapitems/qdeclarativecirclemapitem_p_p.h20
-rw-r--r--src/location/quickmapitems/qdeclarativegeomapitembase.cpp22
-rw-r--r--src/location/quickmapitems/qdeclarativegeomapitembase_p.h29
-rw-r--r--src/location/quickmapitems/qdeclarativepolygonmapitem.cpp94
-rw-r--r--src/location/quickmapitems/qdeclarativepolygonmapitem_p_p.h28
-rw-r--r--src/location/quickmapitems/qdeclarativepolylinemapitem.cpp114
-rw-r--r--src/location/quickmapitems/qdeclarativepolylinemapitem_p_p.h22
-rw-r--r--src/location/quickmapitems/qdeclarativerectanglemapitem.cpp94
-rw-r--r--src/location/quickmapitems/qdeclarativerectanglemapitem_p_p.h26
-rw-r--r--src/location/quickmapitems/qgeomapitemgeometry.cpp2
-rw-r--r--src/location/quickmapitems/qgeomapitemgeometry_p.h6
14 files changed, 501 insertions, 74 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2c186a19..7bc5110f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,7 +28,7 @@ endif()
# Need to search for positioning only after we make sure that it's not WASM.
# Otherwise we'll get an "QtPositioning not found" error in WASM build.
find_package(Qt6 ${PROJECT_VERSION} CONFIG REQUIRED COMPONENTS
- Qml Quick Network Test QuickTest Positioning PositioningQuick
+ Qml Quick Network Test QuickTest Positioning PositioningQuick QuickShapesPrivate
)
find_package(Qt6 ${PROJECT_VERSION} QUIET CONFIG OPTIONAL_COMPONENTS
ShaderTools
diff --git a/src/location/CMakeLists.txt b/src/location/CMakeLists.txt
index e0eca263..dce71dfe 100644
--- a/src/location/CMakeLists.txt
+++ b/src/location/CMakeLists.txt
@@ -86,6 +86,7 @@ qt_internal_add_module(Location
Qt::Core
Qt::Positioning
Qt::PositioningQuick
+ Qt::QuickShapesPrivate
PRIVATE_MODULE_INTERFACE
Qt::CorePrivate
Qt::QuickPrivate
diff --git a/src/location/quickmapitems/qdeclarativecirclemapitem.cpp b/src/location/quickmapitems/qdeclarativecirclemapitem.cpp
index 5156b5e9..727e2eb0 100644
--- a/src/location/quickmapitems/qdeclarativecirclemapitem.cpp
+++ b/src/location/quickmapitems/qdeclarativecirclemapitem.cpp
@@ -16,6 +16,8 @@
#include <qmath.h>
#include <algorithm>
+#include <QtQuick/private/qquickitem_p.h>
+
QT_BEGIN_NAMESPACE
/*!
@@ -109,11 +111,12 @@ QGeoMapCircleGeometry::QGeoMapCircleGeometry()
/*!
\internal
*/
-void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map)
+void QGeoMapCircleGeometry::updateSourceAndScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map)
{
const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection());
// Not checking for !screenDirty anymore, as everything is now recalculated.
clear();
+ srcPath_ = QPainterPath();
if (map.viewportWidth() == 0 || map.viewportHeight() == 0 || circlePath.size() < 3) // a circle requires at least 3 points;
return;
@@ -187,23 +190,28 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D
//3)
const QDoubleVector2D origin = p.wrappedMapProjectionToItemPosition(lb);
- QPainterPath ppi;
for (const QList<QDoubleVector2D> &path: clippedPaths) {
QDoubleVector2D lastAddedPoint;
for (qsizetype i = 0; i < path.size(); ++i) {
QDoubleVector2D point = p.wrappedMapProjectionToItemPosition(path.at(i));
//point = point - origin; // Do this using ppi.translate()
+ const QDoubleVector2D pt = point - origin;
+ if (qMax(pt.x(), pt.y()) > maxCoord_)
+ maxCoord_ = qMax(pt.x(), pt.y());
+
if (i == 0) {
- ppi.moveTo(point.toPointF());
+ srcPath_.moveTo(point.toPointF());
lastAddedPoint = point;
} else if ((point - lastAddedPoint).manhattanLength() > 3 || i == path.size() - 1) {
- ppi.lineTo(point.toPointF());
+ srcPath_.lineTo(point.toPointF());
lastAddedPoint = point;
}
}
- ppi.closeSubpath();
+ srcPath_.closeSubpath();
}
+
+ QPainterPath ppi = srcPath_;
ppi.translate(-1 * origin.toPointF());
QTriangleSet ts = qTriangulate(ppi);
@@ -225,7 +233,7 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D
screenVertices_ << QPointF(vx[i], vx[i + 1]);
screenBounds_ = ppi.boundingRect();
- sourceBounds_ = screenBounds_;
+ sourceBounds_ = srcPath_.boundingRect();
}
QDeclarativeCircleMapItem::QDeclarativeCircleMapItem(QQuickItem *parent)
@@ -440,9 +448,36 @@ void QDeclarativeCircleMapItem::geometryChange(const QRectF &newGeometry, const
// call to this function.
}
-QDeclarativeCircleMapItemPrivate::~QDeclarativeCircleMapItemPrivate() {}
+QDeclarativeCircleMapItemPrivate::~QDeclarativeCircleMapItemPrivate()
+{
+}
+
+QDeclarativeCircleMapItemPrivateCPU::QDeclarativeCircleMapItemPrivateCPU(QDeclarativeCircleMapItem &circle)
+ : QDeclarativeCircleMapItemPrivate(circle)
+{
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape = new QQuickShape(&m_circle);
+ m_shape->setObjectName("_qt_map_item_shape");
+ m_shape->setZ(-1);
+ m_shape->setContainsMode(QQuickShape::FillContains);
+
+ m_shapePath = new QQuickShapePath(m_shape);
+ m_painterPath = new QDeclarativeGeoMapPainterPath(m_shapePath);
+
+ auto pathElements = m_shapePath->pathElements();
+ pathElements.append(&pathElements, m_painterPath);
-QDeclarativeCircleMapItemPrivateCPU::~QDeclarativeCircleMapItemPrivateCPU() {}
+ auto shapePaths = m_shape->data();
+ shapePaths.append(&shapePaths, m_shapePath);
+#endif
+}
+
+QDeclarativeCircleMapItemPrivateCPU::~QDeclarativeCircleMapItemPrivateCPU()
+{
+#ifdef MAPITEMS_USE_SHAPES
+ delete m_shape;
+#endif
+}
bool QDeclarativeCircleMapItemPrivate::preserveCircleGeometry (QList<QDoubleVector2D> &path,
const QGeoCoordinate &center, qreal distance, const QGeoProjectionWebMercator &p)
@@ -597,9 +632,13 @@ void QDeclarativeCircleMapItemPrivateCPU::updatePolish()
{
if (!m_circle.m_circle.isValid()) {
m_geometry.clear();
- m_borderGeometry.clear();
m_circle.setWidth(0);
m_circle.setHeight(0);
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape->setVisible(false);
+#else
+ m_borderGeometry.clear();
+#endif
return;
}
@@ -619,16 +658,18 @@ void QDeclarativeCircleMapItemPrivateCPU::updatePolish()
m_geometry.setPreserveGeometry(preserve, m_leftBound);
bool invertedCircle = false;
- if (crossEarthPole(m_circle.m_circle.center(), m_circle.m_circle.radius())
- && circlePath.size() == pathCount) {
+ if (crossEarthPole(m_circle.m_circle.center(), m_circle.m_circle.radius()) && circlePath.size() == pathCount) {
// invert fill area for really huge circles
- m_geometry.updateScreenPointsInvert(circlePath, *m_circle.map());
+ m_geometry.updateSourceAndScreenPointsInvert(circlePath, *m_circle.map());
invertedCircle = true;
} else {
m_geometry.updateSourcePoints(*m_circle.map(), circlePath);
- m_geometry.updateScreenPoints(*m_circle.map(), m_circle.m_border.width());
}
+#ifndef MAPITEMS_USE_SHAPES
+ if (!invertedCircle)
+ m_geometry.updateScreenPoints(*m_circle.map(), m_circle.m_border.width());
+
m_borderGeometry.clear();
QList<QGeoMapItemGeometry *> geoms;
geoms << &m_geometry;
@@ -665,9 +706,33 @@ void QDeclarativeCircleMapItemPrivateCPU::updatePolish()
m_borderGeometry.clear();
}
}
-
- QRectF combined = QGeoMapItemGeometry::translateToCommonOrigin(geoms);
-
+#endif
+
+#ifdef MAPITEMS_USE_SHAPES
+ m_circle.setShapeTriangulationScale(m_shape, m_geometry.maxCoord());
+
+ const bool hasBorder = m_circle.m_border.color().alpha() != 0 && m_circle.m_border.width() > 0;
+ const float borderWidth = hasBorder ? m_circle.m_border.width() : 0.0f;
+ m_shapePath->setStrokeColor(hasBorder ? m_circle.m_border.color() : Qt::transparent);
+ m_shapePath->setStrokeWidth(hasBorder ? borderWidth : -1.0f);
+ m_shapePath->setFillColor(m_circle.color());
+
+ const QRectF bb = m_geometry.sourceBoundingBox();
+ QPainterPath path = m_geometry.srcPath();
+ path.translate(-bb.left() + borderWidth, -bb.top() + borderWidth);
+ path.closeSubpath();
+ m_painterPath->setPath(path);
+
+ m_circle.setSize(invertedCircle || !preserve
+ ? bb.size()
+ : bb.size() + QSize(2 * borderWidth, 2 * borderWidth));
+ m_shape->setSize(m_circle.size());
+ m_shape->setOpacity(m_circle.zoomLevelOpacity());
+ m_shape->setVisible(true);
+
+ m_circle.setPositionOnMap(m_geometry.origin(), -1 * bb.topLeft() + QPointF(borderWidth, borderWidth));
+#else
+ const QRectF combined = QGeoMapItemGeometry::translateToCommonOrigin(geoms);
if (invertedCircle || !preserve) {
m_circle.setWidth(combined.width());
m_circle.setHeight(combined.height());
@@ -675,15 +740,24 @@ void QDeclarativeCircleMapItemPrivateCPU::updatePolish()
m_circle.setWidth(combined.width() + 2 * m_circle.m_border.width()); // ToDo: Fix this!
m_circle.setHeight(combined.height() + 2 * m_circle.m_border.width());
}
-
// No offsetting here, even in normal case, because first point offset is already translated
m_circle.setPositionOnMap(m_geometry.origin(), m_geometry.firstPointOffset());
+#endif
}
QSGNode *QDeclarativeCircleMapItemPrivateCPU::updateMapItemPaintNode(QSGNode *oldNode,
QQuickItem::UpdatePaintNodeData *data)
{
Q_UNUSED(data);
+#ifdef MAPITEMS_USE_SHAPES
+ delete oldNode;
+ if (m_geometry.isScreenDirty() || m_circle.m_dirtyMaterial) {
+ m_geometry.setPreserveGeometry(false);
+ m_geometry.markClean();
+ m_circle.m_dirtyMaterial = false;
+ }
+ return nullptr;
+#else
if (!m_node || !oldNode) { // Apparently the QSG might delete the nodes if they become invisible
m_node = new MapPolygonNode();
if (oldNode) {
@@ -703,11 +777,18 @@ QSGNode *QDeclarativeCircleMapItemPrivateCPU::updateMapItemPaintNode(QSGNode *ol
m_borderGeometry.markClean();
m_circle.m_dirtyMaterial = false;
}
+
return m_node;
+#endif
}
+
bool QDeclarativeCircleMapItemPrivateCPU::contains(const QPointF &point) const
{
+#ifdef MAPITEMS_USE_SHAPES
+ return m_shape->contains(m_circle.mapToItem(m_shape, point));
+#else
return (m_geometry.contains(point) || m_borderGeometry.contains(point));
+#endif
}
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qdeclarativecirclemapitem_p_p.h b/src/location/quickmapitems/qdeclarativecirclemapitem_p_p.h
index e933cb70..e4e3a59c 100644
--- a/src/location/quickmapitems/qdeclarativecirclemapitem_p_p.h
+++ b/src/location/quickmapitems/qdeclarativecirclemapitem_p_p.h
@@ -22,12 +22,15 @@
QT_BEGIN_NAMESPACE
+class QQuickShape;
+class QQuickShapePath;
+
class Q_LOCATION_PRIVATE_EXPORT QGeoMapCircleGeometry : public QGeoMapPolygonGeometry
{
public:
QGeoMapCircleGeometry();
- void updateScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map);
+ void updateSourceAndScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map);
};
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeCircleMapItemPrivate
@@ -83,12 +86,7 @@ public:
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeCircleMapItemPrivateCPU: public QDeclarativeCircleMapItemPrivate
{
public:
-
- QDeclarativeCircleMapItemPrivateCPU(QDeclarativeCircleMapItem &circle)
- : QDeclarativeCircleMapItemPrivate(circle)
- {
- }
-
+ QDeclarativeCircleMapItemPrivateCPU(QDeclarativeCircleMapItem &circle);
~QDeclarativeCircleMapItemPrivateCPU() override;
void onLinePropertiesChanged() override
@@ -100,7 +98,9 @@ public:
{
// preserveGeometry is cleared in updateMapItemPaintNode
m_geometry.markSourceDirty();
+#ifndef MAPITEMS_USE_SHAPES
m_borderGeometry.markSourceDirty();
+#endif
m_circle.polishAndUpdate();
}
void onMapSet() override
@@ -126,8 +126,14 @@ public:
bool contains(const QPointF &point) const override;
QGeoMapCircleGeometry m_geometry;
+#ifdef MAPITEMS_USE_SHAPES
+ QQuickShape *m_shape = nullptr;
+ QQuickShapePath *m_shapePath = nullptr;
+ QDeclarativeGeoMapPainterPath *m_painterPath = nullptr;
+#else
QGeoMapPolylineGeometry m_borderGeometry;
MapPolygonNode *m_node = nullptr;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qdeclarativegeomapitembase.cpp b/src/location/quickmapitems/qdeclarativegeomapitembase.cpp
index 88bf801d..c5b1cc8c 100644
--- a/src/location/quickmapitems/qdeclarativegeomapitembase.cpp
+++ b/src/location/quickmapitems/qdeclarativegeomapitembase.cpp
@@ -13,6 +13,8 @@
#include <QtLocation/private/qgeomap_p.h>
#include <QtLocation/private/qgeoprojection_p.h>
+#include <QtQuickShapes/private/qquickshape_p_p.h>
+
QT_BEGIN_NAMESPACE
QDeclarativeGeoMapItemBase::QDeclarativeGeoMapItemBase(QQuickItem *parent)
@@ -43,7 +45,9 @@ void QDeclarativeGeoMapItemBase::afterChildrenChanged()
bool printedWarning = false;
for (auto *i : kids) {
if (i->flags() & QQuickItem::ItemHasContents
- && !qobject_cast<QQuickMouseArea *>(i)) {
+ && !qobject_cast<QQuickMouseArea *>(i)
+ && i->objectName() != QStringLiteral("_qt_map_item_shape"))
+ {
if (!printedWarning) {
qmlWarning(this) << "Geographic map items do not support child items";
printedWarning = true;
@@ -199,6 +203,22 @@ float QDeclarativeGeoMapItemBase::zoomLevelOpacity() const
return 0.0;
}
+void QDeclarativeGeoMapItemBase::setShapeTriangulationScale(QQuickShape *shape, qreal maxCoord) const
+{
+ const qreal zoom = qMax(0.01, quickMap_->zoomLevel());
+ qreal scale = 1 / zoom;
+
+ // cater also for QTriangulator's 65536 coordinate limit due to the fixed point math
+ qint64 coord = qint64(maxCoord);
+ const qint64 COORD_LIMIT = (1 << 21) / 32; // 65536 (where 32 is Q_FIXED_POINT_SCALE)
+ while (coord > COORD_LIMIT) {
+ coord /= COORD_LIMIT;
+ scale /= COORD_LIMIT;
+ }
+
+ QQuickShapePrivate::get(shape)->triangulationScale = scale;
+}
+
/*!
\internal
*/
diff --git a/src/location/quickmapitems/qdeclarativegeomapitembase_p.h b/src/location/quickmapitems/qdeclarativegeomapitembase_p.h
index 899738d0..18624060 100644
--- a/src/location/quickmapitems/qdeclarativegeomapitembase_p.h
+++ b/src/location/quickmapitems/qdeclarativegeomapitembase_p.h
@@ -25,6 +25,11 @@
#include <QtLocation/private/qgeomap_p.h>
#include <QtLocation/private/qdeclarativegeomapitemtransitionmanager_p.h>
#include <QScopedPointer>
+#include <QtQuickShapes/private/qquickshape_p.h>
+
+// Master switch to make rectangle, circle, polygon, and polyline use
+// QQuickShape instead of a custom scenegraph node.
+#define MAPITEMS_USE_SHAPES
QT_BEGIN_NAMESPACE
@@ -94,6 +99,8 @@ public:
return res;
}
+ void setShapeTriangulationScale(QQuickShape *shape, qreal maxCoord) const;
+
Q_SIGNALS:
void mapItemOpacityChanged();
Q_REVISION(12) void addTransitionFinished();
@@ -134,6 +141,28 @@ private:
friend class QDeclarativeGeoMapItemTransitionManager;
};
+class QDeclarativeGeoMapPainterPath : public QQuickCurve
+{
+ Q_OBJECT
+public:
+ QDeclarativeGeoMapPainterPath(QObject *parent = nullptr) : QQuickCurve(parent) {}
+ QPainterPath path() const
+ {
+ return m_path;
+ }
+ void setPath(const QPainterPath &path)
+ {
+ m_path = path;
+ emit changed();
+ }
+ void addToPath(QPainterPath &path, const QQuickPathData &) override
+ {
+ path.addPath(m_path);
+ }
+private:
+ QPainterPath m_path;
+};
+
QT_END_NAMESPACE
#endif
diff --git a/src/location/quickmapitems/qdeclarativepolygonmapitem.cpp b/src/location/quickmapitems/qdeclarativepolygonmapitem.cpp
index 480b12cc..897ef22d 100644
--- a/src/location/quickmapitems/qdeclarativepolygonmapitem.cpp
+++ b/src/location/quickmapitems/qdeclarativepolygonmapitem.cpp
@@ -187,6 +187,7 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
}
// 3)
+ maxCoord_ = 0.0;
QDoubleVector2D origin = p.wrappedMapProjectionToItemPosition(leftBoundWrapped);
for (const QList<QDoubleVector2D> &path: clippedPaths) {
QDoubleVector2D lastAddedPoint;
@@ -194,6 +195,9 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
QDoubleVector2D point = p.wrappedMapProjectionToItemPosition(path.at(i));
point = point - origin; // (0,0) if point == geoLeftBound_
+ if (qMax(point.x(), point.y()) > maxCoord_)
+ maxCoord_ = qMax(point.x(), point.y());
+
if (i == 0) {
srcPath_.moveTo(point.toPointF());
lastAddedPoint = point;
@@ -214,6 +218,7 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
sourceBounds_ = srcPath_.boundingRect();
}
+#ifndef MAPITEMS_USE_SHAPES
/*!
\internal
*/
@@ -284,37 +289,71 @@ void QGeoMapPolygonGeometry::updateScreenPoints(const QGeoMap &map, qreal stroke
if (strokeWidth != 0.0)
this->translate(QPointF(strokeWidth, strokeWidth));
}
+#endif
/*
* QDeclarativePolygonMapItem Private Implementations
*/
-QDeclarativePolygonMapItemPrivate::~QDeclarativePolygonMapItemPrivate() {}
+QDeclarativePolygonMapItemPrivate::~QDeclarativePolygonMapItemPrivate()
+{
+}
+
+QDeclarativePolygonMapItemPrivateCPU::QDeclarativePolygonMapItemPrivateCPU(QDeclarativePolygonMapItem &polygon)
+ : QDeclarativePolygonMapItemPrivate(polygon)
+{
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape = new QQuickShape(&m_poly);
+ m_shape->setObjectName("_qt_map_item_shape");
+ m_shape->setZ(-1);
+ m_shape->setContainsMode(QQuickShape::FillContains);
+
+ m_shapePath = new QQuickShapePath(m_shape);
+ m_painterPath = new QDeclarativeGeoMapPainterPath(m_shapePath);
+
+ auto pathElements = m_shapePath->pathElements();
+ pathElements.append(&pathElements, m_painterPath);
-QDeclarativePolygonMapItemPrivateCPU::~QDeclarativePolygonMapItemPrivateCPU() {}
+ auto shapePaths = m_shape->data();
+ shapePaths.append(&shapePaths, m_shapePath);
+#endif
+}
+
+QDeclarativePolygonMapItemPrivateCPU::~QDeclarativePolygonMapItemPrivateCPU()
+{
+#ifdef MAPITEMS_USE_SHAPES
+ delete m_shape;
+#endif
+}
void QDeclarativePolygonMapItemPrivateCPU::updatePolish()
{
if (m_poly.m_geopoly.perimeter().length() == 0) { // Possibly cleared
m_geometry.clear();
- m_borderGeometry.clear();
m_poly.setWidth(0);
m_poly.setHeight(0);
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape->setVisible(false);
+#else
+ m_borderGeometry.clear();
+#endif
return;
}
const QGeoMap *map = m_poly.map();
const qreal borderWidth = m_poly.m_border.width();
- const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map->geoProjection());
QScopedValueRollback<bool> rollback(m_poly.m_updatingGeometry);
m_poly.m_updatingGeometry = true;
m_geometry.updateSourcePoints(*map, m_geopathProjected);
+
+#ifndef MAPITEMS_USE_SHAPES
m_geometry.updateScreenPoints(*map, borderWidth);
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map->geoProjection());
QList<QGeoMapItemGeometry *> geoms;
geoms << &m_geometry;
- m_borderGeometry.clear();
+ m_borderGeometry.clear();
if (m_poly.m_border.color().alpha() != 0 && borderWidth > 0) {
QList<QDoubleVector2D> closedPath = m_geopathProjected;
closedPath << closedPath.first();
@@ -338,19 +377,49 @@ void QDeclarativePolygonMapItemPrivateCPU::updatePolish()
m_borderGeometry.clear();
}
}
+#endif
+
+ const QRectF bb = m_geometry.sourceBoundingBox();
+
+#ifdef MAPITEMS_USE_SHAPES
+ m_poly.setShapeTriangulationScale(m_shape, m_geometry.maxCoord());
+
+ const bool hasBorder = m_poly.m_border.color().alpha() != 0 && m_poly.m_border.width() > 0;
+ m_shapePath->setStrokeColor(hasBorder ? m_poly.m_border.color() : Qt::transparent);
+ m_shapePath->setStrokeWidth(hasBorder ? borderWidth : -1.0f);
+ m_shapePath->setFillColor(m_poly.color());
- QRectF combined = QGeoMapItemGeometry::translateToCommonOrigin(geoms);
+ QPainterPath path = m_geometry.srcPath();
+ path.translate(-bb.left() + borderWidth, -bb.top() + borderWidth);
+ path.closeSubpath();
+ m_painterPath->setPath(path);
+
+ m_poly.setSize(bb.size() + QSize(2 * borderWidth, 2 * borderWidth));
+ m_shape->setSize(m_poly.size());
+ m_shape->setOpacity(m_poly.zoomLevelOpacity());
+ m_shape->setVisible(true);
+#else
+ const QRectF combined = QGeoMapItemGeometry::translateToCommonOrigin(geoms);
m_poly.setWidth(combined.width() + 2 * borderWidth);
m_poly.setHeight(combined.height() + 2 * borderWidth);
+#endif
- m_poly.setPositionOnMap(m_geometry.origin(), -1 * m_geometry.sourceBoundingBox().topLeft()
- + QPointF(borderWidth, borderWidth));
+ m_poly.setPositionOnMap(m_geometry.origin(), -1 * bb.topLeft() + QPointF(borderWidth, borderWidth));
}
QSGNode *QDeclarativePolygonMapItemPrivateCPU::updateMapItemPaintNode(QSGNode *oldNode,
QQuickItem::UpdatePaintNodeData *data)
{
Q_UNUSED(data);
+#ifdef MAPITEMS_USE_SHAPES
+ delete oldNode;
+ if (m_geometry.isScreenDirty() || m_poly.m_dirtyMaterial) {
+ m_geometry.setPreserveGeometry(false);
+ m_geometry.markClean();
+ m_poly.m_dirtyMaterial = false;
+ }
+ return nullptr;
+#else
if (!m_node || !oldNode) {
m_node = new MapPolygonNode();
if (oldNode) {
@@ -376,12 +445,18 @@ QSGNode *QDeclarativePolygonMapItemPrivateCPU::updateMapItemPaintNode(QSGNode *o
m_borderGeometry.markClean();
m_poly.m_dirtyMaterial = false;
}
+
return m_node;
+#endif
}
bool QDeclarativePolygonMapItemPrivateCPU::contains(const QPointF &point) const
{
+#ifdef MAPITEMS_USE_SHAPES
+ return m_shape->contains(m_poly.mapToItem(m_shape, point));
+#else
return (m_geometry.contains(point) || m_borderGeometry.contains(point));
+#endif
}
/*
@@ -624,6 +699,8 @@ void QDeclarativePolygonMapItem::geometryChange(const QRectF &newGeometry, const
//////////////////////////////////////////////////////////////////////
+#ifndef MAPITEMS_USE_SHAPES
+
MapPolygonNode::MapPolygonNode()
: border_(new MapPolylineNode()),
geometry_(QSGGeometry::defaultAttributes_Point2D(), 0)
@@ -674,5 +751,6 @@ void MapPolygonNode::update(const QColor &fillColor, const QColor &borderColor,
}
}
+#endif
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qdeclarativepolygonmapitem_p_p.h b/src/location/quickmapitems/qdeclarativepolygonmapitem_p_p.h
index 8595bd7b..80f2159c 100644
--- a/src/location/quickmapitems/qdeclarativepolygonmapitem_p_p.h
+++ b/src/location/quickmapitems/qdeclarativepolygonmapitem_p_p.h
@@ -32,6 +32,9 @@
QT_BEGIN_NAMESPACE
+class QQuickShape;
+class QQuickShapePath;
+
class Q_LOCATION_PRIVATE_EXPORT QGeoMapPolygonGeometry : public QGeoMapItemGeometry
{
public:
@@ -42,13 +45,20 @@ public:
void updateSourcePoints(const QGeoMap &map,
const QList<QDoubleVector2D> &path);
+#ifndef MAPITEMS_USE_SHAPES
void updateScreenPoints(const QGeoMap &map, qreal strokeWidth = 0.0);
+#endif
+
+ QPainterPath srcPath() const { return srcPath_; }
+ qreal maxCoord() const { return maxCoord_; }
protected:
QPainterPath srcPath_;
+ qreal maxCoord_ = 0.0;
bool assumeSimple_ = false;
};
+#ifndef MAPITEMS_USE_SHAPES
class Q_LOCATION_PRIVATE_EXPORT MapPolygonNode : public MapItemGeometryNode
{
@@ -64,6 +74,7 @@ private:
MapPolylineNode *border_;
QSGGeometry geometry_;
};
+#endif
class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolygonMapItemPrivate
{
@@ -92,12 +103,9 @@ public:
class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolygonMapItemPrivateCPU: public QDeclarativePolygonMapItemPrivate
{
public:
- QDeclarativePolygonMapItemPrivateCPU(QDeclarativePolygonMapItem &polygon)
- : QDeclarativePolygonMapItemPrivate(polygon)
- {
- }
-
+ QDeclarativePolygonMapItemPrivateCPU(QDeclarativePolygonMapItem &polygon);
~QDeclarativePolygonMapItemPrivateCPU() override;
+
void onLinePropertiesChanged() override
{
// mark dirty just in case we're a width change
@@ -107,7 +115,9 @@ public:
{
// preserveGeometry is cleared in updateMapItemPaintNode
m_geometry.markSourceDirty();
+#ifndef MAPITEMS_USE_SHAPES
m_borderGeometry.markSourceDirty();
+#endif
m_poly.polishAndUpdate();
}
void regenerateCache()
@@ -130,7 +140,9 @@ public:
void preserveGeometry()
{
m_geometry.setPreserveGeometry(true, m_poly.m_geopoly.boundingGeoRectangle().topLeft());
+#ifndef MAPITEMS_USE_SHAPES
m_borderGeometry.setPreserveGeometry(true, m_poly.m_geopoly.boundingGeoRectangle().topLeft());
+#endif
}
void afterViewportChanged() override
{
@@ -165,8 +177,14 @@ public:
QList<QDoubleVector2D> m_geopathProjected;
QGeoMapPolygonGeometry m_geometry;
+#ifdef MAPITEMS_USE_SHAPES
+ QQuickShape *m_shape = nullptr;
+ QQuickShapePath *m_shapePath = nullptr;
+ QDeclarativeGeoMapPainterPath *m_painterPath = nullptr;
+#else
QGeoMapPolylineGeometry m_borderGeometry;
MapPolygonNode *m_node = nullptr;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qdeclarativepolylinemapitem.cpp b/src/location/quickmapitems/qdeclarativepolylinemapitem.cpp
index 774228c8..fda978ea 100644
--- a/src/location/quickmapitems/qdeclarativepolylinemapitem.cpp
+++ b/src/location/quickmapitems/qdeclarativepolylinemapitem.cpp
@@ -458,6 +458,34 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map,
// 3)
pathToScreen(map, clippedPaths, leftBoundWrapped);
+
+ srcPath_ = QPainterPath();
+ maxCoord_ = 0.0;
+ const int elemCount = srcPointTypes_.count();
+ for (int i = 0; i < elemCount; ++i) {
+ switch (srcPointTypes_[i]) {
+ case QPainterPath::MoveToElement:
+ {
+ const qreal x = srcPoints_[2 * i];
+ const qreal y = srcPoints_[2 * i + 1];
+ if (qMax(x, y) > maxCoord_)
+ maxCoord_ = qMax(x, y);
+ srcPath_.moveTo(x, y);
+ }
+ break;
+ case QPainterPath::LineToElement:
+ {
+ const qreal x = srcPoints_[2 * i];
+ const qreal y = srcPoints_[2 * i + 1];
+ if (qMax(x, y) > maxCoord_)
+ maxCoord_ = qMax(x, y);
+ srcPath_.lineTo(x, y);
+ }
+ break;
+ default:
+ break;
+ }
+ }
}
// *** SCREEN CLIPPING *** //
@@ -650,8 +678,15 @@ void QGeoMapPolylineGeometry::updateScreenPoints(const QGeoMap &map,
}
screenBounds_ = bb;
+
const QPointF strokeOffset = (adjustTranslation) ? QPointF(strokeWidth, strokeWidth) * 0.5: QPointF();
- this->translate( -1 * sourceBounds_.topLeft() + strokeOffset);
+ const QPointF offset = -1 * sourceBounds_.topLeft() + strokeOffset;
+ for (qsizetype i = 0; i < screenVertices_.size(); ++i)
+ screenVertices_[i] += offset;
+
+ firstPointOffset_ += offset;
+ screenOutline_.translate(offset);
+ screenBounds_.translate(offset);
}
void QGeoMapPolylineGeometry::clearSource()
@@ -682,10 +717,36 @@ bool QGeoMapPolylineGeometry::contains(const QPointF &point) const
* QDeclarativePolygonMapItem Private Implementations
*/
-QDeclarativePolylineMapItemPrivate::~QDeclarativePolylineMapItemPrivate() {}
+QDeclarativePolylineMapItemPrivate::~QDeclarativePolylineMapItemPrivate()
+{
+}
+
+QDeclarativePolylineMapItemPrivateCPU::QDeclarativePolylineMapItemPrivateCPU(QDeclarativePolylineMapItem &poly)
+ : QDeclarativePolylineMapItemPrivate(poly)
+{
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape = new QQuickShape(&m_poly);
+ m_shape->setObjectName("_qt_map_item_shape");
+ m_shape->setZ(-1);
+ m_shape->setContainsMode(QQuickShape::FillContains);
-QDeclarativePolylineMapItemPrivateCPU::~QDeclarativePolylineMapItemPrivateCPU() {}
+ m_shapePath = new QQuickShapePath(m_shape);
+ m_painterPath = new QDeclarativeGeoMapPainterPath(m_shapePath);
+
+ auto pathElements = m_shapePath->pathElements();
+ pathElements.append(&pathElements, m_painterPath);
+
+ auto shapePaths = m_shape->data();
+ shapePaths.append(&shapePaths, m_shapePath);
+#endif
+}
+QDeclarativePolylineMapItemPrivateCPU::~QDeclarativePolylineMapItemPrivateCPU()
+{
+#ifdef MAPITEMS_USE_SHAPES
+ delete m_shape;
+#endif
+}
void QDeclarativePolylineMapItemPrivateCPU::regenerateCache()
{
@@ -712,6 +773,9 @@ void QDeclarativePolylineMapItemPrivateCPU::updatePolish()
m_geometry.clear();
m_poly.setWidth(0);
m_poly.setHeight(0);
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape->setVisible(false);
+#endif
return;
}
QScopedValueRollback<bool> rollback(m_poly.m_updatingGeometry);
@@ -721,19 +785,38 @@ void QDeclarativePolylineMapItemPrivateCPU::updatePolish()
const qreal borderWidth = m_poly.m_line.width();
m_geometry.updateSourcePoints(*map, m_geopathProjected, m_poly.m_geopath.boundingGeoRectangle().topLeft());
- m_geometry.updateScreenPoints(*map, borderWidth);
- m_poly.setWidth(m_geometry.sourceBoundingBox().width() + borderWidth);
- m_poly.setHeight(m_geometry.sourceBoundingBox().height() + borderWidth);
+ // still needed even with Shapes, due to contains()
+ m_geometry.updateScreenPoints(*map, borderWidth);
+ const QRectF bb = m_geometry.sourceBoundingBox();
+ m_poly.setSize(bb.size() + QSizeF(borderWidth, borderWidth));
// it has to be shifted so that the center of the line is on the correct geocoord
- m_poly.setPositionOnMap(m_geometry.origin(), -1 * m_geometry.sourceBoundingBox().topLeft()
- + QPointF(borderWidth, borderWidth) * 0.5 );
+ m_poly.setPositionOnMap(m_geometry.origin(), -1 * bb.topLeft() + QPointF(borderWidth, borderWidth) * 0.5);
+
+#ifdef MAPITEMS_USE_SHAPES
+ m_poly.setShapeTriangulationScale(m_shape, m_geometry.maxCoord_);
+
+ m_shapePath->setStrokeColor(m_poly.m_line.color());
+ m_shapePath->setStrokeWidth(borderWidth);
+ m_shapePath->setFillColor(Qt::transparent);
+
+ QPainterPath path = m_geometry.srcPath();
+ path.translate(-bb.left() + borderWidth * 0.5, -bb.top() + borderWidth * 0.5);
+ m_painterPath->setPath(path);
+
+ m_shape->setSize(m_poly.size());
+ m_shape->setOpacity(m_poly.zoomLevelOpacity());
+ m_shape->setVisible(true);
+#endif
}
QSGNode *QDeclarativePolylineMapItemPrivateCPU::updateMapItemPaintNode(QSGNode *oldNode,
QQuickItem::UpdatePaintNodeData * /*data*/)
{
+#ifdef MAPITEMS_USE_SHAPES
+ delete oldNode;
+#else
if (!m_node || !oldNode) {
m_node = new MapPolylineNode();
if (oldNode) {
@@ -743,18 +826,29 @@ QSGNode *QDeclarativePolylineMapItemPrivateCPU::updateMapItemPaintNode(QSGNode *
} else {
m_node = static_cast<MapPolylineNode *>(oldNode);
}
+#endif
//TODO: update only material
if (m_geometry.isScreenDirty() || m_poly.m_dirtyMaterial || !oldNode) {
+#ifndef MAPITEMS_USE_SHAPES
m_node->update(m_poly.m_line.color(), &m_geometry);
+#endif
m_geometry.setPreserveGeometry(false);
m_geometry.markClean();
m_poly.m_dirtyMaterial = false;
}
+#ifdef MAPITEMS_USE_SHAPES
+ return nullptr;
+#else
return m_node;
+#endif
}
+
bool QDeclarativePolylineMapItemPrivateCPU::contains(const QPointF &point) const
{
+ // With Shapes, do not just call
+ // m_shape->contains(m_poly.mapToItem(m_shape, point)) because that can
+ // only do FillContains at best, whereas the polyline relies on stroking.
return m_geometry.contains(point);
}
@@ -1085,6 +1179,8 @@ void QDeclarativePolylineMapItem::setGeoShape(const QGeoShape &shape)
//////////////////////////////////////////////////////////////////////
+#ifndef MAPITEMS_USE_SHAPES
+
/*!
\internal
*/
@@ -1184,4 +1280,6 @@ void MapPolylineNode::update(const QColor &fillColor,
}
}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qdeclarativepolylinemapitem_p_p.h b/src/location/quickmapitems/qdeclarativepolylinemapitem_p_p.h
index 1155a77f..9e8992ad 100644
--- a/src/location/quickmapitems/qdeclarativepolylinemapitem_p_p.h
+++ b/src/location/quickmapitems/qdeclarativepolylinemapitem_p_p.h
@@ -28,7 +28,8 @@
QT_BEGIN_NAMESPACE
-class QSGMaterialShader;
+class QQuickShape;
+class QQuickShapePath;
class Q_LOCATION_PRIVATE_EXPORT QGeoMapPolylineGeometry : public QGeoMapItemGeometry
{
@@ -55,9 +56,13 @@ public:
const QList<QList<QDoubleVector2D> > &clippedPaths,
const QDoubleVector2D &leftBoundWrapped);
+ QPainterPath srcPath() const { return srcPath_; }
+
public:
QList<qreal> srcPoints_;
QList<QPainterPath::ElementType> srcPointTypes_;
+ QPainterPath srcPath_;
+ qreal maxCoord_ = 0.0;
#ifdef QT_LOCATION_DEBUG
QList<QDoubleVector2D> m_wrappedPath;
@@ -69,6 +74,7 @@ public:
friend class QDeclarativeRectangleMapItem;
};
+#ifndef MAPITEMS_USE_SHAPES
class Q_LOCATION_PRIVATE_EXPORT VisibleNode
{
public:
@@ -103,6 +109,7 @@ protected:
QSGFlatColorMaterial fill_material_;
QSGGeometry geometry_;
};
+#endif
class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolylineMapItemPrivate
{
@@ -131,12 +138,9 @@ public:
class Q_LOCATION_PRIVATE_EXPORT QDeclarativePolylineMapItemPrivateCPU: public QDeclarativePolylineMapItemPrivate
{
public:
- QDeclarativePolylineMapItemPrivateCPU(QDeclarativePolylineMapItem &poly)
- : QDeclarativePolylineMapItemPrivate(poly)
- {
- }
-
+ QDeclarativePolylineMapItemPrivateCPU(QDeclarativePolylineMapItem &poly);
~QDeclarativePolylineMapItemPrivateCPU() override;
+
void onLinePropertiesChanged() override
{
// mark dirty just in case we're a width change
@@ -186,7 +190,13 @@ public:
QList<QDoubleVector2D> m_geopathProjected;
QGeoMapPolylineGeometry m_geometry;
+#ifdef MAPITEMS_USE_SHAPES
+ QQuickShape *m_shape = nullptr;
+ QQuickShapePath *m_shapePath = nullptr;
+ QDeclarativeGeoMapPainterPath *m_painterPath = nullptr;
+#else
MapPolylineNode *m_node = nullptr;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qdeclarativerectanglemapitem.cpp b/src/location/quickmapitems/qdeclarativerectanglemapitem.cpp
index b7f3cdda..eae60410 100644
--- a/src/location/quickmapitems/qdeclarativerectanglemapitem.cpp
+++ b/src/location/quickmapitems/qdeclarativerectanglemapitem.cpp
@@ -312,22 +312,56 @@ void QDeclarativeRectangleMapItem::geometryChange(const QRectF &newGeometry, con
// call to this function.
}
-QDeclarativeRectangleMapItemPrivate::~QDeclarativeRectangleMapItemPrivate() {}
+QDeclarativeRectangleMapItemPrivate::QDeclarativeRectangleMapItemPrivate(QDeclarativeRectangleMapItem &rect)
+ : m_rect(rect)
+{
+}
+
+QDeclarativeRectangleMapItemPrivate::~QDeclarativeRectangleMapItemPrivate()
+{
+}
+
+QDeclarativeRectangleMapItemPrivateCPU::QDeclarativeRectangleMapItemPrivateCPU(QDeclarativeRectangleMapItem &rect)
+ : QDeclarativeRectangleMapItemPrivate(rect)
+{
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape = new QQuickShape(&m_rect);
+ m_shape->setObjectName("_qt_map_item_shape");
+ m_shape->setZ(-1);
+ m_shape->setContainsMode(QQuickShape::FillContains);
+
+ m_shapePath = new QQuickShapePath(m_shape);
+ m_painterPath = new QDeclarativeGeoMapPainterPath(m_shapePath);
-QDeclarativeRectangleMapItemPrivateCPU::~QDeclarativeRectangleMapItemPrivateCPU() {}
+ auto pathElements = m_shapePath->pathElements();
+ pathElements.append(&pathElements, m_painterPath);
+
+ auto shapePaths = m_shape->data();
+ shapePaths.append(&shapePaths, m_shapePath);
+#endif
+}
+
+QDeclarativeRectangleMapItemPrivateCPU::~QDeclarativeRectangleMapItemPrivateCPU()
+{
+#ifdef MAPITEMS_USE_SHAPES
+ delete m_shape;
+#endif
+}
void QDeclarativeRectangleMapItemPrivateCPU::updatePolish()
{
if (!m_rect.topLeft().isValid() || !m_rect.bottomRight().isValid()) {
m_geometry.clear();
- m_borderGeometry.clear();
m_rect.setWidth(0);
m_rect.setHeight(0);
+#ifdef MAPITEMS_USE_SHAPES
+ m_shape->setVisible(false);
+#else
+ m_borderGeometry.clear();
+#endif
return;
}
- const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_rect.map()->geoProjection());
-
QScopedValueRollback<bool> rollback(m_rect.m_updatingGeometry);
m_rect.m_updatingGeometry = true;
@@ -335,12 +369,15 @@ void QDeclarativeRectangleMapItemPrivateCPU::updatePolish()
const QList<QDoubleVector2D> pathMercator_ = QGeoMapItemGeometry::pathMercator(perimeter);
m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
m_geometry.updateSourcePoints(*m_rect.map(), pathMercator_);
+
+#ifndef MAPITEMS_USE_SHAPES
m_geometry.updateScreenPoints(*m_rect.map(), m_rect.m_border.width());
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_rect.map()->geoProjection());
QList<QGeoMapItemGeometry *> geoms;
geoms << &m_geometry;
- m_borderGeometry.clear();
+ m_borderGeometry.clear();
if (m_rect.m_border.color().alpha() != 0 && m_rect.m_border.width() > 0) {
QList<QDoubleVector2D> closedPath = pathMercator_;
closedPath << closedPath.first();
@@ -357,24 +394,55 @@ void QDeclarativeRectangleMapItemPrivateCPU::updatePolish()
borderLeftBoundWrapped = p.geoToWrappedMapProjection(geometryOrigin);
m_borderGeometry.pathToScreen(*m_rect.map(), clippedPaths, borderLeftBoundWrapped);
m_borderGeometry.updateScreenPoints(*m_rect.map(), m_rect.m_border.width());
-
geoms << &m_borderGeometry;
} else {
m_borderGeometry.clear();
}
}
-
- QRectF combined = QGeoMapItemGeometry::translateToCommonOrigin(geoms);
+#endif
+
+#ifdef MAPITEMS_USE_SHAPES
+ m_rect.setShapeTriangulationScale(m_shape, m_geometry.maxCoord());
+
+ const bool hasBorder = m_rect.m_border.color().alpha() != 0 && m_rect.m_border.width() > 0;
+ m_shapePath->setStrokeColor(hasBorder ? m_rect.m_border.color() : Qt::transparent);
+ const float borderWidth = hasBorder ? m_rect.m_border.width() : 0.0f;
+ m_shapePath->setStrokeWidth(hasBorder ? borderWidth : -1.0f);
+ m_shapePath->setFillColor(m_rect.color());
+
+ const QRectF bb = m_geometry.sourceBoundingBox();
+ QPainterPath path = m_geometry.srcPath();
+ path.translate(-bb.left() + borderWidth, -bb.top() + borderWidth);
+ path.closeSubpath();
+ m_painterPath->setPath(path);
+
+ m_rect.setSize(bb.size() + QSize(2 * borderWidth, 2 * borderWidth));
+ m_shape->setSize(m_rect.size());
+ m_shape->setOpacity(m_rect.zoomLevelOpacity());
+ m_shape->setVisible(true);
+
+ m_rect.setPositionOnMap(m_geometry.origin(), -1 * bb.topLeft() + QPointF(borderWidth, borderWidth));
+#else
+ const QRectF combined = QGeoMapItemGeometry::translateToCommonOrigin(geoms);
m_rect.setWidth(combined.width() + 2 * m_rect.m_border.width()); // ToDo: fix this! 2 is incorrect
m_rect.setHeight(combined.height() + 2 * m_rect.m_border.width());
-
m_rect.setPositionOnMap(m_geometry.origin(), m_geometry.firstPointOffset());
+#endif
}
QSGNode *QDeclarativeRectangleMapItemPrivateCPU::updateMapItemPaintNode(QSGNode *oldNode,
QQuickItem::UpdatePaintNodeData *data)
{
Q_UNUSED(data);
+#ifdef MAPITEMS_USE_SHAPES
+ delete oldNode;
+ if (m_geometry.isScreenDirty() || m_rect.m_dirtyMaterial) {
+ m_geometry.setPreserveGeometry(false);
+ m_geometry.markClean();
+ m_rect.m_dirtyMaterial = false;
+ }
+ return nullptr;
+#else
if (!m_node || !oldNode) {
m_node = new MapPolygonNode();
if (oldNode) {
@@ -394,12 +462,18 @@ QSGNode *QDeclarativeRectangleMapItemPrivateCPU::updateMapItemPaintNode(QSGNode
m_borderGeometry.markClean();
m_rect.m_dirtyMaterial = false;
}
+
return m_node;
+#endif
}
bool QDeclarativeRectangleMapItemPrivateCPU::contains(const QPointF &point) const
{
+#ifdef MAPITEMS_USE_SHAPES
+ return m_shape->contains(m_rect.mapToItem(m_shape, point));
+#else
return (m_geometry.contains(point) || m_borderGeometry.contains(point));
+#endif
}
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qdeclarativerectanglemapitem_p_p.h b/src/location/quickmapitems/qdeclarativerectanglemapitem_p_p.h
index bf299d89..e7007a80 100644
--- a/src/location/quickmapitems/qdeclarativerectanglemapitem_p_p.h
+++ b/src/location/quickmapitems/qdeclarativerectanglemapitem_p_p.h
@@ -23,14 +23,14 @@
QT_BEGIN_NAMESPACE
+class QQuickShape;
+class QQuickShapePath;
+
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeRectangleMapItemPrivate
{
Q_DISABLE_COPY_MOVE(QDeclarativeRectangleMapItemPrivate)
public:
- QDeclarativeRectangleMapItemPrivate(QDeclarativeRectangleMapItem &rect)
- : m_rect(rect)
- {
- }
+ QDeclarativeRectangleMapItemPrivate(QDeclarativeRectangleMapItem &rect);
virtual ~QDeclarativeRectangleMapItemPrivate();
virtual void onLinePropertiesChanged() = 0;
@@ -49,11 +49,7 @@ public:
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeRectangleMapItemPrivateCPU: public QDeclarativeRectangleMapItemPrivate
{
public:
- QDeclarativeRectangleMapItemPrivateCPU(QDeclarativeRectangleMapItem &rect)
- : QDeclarativeRectangleMapItemPrivate(rect)
- {
- }
-
+ QDeclarativeRectangleMapItemPrivateCPU(QDeclarativeRectangleMapItem &rect);
~QDeclarativeRectangleMapItemPrivateCPU() override;
void onLinePropertiesChanged() override
@@ -64,7 +60,9 @@ public:
void markSourceDirtyAndUpdate() override
{
m_geometry.markSourceDirty();
+#ifndef MAPITEMS_USE_SHAPES
m_borderGeometry.markSourceDirty();
+#endif
m_rect.polishAndUpdate();
}
void onMapSet() override
@@ -78,13 +76,17 @@ public:
void onItemGeometryChanged() override
{
m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
+#ifndef MAPITEMS_USE_SHAPES
m_borderGeometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
+#endif
markSourceDirtyAndUpdate();
}
void afterViewportChanged() override
{
m_geometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
+#ifndef MAPITEMS_USE_SHAPES
m_borderGeometry.setPreserveGeometry(true, m_rect.m_rectangle.topLeft());
+#endif
markSourceDirtyAndUpdate();
}
void updatePolish() override;
@@ -92,8 +94,14 @@ public:
bool contains(const QPointF &point) const override;
QGeoMapPolygonGeometry m_geometry;
+#ifdef MAPITEMS_USE_SHAPES
+ QQuickShape *m_shape = nullptr;
+ QQuickShapePath *m_shapePath = nullptr;
+ QDeclarativeGeoMapPainterPath *m_painterPath = nullptr;
+#else
QGeoMapPolylineGeometry m_borderGeometry;
MapPolygonNode *m_node = nullptr;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qgeomapitemgeometry.cpp b/src/location/quickmapitems/qgeomapitemgeometry.cpp
index 0a5fcadb..dda09601 100644
--- a/src/location/quickmapitems/qgeomapitemgeometry.cpp
+++ b/src/location/quickmapitems/qgeomapitemgeometry.cpp
@@ -21,6 +21,7 @@ QGeoMapItemGeometry::~QGeoMapItemGeometry()
}
+#ifndef MAPITEMS_USE_SHAPES
/*!
\internal
*/
@@ -87,5 +88,6 @@ QRectF QGeoMapItemGeometry::translateToCommonOrigin(const QList<QGeoMapItemGeome
return brects.boundingRect();
}
+#endif
QT_END_NAMESPACE
diff --git a/src/location/quickmapitems/qgeomapitemgeometry_p.h b/src/location/quickmapitems/qgeomapitemgeometry_p.h
index 59e90365..4e32315f 100644
--- a/src/location/quickmapitems/qgeomapitemgeometry_p.h
+++ b/src/location/quickmapitems/qgeomapitemgeometry_p.h
@@ -16,6 +16,7 @@
//
#include <QtLocation/private/qlocationglobal_p.h>
+#include <QtLocation/private/qdeclarativegeomapitembase_p.h>
#include <QtLocation/private/qdeclarativegeomapitemutils_p.h>
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtPositioning/private/qwebmercator_p.h>
@@ -86,7 +87,6 @@ public:
inline void clearBounds() { sourceBounds_ = screenBounds_ = QRectF(); firstPointOffset_ = QPointF(); }
inline QPointF firstPointOffset() const { return firstPointOffset_; }
- void translate(const QPointF &offset);
inline const QGeoCoordinate &origin() const { return srcOrigin_; }
@@ -119,9 +119,11 @@ public:
inline void clear() { firstPointOffset_ = QPointF(0,0);
screenVertices_.clear(); screenIndices_.clear(); }
+#ifndef MAPITEMS_USE_SHAPES
+ void translate(const QPointF &offset);
void allocateAndFill(QSGGeometry *geom) const;
-
static QRectF translateToCommonOrigin(const QList<QGeoMapItemGeometry *> &geoms);
+#endif
mutable bool m_dataChanged = false;