diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2018-12-06 13:34:49 +0100 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2018-12-11 00:14:39 +0000 |
commit | 56e07f78579196fc33580ca5f20073a156b0e2dd (patch) | |
tree | 5a572f0a8a2028a6fceb57823c359ca6fecea16b /src | |
parent | c8658686cddee13563aca337c4172a9864caefda (diff) | |
download | qtlocation-56e07f78579196fc33580ca5f20073a156b0e2dd.tar.gz |
Add Map.fitViewportToGeoShape(shape, margins)
This method extends the functionality of setting the visibleRegion, by
also allowing to specify the margins in pixels.
Task-number: QTBUG-69640
Change-Id: I196d0410782992ad2ac954aa08e226521b87ba7b
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/location/declarativemaps/qdeclarativegeomap.cpp | 95 | ||||
-rw-r--r-- | src/location/declarativemaps/qdeclarativegeomap_p.h | 3 | ||||
-rw-r--r-- | src/location/maps/qgeomap.cpp | 3 | ||||
-rw-r--r-- | src/location/maps/qgeomap_p.h | 2 |
4 files changed, 65 insertions, 38 deletions
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp index 63587efe..3c73ca12 100644 --- a/src/location/declarativemaps/qdeclarativegeomap.cpp +++ b/src/location/declarativemaps/qdeclarativegeomap.cpp @@ -1305,7 +1305,7 @@ void QDeclarativeGeoMap::setVisibleRegion(const QGeoShape &shape) return; } - fitViewportToGeoShape(); + fitViewportToGeoShape(m_visibleRegion); } QGeoShape QDeclarativeGeoMap::visibleRegion() const @@ -1445,39 +1445,6 @@ QMargins QDeclarativeGeoMap::mapMargins() const , height() - va.height() - va.y()); } -// TODO: offer the possibility to specify the margins. -void QDeclarativeGeoMap::fitViewportToGeoShape() -{ - if (m_map->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) { - // This case remains handled here, and not inside QGeoMap*::fitViewportToGeoRectangle, - // in order to honor animations on center and zoomLevel - const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection()); - const int borderSize = 10; - const QMargins borders(borderSize, borderSize, borderSize, borderSize); - - if (!m_map || !m_visibleRegion.isValid()) - return; - - const QMargins margins = borders + mapMargins(); - const QPair<QGeoCoordinate, qreal> fitData = p.fitViewportToGeoRectangle(m_visibleRegion, - margins); - if (!fitData.first.isValid()) - return; - - // position camera to the center of bounding box - setProperty("center", QVariant::fromValue(fitData.first)); // not using setCenter(centerCoordinate) to honor a possible animation set on the center property - - if (!qIsFinite(fitData.second)) - return; - double newZoom = qMax<double>(minimumZoomLevel(), fitData.second); - setProperty("zoomLevel", QVariant::fromValue(newZoom)); // not using setZoomLevel(newZoom) to honor a possible animation set on the zoomLevel property - } else if (m_map->capabilities() & QGeoMap::SupportsFittingViewportToGeoRectangle) { - // Animations cannot be honored in this case, as m_map acts as a black box - m_map->fitViewportToGeoRectangle(m_visibleRegion); - } -} - - /*! \qmlproperty list<MapType> QtLocation::Map::supportedMapTypes @@ -1604,6 +1571,64 @@ void QDeclarativeGeoMap::clearData() } /*! + \qmlmethod void QtLocation::Map::fitViewportToGeoShape(geoShape, margins) + + Fits the viewport to a specific geo shape. + The margins are in screen pixels. + + \note If the projection used by the plugin is not WebMercator, and the plugin does not have fitting to + shape capability, this method will do nothing. + + \sa visibleRegion + \since 5.13 +*/ +void QDeclarativeGeoMap::fitViewportToGeoShape(const QGeoShape &shape, QVariant margins) +{ + QMargins m(10, 10, 10, 10); // lets defaults to 10 if margins is invalid + switch (margins.type()) { + case QMetaType::Int: + case QMetaType::Double: { + const int value = int(margins.toDouble()); + m = QMargins(value, value, value, value); + } + break; + // ToDo: Support distinct margins in some QML form. Perhaps QRect? + default: + break; + } + fitViewportToGeoShape(shape, m); +} + +void QDeclarativeGeoMap::fitViewportToGeoShape(const QGeoShape &shape, const QMargins &borders) +{ + if (!m_map || !shape.isValid()) + return; + + if (m_map->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) { + // This case remains handled here, and not inside QGeoMap*::fitViewportToGeoRectangle, + // in order to honor animations on center and zoomLevel + const QMargins margins = borders + mapMargins(); + const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection()); + const QPair<QGeoCoordinate, qreal> fitData = p.fitViewportToGeoRectangle(shape.boundingGeoRectangle(), + margins); + if (!fitData.first.isValid()) + return; + + // position camera to the center of bounding box + setProperty("center", QVariant::fromValue(fitData.first)); // not using setCenter(centerCoordinate) to honor a possible animation set on the center property + + if (!qIsFinite(fitData.second)) + return; + double newZoom = qMax<double>(minimumZoomLevel(), fitData.second); + setProperty("zoomLevel", QVariant::fromValue(newZoom)); // not using setZoomLevel(newZoom) to honor a possible animation set on the zoomLevel property + } else if (m_map->capabilities() & QGeoMap::SupportsFittingViewportToGeoRectangle) { + // Animations cannot be honored in this case, as m_map acts as a black box + m_map->fitViewportToGeoRectangle(m_visibleRegion, borders); + } + // else out of luck +} + +/*! \qmlproperty string QtLocation::Map::errorString This read-only property holds the textual presentation of the latest mapping provider error. @@ -2205,7 +2230,7 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF Multiple fitViewportTo*() calls replace each other. */ if (m_pendingFitViewport && width() && height()) { - fitViewportToGeoShape(); + fitViewportToGeoShape(m_visibleRegion); m_pendingFitViewport = false; } diff --git a/src/location/declarativemaps/qdeclarativegeomap_p.h b/src/location/declarativemaps/qdeclarativegeomap_p.h index f59f6f54..3cbefe79 100644 --- a/src/location/declarativemaps/qdeclarativegeomap_p.h +++ b/src/location/declarativemaps/qdeclarativegeomap_p.h @@ -198,6 +198,8 @@ public: Q_INVOKABLE void pan(int dx, int dy); Q_INVOKABLE void prefetchData(); // optional hint for prefetch Q_INVOKABLE void clearData(); + Q_INVOKABLE void fitViewportToGeoShape(const QGeoShape &shape, QVariant margins); + void fitViewportToGeoShape(const QGeoShape &shape, const QMargins &borders = QMargins(10, 10, 10, 10)); QString errorString() const; QGeoServiceProvider::Error error() const; @@ -278,7 +280,6 @@ private: void populateMap(); void populateParameters(); void fitViewportToMapItemsRefine(bool refine, bool onlyVisible); - void fitViewportToGeoShape(); bool isInteractive(); void attachCopyrightNotice(bool initialVisibility); void detachCopyrightNotice(bool currentVisibility); diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index 963ef6bd..bf5e557d 100644 --- a/src/location/maps/qgeomap.cpp +++ b/src/location/maps/qgeomap.cpp @@ -135,9 +135,10 @@ bool QGeoMap::anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QP return false; } -bool QGeoMap::fitViewportToGeoRectangle(const QGeoRectangle &rectangle) +bool QGeoMap::fitViewportToGeoRectangle(const QGeoRectangle &rectangle, const QMargins &borders) { Q_UNUSED(rectangle) + Q_UNUSED(borders) return false; } diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h index 874b300f..c0af9e10 100644 --- a/src/location/maps/qgeomap_p.h +++ b/src/location/maps/qgeomap_p.h @@ -150,7 +150,7 @@ public: virtual bool setBearing(qreal bearing, const QGeoCoordinate &coordinate); virtual QGeoShape visibleRegion() const; virtual bool anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint); - virtual bool fitViewportToGeoRectangle(const QGeoRectangle &rectangle); + virtual bool fitViewportToGeoRectangle(const QGeoRectangle &rectangle, const QMargins &borders); virtual void setCopyrightVisible(bool visible); virtual void removeMapObject(QGeoMapObject *obj); |