summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Bremer <wolfgang@w-bremer.de>2015-05-11 02:41:58 +0200
committerAlex Blasche <alexander.blasche@theqtcompany.com>2015-06-01 05:30:53 +0000
commita2af44354014d1f3d10727a7381fb5273917ae1f (patch)
tree55f75ad5953de37a61a889439306c9360fa23cee
parentf49cff62775b6699a6a2edcdcfe0c9f6b3ecc7d2 (diff)
downloadqtlocation-a2af44354014d1f3d10727a7381fb5273917ae1f.tar.gz
Improve Polyline MapItem
The old implementation used polygons added to a QPainterPath for the screenBounds and the "contains" area calculation on each screen update and thus had a huge performance impact when using more complex polyline map items with several hundred points. The new implementation only calculates the screenBounds on each screen update. However, the contains check uses a similar logic to the previous QPainterPath approach but is way more performant. This is achieved by testing only parts of the polyline and not the whole QPainterPath at once. Change-Id: Ia332343f40ff865079fc86f0241a3f46a650162d Reviewed-by: Alex Blasche <alexander.blasche@theqtcompany.com>
-rw-r--r--src/imports/location/qdeclarativepolylinemapitem.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp
index 0a9b161a..f39c6f53 100644
--- a/src/imports/location/qdeclarativepolylinemapitem.cpp
+++ b/src/imports/location/qdeclarativepolylinemapitem.cpp
@@ -421,24 +421,32 @@ void QGeoMapPolylineGeometry::updateScreenPoints(const QGeoMap &map,
// not the number of vertices
screenVertices_.reserve(ts.vertexCount());
- screenOutline_ = QPainterPath();
+ QRectF bb;
- QPolygonF tri;
+ QPointF pt;
const float *vs = ts.vertices();
for (int i = 0; i < (ts.vertexCount()/2*2); i += 2) {
- screenVertices_ << QPointF(vs[i], vs[i + 1]);
+ pt = QPointF(vs[i], vs[i + 1]);
+ screenVertices_ << pt;
- if (!qIsFinite(vs[i]) || !qIsFinite(vs[i + 1]))
+ if (!qIsFinite(pt.x()) || !qIsFinite(pt.y()))
break;
- tri << QPointF(vs[i], vs[i + 1]);
- if (tri.size() == 4) {
- tri.remove(0);
- screenOutline_.addPolygon(tri);
+ if (!bb.contains(pt)) {
+ if (pt.x() < bb.left())
+ bb.setLeft(pt.x());
+
+ if (pt.x() > bb.right())
+ bb.setRight(pt.x());
+
+ if (pt.y() < bb.top())
+ bb.setTop(pt.y());
+
+ if (pt.y() > bb.bottom())
+ bb.setBottom(pt.y());
}
}
- QRectF bb = screenOutline_.boundingRect();
screenBounds_ = bb;
this->translate( -1 * sourceBounds_.topLeft());
}
@@ -735,7 +743,17 @@ QSGNode *QDeclarativePolylineMapItem::updateMapItemPaintNode(QSGNode *oldNode, U
bool QDeclarativePolylineMapItem::contains(const QPointF &point) const
{
- return geometry_.contains(point);
+ QPolygonF tri;
+ for (int i = 0; i < geometry_.vertices().size(); ++i) {
+ tri << geometry_.vertices()[i];
+ if (tri.size() == 3) {
+ if (tri.containsPoint(point,Qt::OddEvenFill))
+ return true;
+ tri.remove(0);
+ }
+ }
+
+ return false;
}
//////////////////////////////////////////////////////////////////////