summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-03-14 13:51:46 +0100
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-03-22 11:13:38 +0000
commitec1033a1cc24305025f9397ff29b6562a3187eb8 (patch)
tree651bef1e1871da1654840ca4c3fd9c285ed7a175 /src
parent172cff4678d26883b822c5486f1da7f33f760575 (diff)
downloadqtlocation-ec1033a1cc24305025f9397ff29b6562a3187eb8.tar.gz
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 <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/location/declarativemaps/qdeclarativecirclemapitem.cpp81
-rw-r--r--src/location/declarativemaps/qdeclarativecirclemapitem_p.h9
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem.cpp45
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem_p.h5
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp48
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem_p.h7
-rw-r--r--src/location/declarativemaps/qdeclarativerectanglemapitem.cpp35
-rw-r--r--src/location/declarativemaps/qdeclarativerectanglemapitem_p.h3
8 files changed, 165 insertions, 68 deletions
diff --git a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
index a4eee272..1684a186 100644
--- a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
@@ -142,7 +142,7 @@ QGeoMapCircleGeometry::QGeoMapCircleGeometry()
/*!
\internal
*/
-void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QGeoCoordinate> &circlePath, const QGeoMap &map)
+void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map)
{
// Not checking for !screenDirty anymore, as everything is now recalculated.
clear();
@@ -175,8 +175,8 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QGeoCoordinate>
fill << tl << tr << br << bl;
QList<QDoubleVector2D> hole;
- for (const QGeoCoordinate &c: circlePath)
- hole << map.geoProjection().geoToWrappedMapProjection(c);
+ for (const QDoubleVector2D &c: circlePath)
+ hole << map.geoProjection().wrapMapProjection(c);
c2t::clip2tri clipper;
clipper.addSubjectPath(QClipperUtils::qListToPath(fill), true);
@@ -358,8 +358,10 @@ void QDeclarativeCircleMapItem::markSourceDirtyAndUpdate()
void QDeclarativeCircleMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *map)
{
QDeclarativeGeoMapItemBase::setMap(quickMap,map);
- if (map)
- markSourceDirtyAndUpdate();
+ if (!map)
+ return;
+ updateCirclePath();
+ markSourceDirtyAndUpdate();
}
/*!
@@ -375,6 +377,7 @@ void QDeclarativeCircleMapItem::setCenter(const QGeoCoordinate &center)
return;
circle_.setCenter(center);
+ updateCirclePath();
markSourceDirtyAndUpdate();
emit centerChanged(center);
}
@@ -418,6 +421,7 @@ void QDeclarativeCircleMapItem::setRadius(qreal radius)
return;
circle_.setRadius(radius);
+ updateCirclePath();
markSourceDirtyAndUpdate();
emit radiusChanged(radius);
}
@@ -472,24 +476,19 @@ void QDeclarativeCircleMapItem::updatePolish()
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- if (geometry_.isSourceDirty()) {
- circlePath_.clear();
- calculatePeripheralPoints(circlePath_, circle_.center(), circle_.radius(), CircleSamples);
- }
-
- QList<QGeoCoordinate> originalCirclePath = circlePath_;
+ QList<QDoubleVector2D> circlePath = circlePath_;
- int pathCount = circlePath_.size();
- bool preserve = preserveCircleGeometry(circlePath_, circle_.center(), circle_.radius());
+ int pathCount = circlePath.size();
+ bool preserve = preserveCircleGeometry(circlePath, circle_.center(), circle_.radius());
geometry_.setPreserveGeometry(true, circle_.boundingGeoRectangle().topLeft()); // to set the geoLeftBound_
geometry_.setPreserveGeometry(preserve, circle_.boundingGeoRectangle().topLeft());
bool invertedCircle = false;
- if (crossEarthPole(circle_.center(), circle_.radius()) && circlePath_.size() == pathCount) {
- geometry_.updateScreenPointsInvert(circlePath_, *map()); // invert fill area for really huge circles
+ if (crossEarthPole(circle_.center(), circle_.radius()) && circlePath.size() == pathCount) {
+ geometry_.updateScreenPointsInvert(circlePath, *map()); // invert fill area for really huge circles
invertedCircle = true;
} else {
- geometry_.updateSourcePoints(*map(), circlePath_);
+ geometry_.updateSourcePoints(*map(), circlePath);
geometry_.updateScreenPoints(*map());
}
@@ -498,11 +497,11 @@ void QDeclarativeCircleMapItem::updatePolish()
geoms << &geometry_;
if (border_.color() != Qt::transparent && border_.width() > 0) {
- QList<QGeoCoordinate> closedPath = circlePath_;
+ QList<QDoubleVector2D> closedPath = circlePath;
closedPath << closedPath.first();
if (invertedCircle) {
- closedPath = originalCirclePath;
+ closedPath = circlePath_;
closedPath << closedPath.first();
std::reverse(closedPath.begin(), closedPath.end());
}
@@ -549,6 +548,20 @@ void QDeclarativeCircleMapItem::afterViewportChanged(const QGeoMapViewportChange
/*!
\internal
*/
+void QDeclarativeCircleMapItem::updateCirclePath()
+{
+ if (!map())
+ return;
+ QList<QGeoCoordinate> path;
+ calculatePeripheralPoints(path, circle_.center(), circle_.radius(), CircleSamples);
+ circlePath_.clear();
+ for (const QGeoCoordinate &c : path)
+ circlePath_ << map()->geoProjection().geoToMapProjection(c);
+}
+
+/*!
+ \internal
+*/
bool QDeclarativeCircleMapItem::contains(const QPointF &point) const
{
return (geometry_.contains(point) || borderGeometry_.contains(point));
@@ -583,7 +596,7 @@ void QDeclarativeCircleMapItem::geometryChanged(const QRectF &newGeometry, const
// call to this function.
}
-bool QDeclarativeCircleMapItem::preserveCircleGeometry (QList<QGeoCoordinate> &path,
+bool QDeclarativeCircleMapItem::preserveCircleGeometry (QList<QDoubleVector2D> &path,
const QGeoCoordinate &center, qreal distance)
{
// if circle crosses north/south pole, then don't preserve circular shape,
@@ -612,7 +625,7 @@ bool QDeclarativeCircleMapItem::preserveCircleGeometry (QList<QGeoCoordinate> &p
* | ____ |
* \__/ \__/
*/
-void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinate> &path,
+void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QDoubleVector2D> &path,
const QGeoCoordinate &center,
qreal distance)
{
@@ -623,11 +636,11 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinat
bool crossSouthPole = distanceToSouthPole < distance;
QList<int> wrapPathIndex;
- QDoubleVector2D prev = map()->geoProjection().wrapMapProjection(map()->geoProjection().geoToMapProjection(path.at(0)));
+ QDoubleVector2D prev = map()->geoProjection().wrapMapProjection(path.at(0));
for (int i = 1; i <= path.count(); ++i) {
int index = i % path.count();
- QDoubleVector2D point = map()->geoProjection().wrapMapProjection(map()->geoProjection().geoToMapProjection(path.at(index)));
+ QDoubleVector2D point = map()->geoProjection().wrapMapProjection(path.at(index));
double diff = qAbs(point.x() - prev.x());
if (diff > 0.5) {
continue;
@@ -637,7 +650,7 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinat
// find the points in path where wrapping occurs
for (int i = 1; i <= path.count(); ++i) {
int index = i % path.count();
- QDoubleVector2D point = map()->geoProjection().wrapMapProjection(map()->geoProjection().geoToMapProjection(path.at(index)));
+ QDoubleVector2D point = map()->geoProjection().wrapMapProjection(path.at(index));
if ( (qAbs(point.x() - prev.x())) >= 0.5 ) {
wrapPathIndex << index;
if (wrapPathIndex.size() == 2 || !(crossNorthPole && crossSouthPole))
@@ -648,25 +661,25 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QGeoCoordinat
// insert two additional coords at top/bottom map corners of the map for shape
// to be drawn correctly
if (wrapPathIndex.size() > 0) {
- qreal newPoleLat = 90;
- QGeoCoordinate wrapCoord = path.at(wrapPathIndex[0]);
+ qreal newPoleLat = 0; // 90 latitude
+ QDoubleVector2D wrapCoord = path.at(wrapPathIndex[0]);
if (wrapPathIndex.size() == 2) {
- QGeoCoordinate wrapCoord2 = path.at(wrapPathIndex[1]);
- if (wrapCoord2.latitude() > wrapCoord.latitude())
- newPoleLat = -90;
+ QDoubleVector2D wrapCoord2 = path.at(wrapPathIndex[1]);
+ if (wrapCoord2.y() < wrapCoord.y())
+ newPoleLat = 1; // -90 latitude
} else if (center.latitude() < 0) {
- newPoleLat = -90;
+ newPoleLat = 1; // -90 latitude
}
for (int i = 0; i < wrapPathIndex.size(); ++i) {
int index = wrapPathIndex[i] == 0 ? 0 : wrapPathIndex[i] + i*2;
int prevIndex = (index - 1) < 0 ? (path.count() - 1): index - 1;
- QGeoCoordinate coord0 = path.at(prevIndex);
- QGeoCoordinate coord1 = path.at(index);
- coord0.setLatitude(newPoleLat);
- coord1.setLatitude(newPoleLat);
+ QDoubleVector2D coord0 = path.at(prevIndex);
+ QDoubleVector2D coord1 = path.at(index);
+ coord0.setY(newPoleLat);
+ coord1.setY(newPoleLat);
path.insert(index ,coord1);
path.insert(index, coord0);
- newPoleLat = -newPoleLat;
+ newPoleLat = 1.0 - newPoleLat;
}
}
}
diff --git a/src/location/declarativemaps/qdeclarativecirclemapitem_p.h b/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
index bcbd67d8..511e3b17 100644
--- a/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
@@ -63,7 +63,7 @@ class QGeoMapCircleGeometry : public QGeoMapPolygonGeometry
public:
QGeoMapCircleGeometry();
- void updateScreenPointsInvert(const QList<QGeoCoordinate> &circlePath, const QGeoMap &map);
+ void updateScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map);
};
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeCircleMapItem : public QDeclarativeGeoMapItemBase
@@ -110,16 +110,17 @@ protected Q_SLOTS:
virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) Q_DECL_OVERRIDE;
private:
- bool preserveCircleGeometry(QList<QGeoCoordinate> &path, const QGeoCoordinate &center,
+ void updateCirclePath();
+ bool preserveCircleGeometry(QList<QDoubleVector2D> &path, const QGeoCoordinate &center,
qreal distance);
- void updateCirclePathForRendering(QList<QGeoCoordinate> &path, const QGeoCoordinate &center,
+ void updateCirclePathForRendering(QList<QDoubleVector2D> &path, const QGeoCoordinate &center,
qreal distance);
private:
QGeoCircle circle_;
QDeclarativeMapLineProperties border_;
QColor color_;
- QList<QGeoCoordinate> circlePath_;
+ QList<QDoubleVector2D> circlePath_;
bool dirtyMaterial_;
QGeoMapCircleGeometry geometry_;
QGeoMapPolylineGeometry borderGeometry_;
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<QGeoCoordinate> &path)
+ const QList<QDoubleVector2D> &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<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- geometry_.updateSourcePoints(*map(), geopath_.path());
+ geometry_.updateSourcePoints(*map(), geopathProjected_);
geometry_.updateScreenPoints(*map());
QList<QGeoMapItemGeometry *> geoms;
@@ -550,7 +553,7 @@ void QDeclarativePolygonMapItem::updatePolish()
borderGeometry_.clear();
if (border_.color() != Qt::transparent && border_.width() > 0) {
- QList<QGeoCoordinate> closedPath = geopath_.path();
+ QList<QDoubleVector2D> closedPath = geopathProjected_;
closedPath << closedPath.first();
borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
@@ -605,6 +608,29 @@ void QDeclarativePolygonMapItem::afterViewportChanged(const QGeoMapViewportChang
/*!
\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
+*/
bool QDeclarativePolygonMapItem::contains(const QPointF &point) const
{
return (geometry_.contains(point) || borderGeometry_.contains(point));
@@ -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();
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
index 9a46bb2c..2e1f0d52 100644
--- a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h
@@ -68,7 +68,7 @@ public:
inline void setAssumeSimple(bool value) { assumeSimple_ = value; }
void updateSourcePoints(const QGeoMap &map,
- const QList<QGeoCoordinate> &path);
+ const QList<QDoubleVector2D> &path);
void updateScreenPoints(const QGeoMap &map);
@@ -122,9 +122,12 @@ protected Q_SLOTS:
virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) Q_DECL_OVERRIDE;
private:
+ void regenerateCache();
+ void updateCache();
void pathPropertyChanged();
QGeoPath geopath_;
+ QList<QDoubleVector2D> geopathProjected_;
QDeclarativeMapLineProperties border_;
QColor color_;
bool dirtyMaterial_;
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
index cdc0175e..b74023f8 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
@@ -179,7 +179,7 @@ QGeoMapPolylineGeometry::QGeoMapPolylineGeometry()
}
QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
QDoubleVector2D &leftBoundWrapped)
{
/*
@@ -202,11 +202,8 @@ QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &
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
@@ -310,7 +307,7 @@ void QGeoMapPolylineGeometry::pathToScreen(const QGeoMap &map,
\internal
*/
void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
const QGeoCoordinate geoLeftBound)
{
if (!sourceDirty_)
@@ -556,6 +553,7 @@ void QDeclarativePolylineMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *
{
QDeclarativeGeoMapItemBase::setMap(quickMap,map);
if (map) {
+ regenerateCache();
geometry_.markSourceDirty();
polishAndUpdate();
}
@@ -618,6 +616,7 @@ void QDeclarativePolylineMapItem::setPathFromGeoList(const QList<QGeoCoordinate>
geopath_.setPath(path);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -646,8 +645,12 @@ int QDeclarativePolylineMapItem::pathLength() const
*/
void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate)
{
+ if (!coordinate.isValid())
+ return;
+
geopath_.addCoordinate(coordinate);
+ updateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -669,6 +672,7 @@ void QDeclarativePolylineMapItem::insertCoordinate(int index, const QGeoCoordina
geopath_.insertCoordinate(index, coordinate);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -691,6 +695,7 @@ void QDeclarativePolylineMapItem::replaceCoordinate(int index, const QGeoCoordin
geopath_.replaceCoordinate(index, coordinate);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -741,6 +746,8 @@ void QDeclarativePolylineMapItem::removeCoordinate(const QGeoCoordinate &coordin
geopath_.removeCoordinate(coordinate);
if (geopath_.path().length() == length)
return;
+
+ regenerateCache();
markSourceDirtyAndUpdate();
emit pathChanged();
}
@@ -763,6 +770,7 @@ void QDeclarativePolylineMapItem::removeCoordinate(int index)
geopath_.removeCoordinate(index);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -807,6 +815,7 @@ void QDeclarativePolylineMapItem::geometryChanged(const QRectF &newGeometry, con
return;
geopath_.translate(offsetLati, offsetLongi);
+ regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
emit pathChanged();
@@ -830,6 +839,29 @@ void QDeclarativePolylineMapItem::afterViewportChanged(const QGeoMapViewportChan
/*!
\internal
*/
+void QDeclarativePolylineMapItem::regenerateCache()
+{
+ if (!map())
+ return;
+ geopathProjected_.clear();
+ geopathProjected_.reserve(geopath_.path().size());
+ for (const QGeoCoordinate &c : geopath_.path())
+ geopathProjected_ << map()->geoProjection().geoToMapProjection(c);
+}
+
+/*!
+ \internal
+*/
+void QDeclarativePolylineMapItem::updateCache()
+{
+ if (!map())
+ return;
+ geopathProjected_ << map()->geoProjection().geoToMapProjection(geopath_.path().last());
+}
+
+/*!
+ \internal
+*/
void QDeclarativePolylineMapItem::updatePolish()
{
if (!map() || geopath_.path().length() == 0)
@@ -838,7 +870,7 @@ void QDeclarativePolylineMapItem::updatePolish()
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- geometry_.updateSourcePoints(*map(), geopath_.path(), geopath_.boundingGeoRectangle().topLeft());
+ geometry_.updateSourcePoints(*map(), geopathProjected_, geopath_.boundingGeoRectangle().topLeft());
geometry_.updateScreenPoints(*map(), line_.width());
setWidth(geometry_.sourceBoundingBox().width());
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
index 55703258..90e03b9a 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
@@ -91,7 +91,7 @@ public:
QGeoMapPolylineGeometry();
void updateSourcePoints(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
const QGeoCoordinate geoLeftBound);
void updateScreenPoints(const QGeoMap &map,
@@ -99,7 +99,7 @@ public:
protected:
QList<QList<QDoubleVector2D> > clipPath(const QGeoMap &map,
- const QList<QGeoCoordinate> &path,
+ const QList<QDoubleVector2D> &path,
QDoubleVector2D &leftBoundWrapped);
void pathToScreen(const QGeoMap &map,
@@ -162,9 +162,12 @@ protected Q_SLOTS:
virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) Q_DECL_OVERRIDE;
private:
+ void regenerateCache();
+ void updateCache();
void pathPropertyChanged();
QGeoPath geopath_;
+ QList<QDoubleVector2D> geopathProjected_;
QDeclarativeMapLineProperties line_;
QColor color_;
bool dirtyMaterial_;
diff --git a/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp b/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
index 1bfbf1fd..53178364 100644
--- a/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
@@ -134,8 +134,10 @@ QDeclarativeRectangleMapItem::~QDeclarativeRectangleMapItem()
void QDeclarativeRectangleMapItem::setMap(QDeclarativeGeoMap *quickMap, QGeoMap *map)
{
QDeclarativeGeoMapItemBase::setMap(quickMap,map);
- if (map)
- markSourceDirtyAndUpdate();
+ if (!map)
+ return;
+ updatePath();
+ markSourceDirtyAndUpdate();
}
/*!
@@ -167,6 +169,7 @@ void QDeclarativeRectangleMapItem::setTopLeft(const QGeoCoordinate &topLeft)
return;
rectangle_.setTopLeft(topLeft);
+ updatePath();
markSourceDirtyAndUpdate();
emit topLeftChanged(topLeft);
}
@@ -198,6 +201,7 @@ void QDeclarativeRectangleMapItem::setBottomRight(const QGeoCoordinate &bottomRi
return;
rectangle_.setBottomRight(bottomRight);
+ updatePath();
markSourceDirtyAndUpdate();
emit bottomRightChanged(bottomRight);
}
@@ -274,14 +278,8 @@ void QDeclarativeRectangleMapItem::updatePolish()
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
- QList<QGeoCoordinate> path;
- path << rectangle_.topLeft();
- path << QGeoCoordinate(rectangle_.topLeft().latitude(), rectangle_.bottomRight().longitude());
- path << rectangle_.bottomRight();
- path << QGeoCoordinate(rectangle_.bottomRight().latitude(), rectangle_.topLeft().longitude());
-
geometry_.setPreserveGeometry(true, rectangle_.topLeft());
- geometry_.updateSourcePoints(*map(), path);
+ geometry_.updateSourcePoints(*map(), pathMercator_);
geometry_.updateScreenPoints(*map());
QList<QGeoMapItemGeometry *> geoms;
@@ -289,7 +287,7 @@ void QDeclarativeRectangleMapItem::updatePolish()
borderGeometry_.clear();
if (border_.color() != Qt::transparent && border_.width() > 0) {
- QList<QGeoCoordinate> closedPath = path;
+ QList<QDoubleVector2D> closedPath = pathMercator_;
closedPath << closedPath.first();
borderGeometry_.setPreserveGeometry(true, rectangle_.topLeft());
@@ -352,6 +350,22 @@ QGeoMap::ItemType QDeclarativeRectangleMapItem::itemType() const
/*!
\internal
*/
+void QDeclarativeRectangleMapItem::updatePath()
+{
+ if (!map())
+ return;
+ pathMercator_.clear();
+ pathMercator_ << map()->geoProjection().geoToMapProjection(rectangle_.topLeft());
+ pathMercator_ << map()->geoProjection().geoToMapProjection(
+ QGeoCoordinate(rectangle_.topLeft().latitude(), rectangle_.bottomRight().longitude()));
+ pathMercator_ << map()->geoProjection().geoToMapProjection(rectangle_.bottomRight());
+ pathMercator_ << map()->geoProjection().geoToMapProjection(
+ QGeoCoordinate(rectangle_.bottomRight().latitude(), rectangle_.topLeft().longitude()));
+}
+
+/*!
+ \internal
+*/
void QDeclarativeRectangleMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
if (updatingGeometry_ || newGeometry.topLeft() == oldGeometry.topLeft()) {
@@ -369,6 +383,7 @@ void QDeclarativeRectangleMapItem::geometryChanged(const QRectF &newGeometry, co
return;
rectangle_.translate(offsetLati, offsetLongi);
+ updatePath();
geometry_.setPreserveGeometry(true, rectangle_.topLeft());
borderGeometry_.setPreserveGeometry(true, rectangle_.topLeft());
markSourceDirtyAndUpdate();
diff --git a/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h b/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h
index b65db813..ca7ca9b7 100644
--- a/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativerectanglemapitem_p.h
@@ -53,6 +53,7 @@
#include <QtLocation/private/qgeomapitemgeometry_p.h>
#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
#include <QtLocation/private/qdeclarativepolygonmapitem_p.h>
+#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
@@ -97,6 +98,7 @@ Q_SIGNALS:
void colorChanged(const QColor &color);
protected:
+ void updatePath();
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) Q_DECL_OVERRIDE;
void updatePolish() Q_DECL_OVERRIDE;
@@ -112,6 +114,7 @@ private:
QGeoMapPolygonGeometry geometry_;
QGeoMapPolylineGeometry borderGeometry_;
bool updatingGeometry_;
+ QList<QDoubleVector2D> pathMercator_;
};
//////////////////////////////////////////////////////////////////////