From 444e178a0779f1b0d28e2de1d4dc6a4b228c7a5d Mon Sep 17 00:00:00 2001 From: Paolo Angelelli Date: Tue, 9 Jan 2018 15:43:36 +0100 Subject: Fix fitViewportToMapItems in presence of MapQuickItems with zoomLevel Map.fitViewportToMapItems currently uses the screen geometries of the items to calculate the new values for zoom level and center. When the zoomLevel property is set on MapQuickItems, their on-screen geometry is affected by a hidden transformation within the item. This patch considers that transformation in the calculations. Task-number: QTBUG-63093 Change-Id: I328028f1901b31225866aa3d749849815d59a2a1 Reviewed-by: Vlad Seryakov Reviewed-by: Alex Blasche Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../declarativemaps/qdeclarativegeomap.cpp | 52 +++++++++++++--------- .../qdeclarativegeomapquickitem_p.h | 2 + 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp index ad3558e8..52610ab6 100644 --- a/src/location/declarativemaps/qdeclarativegeomap.cpp +++ b/src/location/declarativemaps/qdeclarativegeomap.cpp @@ -2013,10 +2013,10 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine, bool onlyVisib if (m_mapItems.size() == 0) return; - double minX = 0; - double maxX = 0; - double minY = 0; - double maxY = 0; + double minX = qInf(); + double maxX = -qInf(); + double minY = qInf(); + double maxY = -qInf(); double topLeftX = 0; double topLeftY = 0; double bottomRightX = 0; @@ -2033,13 +2033,11 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine, bool onlyVisib continue; // skip quick items in the first pass and refine the fit later - if (refine) { - QDeclarativeGeoMapQuickItem *quickItem = - qobject_cast(item); - if (quickItem) { + QDeclarativeGeoMapQuickItem *quickItem = + qobject_cast(item); + if (refine && quickItem) { haveQuickItem = true; continue; - } } // Force map items to update immediately. Needed to ensure correct item size and positions // when recursively calling this function. @@ -2047,25 +2045,35 @@ void QDeclarativeGeoMap::fitViewportToMapItemsRefine(bool refine, bool onlyVisib // in relation to // a) fitViewportToMapItems // b) presence of MouseArea + // + // This is also legacy code. It must be updated to not operate on screen sizes. if (item->isPolishScheduled()) item->updatePolish(); - topLeftX = item->position().x(); - topLeftY = item->position().y(); - bottomRightX = topLeftX + item->width(); - bottomRightY = topLeftY + item->height(); + if (quickItem && quickItem->matrix_ && !quickItem->matrix_->m_matrix.isIdentity()) { + // TODO: recalculate the center/zoom level so that the item becomes projectable again + if (quickItem->zoomLevel() == 0.0) // the item is unprojectable, should be skipped. + continue; - if (itemCount == 0) { - minX = topLeftX; - maxX = bottomRightX; - minY = topLeftY; - maxY = bottomRightY; + QRectF brect = item->boundingRect(); + brect = quickItem->matrix_->m_matrix.mapRect(brect); + QPointF transformedPosition = quickItem->matrix_->m_matrix * item->position(); + topLeftX = transformedPosition.x(); + topLeftY = transformedPosition.y(); + bottomRightX = topLeftX + brect.width(); + bottomRightY = topLeftY + brect.height(); } else { - minX = qMin(minX, topLeftX); - maxX = qMax(maxX, bottomRightX); - minY = qMin(minY, topLeftY); - maxY = qMax(maxY, bottomRightY); + topLeftX = item->position().x(); + topLeftY = item->position().y(); + bottomRightX = topLeftX + item->width(); + bottomRightY = topLeftY + item->height(); } + + minX = qMin(minX, topLeftX); + maxX = qMax(maxX, bottomRightX); + minY = qMin(minY, topLeftY); + maxY = qMax(maxY, bottomRightY); + ++itemCount; } diff --git a/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h b/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h index 2035a997..f6b2c7b1 100644 --- a/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h +++ b/src/location/declarativemaps/qdeclarativegeomapquickitem_p.h @@ -126,6 +126,8 @@ private: bool mapAndSourceItemSet_; bool updatingGeometry_; QMapQuickItemMatrix4x4 *matrix_; + + friend class QDeclarativeGeoMap; }; QT_END_NAMESPACE -- cgit v1.2.1