From ec1033a1cc24305025f9397ff29b6562a3187eb8 Mon Sep 17 00:00:00 2001 From: Paolo Angelelli Date: Tue, 14 Mar 2017 13:51:46 +0100 Subject: Cache coordinate projections in map items This patch caches the result of geoToMapProjection() for the coordinates of the map items, regenerating this data only upon coordinate changes. This allows avoiding to perform a (mercator) projection basically every time the item has to be drawn, and instead do only the wrapping around the camera center and the projection to screen Task-number: QTBUG-59479 Change-Id: Iea5ec04f360d2fe7495cd9c1dd278e83200e0f8d Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../declarativemaps/qdeclarativepolygonmapitem.cpp | 45 +++++++++++++++++----- 1 file changed, 36 insertions(+), 9 deletions(-) (limited to 'src/location/declarativemaps/qdeclarativepolygonmapitem.cpp') diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp index 857aec41..44d1787f 100644 --- a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp +++ b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp @@ -141,7 +141,7 @@ QGeoMapPolygonGeometry::QGeoMapPolygonGeometry() \internal */ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map, - const QList &path) + const QList &path) { if (!sourceDirty_) return; @@ -161,11 +161,8 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map, QDoubleVector2D wrappedLeftBound(qInf(), qInf()); // 1) for (int i = 0; i < path.size(); ++i) { - const QGeoCoordinate &coord = path.at(i); - if (!coord.isValid()) - continue; - - QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(map.geoProjection().geoToMapProjection(coord)); + const QDoubleVector2D &coord = path.at(i); + QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(coord); // We can get NaN if the map isn't set up correctly, or the projection // is faulty -- probably best thing to do is abort @@ -380,6 +377,7 @@ void QDeclarativePolygonMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *m { QDeclarativeGeoMapItemBase::setMap(quickMap,map); if (map) { + regenerateCache(); geometry_.markSourceDirty(); borderGeometry_.markSourceDirty(); polishAndUpdate(); @@ -437,6 +435,7 @@ void QDeclarativePolygonMapItem::setPath(const QJSValue &value) geopath_.setPath(pathList); + regenerateCache(); geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); markSourceDirtyAndUpdate(); @@ -453,8 +452,11 @@ void QDeclarativePolygonMapItem::setPath(const QJSValue &value) void QDeclarativePolygonMapItem::addCoordinate(const QGeoCoordinate &coordinate) { - geopath_.addCoordinate(coordinate); + if (!coordinate.isValid()) + return; + geopath_.addCoordinate(coordinate); + updateCache(); geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); markSourceDirtyAndUpdate(); @@ -478,6 +480,7 @@ void QDeclarativePolygonMapItem::removeCoordinate(const QGeoCoordinate &coordina if (geopath_.path().length() == length) return; + regenerateCache(); geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); markSourceDirtyAndUpdate(); @@ -542,7 +545,7 @@ void QDeclarativePolygonMapItem::updatePolish() QScopedValueRollback rollback(updatingGeometry_); updatingGeometry_ = true; - geometry_.updateSourcePoints(*map(), geopath_.path()); + geometry_.updateSourcePoints(*map(), geopathProjected_); geometry_.updateScreenPoints(*map()); QList geoms; @@ -550,7 +553,7 @@ void QDeclarativePolygonMapItem::updatePolish() borderGeometry_.clear(); if (border_.color() != Qt::transparent && border_.width() > 0) { - QList closedPath = geopath_.path(); + QList closedPath = geopathProjected_; closedPath << closedPath.first(); borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); @@ -602,6 +605,29 @@ void QDeclarativePolygonMapItem::afterViewportChanged(const QGeoMapViewportChang polishAndUpdate(); } +/*! + \internal +*/ +void QDeclarativePolygonMapItem::regenerateCache() +{ + if (!map()) + return; + geopathProjected_.clear(); + geopathProjected_.reserve(geopath_.path().size()); + for (const QGeoCoordinate &c : geopath_.path()) + geopathProjected_ << map()->geoProjection().geoToMapProjection(c); +} + +/*! + \internal +*/ +void QDeclarativePolygonMapItem::updateCache() +{ + if (!map()) + return; + geopathProjected_ << map()->geoProjection().geoToMapProjection(geopath_.path().last()); +} + /*! \internal */ @@ -640,6 +666,7 @@ void QDeclarativePolygonMapItem::geometryChanged(const QRectF &newGeometry, cons return; geopath_.translate(offsetLati, offsetLongi); + regenerateCache(); geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft()); markSourceDirtyAndUpdate(); -- cgit v1.2.1