summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorErik Mattsson <erik.mattsson@appello.com>2013-10-07 10:23:01 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-15 11:38:26 +0200
commitd2411f350e407da0dd299606b8d6f988cf2f9f80 (patch)
tree25d09afb06f0f0b5d9d09ad96e3111d82cda3462 /src
parent42541b2406f6b35e109ee6bee64283582dfd2adc (diff)
downloadqtlocation-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.cpp83
-rw-r--r--src/imports/location/qdeclarativegeomap_p.h1
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