diff options
author | Wolfgang Bremer <wolfgang@w-bremer.de> | 2015-05-11 02:41:58 +0200 |
---|---|---|
committer | Alex Blasche <alexander.blasche@theqtcompany.com> | 2015-06-01 05:30:53 +0000 |
commit | a2af44354014d1f3d10727a7381fb5273917ae1f (patch) | |
tree | 55f75ad5953de37a61a889439306c9360fa23cee | |
parent | f49cff62775b6699a6a2edcdcfe0c9f6b3ecc7d2 (diff) |
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.cpp | 38 |
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; } ////////////////////////////////////////////////////////////////////// |