diff options
author | Erik Mattsson <erik.mattsson@appello.com> | 2013-10-07 10:23:01 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-15 11:38:26 +0200 |
commit | d2411f350e407da0dd299606b8d6f988cf2f9f80 (patch) | |
tree | 25d09afb06f0f0b5d9d09ad96e3111d82cda3462 /src | |
parent | 42541b2406f6b35e109ee6bee64283582dfd2adc (diff) | |
download | qtlocation-d2411f350e407da0dd299606b8d6f988cf2f9f80.tar.gz |
Added qml function to fit map to geo shape
Added a qml invokable function in the map object to fit the viewport
to a geo shape. It's heavily influenced from fitViewportToMapItems.
Also added some basic ui tests.
Added handlig for the case with an empty shape
Change-Id: Iecad849f2c1b6d9a54eab90e26435b31a138886c
Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/imports/location/qdeclarativegeomap.cpp | 83 | ||||
-rw-r--r-- | src/imports/location/qdeclarativegeomap_p.h | 1 |
2 files changed, 84 insertions, 0 deletions
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp index bfa1922f..95812906 100644 --- a/src/imports/location/qdeclarativegeomap.cpp +++ b/src/imports/location/qdeclarativegeomap.cpp @@ -57,9 +57,13 @@ #include "mapnode_p.h" #include <cmath> +#include <QtPositioning/QGeoCoordinate> +#include <QtPositioning/QGeoCircle> +#include <QtPositioning/QGeoRectangle> #include <QtLocation/QGeoServiceProvider> #include <QtLocation/private/qgeomappingmanager_p.h> +#include <QPointF> #include <QtQml/QQmlContext> #include <QtQml/qqmlinfo.h> #include <QModelIndex> @@ -1035,6 +1039,85 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF } /*! + \qmlmethod QtLocation5::Map::fitViewportToGeoShape(QGeoShape shape) + + Fits the current viewport to the boundary of the shape. The camera is positioned + in the center of the shape, and at the largest integral zoom level possible which + allows the whole shape to be visible on screen + +*/ +void QDeclarativeGeoMap::fitViewportToGeoShape(const QVariant &variantShape) +{ + if (!map_ || !mappingManagerInitialized_) + return; + + QGeoShape shape; + + if (variantShape.userType() == qMetaTypeId<QGeoRectangle>()) + shape = variantShape.value<QGeoRectangle>(); + else if (variantShape.userType() == qMetaTypeId<QGeoCircle>()) + shape = variantShape.value<QGeoCircle>(); + else if (variantShape.userType() == qMetaTypeId<QGeoShape>()) + shape = variantShape.value<QGeoShape>(); + + if (!shape.isValid()) + return; + + qreal bboxWidth; + qreal bboxHeight; + QGeoCoordinate centerCoordinate; + + switch (shape.type()) { + case QGeoShape::RectangleType: + { + QGeoRectangle rect = shape; + QPointF topLeftPoint = map_->coordinateToScreenPosition(rect.topLeft(), false); + QPointF botRightPoint = map_->coordinateToScreenPosition(rect.bottomRight(), false); + bboxWidth = qAbs(topLeftPoint.x() - botRightPoint.x()); + bboxHeight = qAbs(topLeftPoint.y() - botRightPoint.y()); + centerCoordinate = rect.center(); + break; + } + case QGeoShape::CircleType: + { + QGeoCircle circle = shape; + centerCoordinate = circle.center(); + QGeoCoordinate edge = centerCoordinate.atDistanceAndAzimuth(circle.radius(), 90); + QPointF centerPoint = map_->coordinateToScreenPosition(centerCoordinate, false); + QPointF edgePoint = map_->coordinateToScreenPosition(edge, false); + bboxWidth = qAbs(centerPoint.x() - edgePoint.x()) * 2; + bboxHeight = bboxWidth; + break; + } + case QGeoShape::UnknownType: + //Fallthrough to default + default: + return; + } + + // position camera to the center of bounding box + setCenter(centerCoordinate); + + //If the shape is empty we just change centerposition, not zoom + if (bboxHeight == 0 && bboxWidth == 0) + return; + + // adjust zoom + double bboxWidthRatio = bboxWidth / (bboxWidth + bboxHeight); + double mapWidthRatio = width() / (width() + height()); + double zoomRatio; + + if (bboxWidthRatio > mapWidthRatio) + zoomRatio = bboxWidth / width(); + else + zoomRatio = bboxHeight / height(); + + qreal newZoom = log10(zoomRatio) / log10(0.5); + newZoom = floor(qMax(minimumZoomLevel(), (map_->mapController()->zoom() + newZoom))); + setZoomLevel(newZoom); +} + +/*! \qmlmethod QtLocation5::Map::fitViewportToMapItems() Fits the current viewport to the boundary of all map items. The camera is positioned diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h index eee281b7..1305d96f 100644 --- a/src/imports/location/qdeclarativegeomap_p.h +++ b/src/imports/location/qdeclarativegeomap_p.h @@ -161,6 +161,7 @@ public: QDeclarativeGeoMapGestureArea *gesture(); + Q_INVOKABLE void fitViewportToGeoShape(const QVariant &shape); Q_INVOKABLE void fitViewportToMapItems(); Q_INVOKABLE void pan(int dx, int dy); Q_INVOKABLE void cameraStopped(); // optional hint for prefetch |