summaryrefslogtreecommitdiff
path: root/src/location/declarativemaps
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-09-21 18:14:26 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2018-01-27 09:56:25 +0000
commit69a42c4a5c37a5a74c4b285c64328bc88ed8e059 (patch)
tree54c3d5bf14a4938ab4786d5dfb70379aeee2894d /src/location/declarativemaps
parenta6ff21e1e5ae264b7de264b47e08d334739fa4c6 (diff)
downloadqtlocation-69a42c4a5c37a5a74c4b285c64328bc88ed8e059.tar.gz
Allow plugins to use alternative map projections
QtLocation mapping has always been geared around the WebMercator projection. Some mapping SDKs support additional projections, such as General Perspective (often called globe view or globe rendering). The goal of this patch is to allow a plugin to provide such a view, disabling WebMercator specific features, and redirecting API calls to plugin-specific implementations. In particular, this patch disables the rendering of Map Items (QDeclarativeGeoMapItemBase and sons) for projections different from WebMercator, with the exception of MapQuickItems. MapQuickItems, in turn, lose the ability to draw "on the map", when the projection is different from WebMercator. However, they can still be used to add geolocated popups, buttons and other UI elements. fitViewportToMapItems is also disabled, for both it can't be computed and there wouldn't be any item to fit (with the exception of mapquickitems) Change-Id: I9fa2fdd01a35a078fc4663efc9d269c4ecaa3f41 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src/location/declarativemaps')
-rw-r--r--src/location/declarativemaps/qdeclarativecirclemapitem.cpp48
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap.cpp224
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitembase.cpp16
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapquickitem.cpp50
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem.cpp30
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp28
-rw-r--r--src/location/declarativemaps/qdeclarativerectanglemapitem.cpp16
-rw-r--r--src/location/declarativemaps/qquickgeomapgesturearea.cpp23
8 files changed, 261 insertions, 174 deletions
diff --git a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
index 91328dc7..a1e34a30 100644
--- a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
@@ -144,6 +144,7 @@ QGeoMapCircleGeometry::QGeoMapCircleGeometry()
*/
void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D> &circlePath, const QGeoMap &map)
{
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection());
// Not checking for !screenDirty anymore, as everything is now recalculated.
clear();
if (map.viewportWidth() == 0 || map.viewportHeight() == 0 || circlePath.size() < 3) // a circle requires at least 3 points;
@@ -160,23 +161,23 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D
*/
// 1)
- double topLati = QLocationUtils::mercatorMaxLatitude();
- double bottomLati = -(QLocationUtils::mercatorMaxLatitude());
- double leftLongi = QLocationUtils::mapLeftLongitude(map.cameraData().center().longitude());
- double rightLongi = QLocationUtils::mapRightLongitude(map.cameraData().center().longitude());
+ const double topLati = QLocationUtils::mercatorMaxLatitude();
+ const double bottomLati = -(QLocationUtils::mercatorMaxLatitude());
+ const double leftLongi = QLocationUtils::mapLeftLongitude(map.cameraData().center().longitude());
+ const double rightLongi = QLocationUtils::mapRightLongitude(map.cameraData().center().longitude());
srcOrigin_ = QGeoCoordinate(topLati,leftLongi);
- QDoubleVector2D tl = map.geoProjection().geoToWrappedMapProjection(QGeoCoordinate(topLati,leftLongi));
- QDoubleVector2D tr = map.geoProjection().geoToWrappedMapProjection(QGeoCoordinate(topLati,rightLongi));
- QDoubleVector2D br = map.geoProjection().geoToWrappedMapProjection(QGeoCoordinate(bottomLati,rightLongi));
- QDoubleVector2D bl = map.geoProjection().geoToWrappedMapProjection(QGeoCoordinate(bottomLati,leftLongi));
+ const QDoubleVector2D tl = p.geoToWrappedMapProjection(QGeoCoordinate(topLati,leftLongi));
+ const QDoubleVector2D tr = p.geoToWrappedMapProjection(QGeoCoordinate(topLati,rightLongi));
+ const QDoubleVector2D br = p.geoToWrappedMapProjection(QGeoCoordinate(bottomLati,rightLongi));
+ const QDoubleVector2D bl = p.geoToWrappedMapProjection(QGeoCoordinate(bottomLati,leftLongi));
QList<QDoubleVector2D> fill;
fill << tl << tr << br << bl;
QList<QDoubleVector2D> hole;
for (const QDoubleVector2D &c: circlePath)
- hole << map.geoProjection().wrapMapProjection(c);
+ hole << p.wrapMapProjection(c);
c2t::clip2tri clipper;
clipper.addSubjectPath(QClipperUtils::qListToPath(fill), true);
@@ -184,9 +185,9 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D
Paths difference = clipper.execute(c2t::clip2tri::Difference, QtClipperLib::pftEvenOdd, QtClipperLib::pftEvenOdd);
// 2)
- QDoubleVector2D lb = map.geoProjection().geoToWrappedMapProjection(srcOrigin_);
+ QDoubleVector2D lb = p.geoToWrappedMapProjection(srcOrigin_);
QList<QList<QDoubleVector2D> > clippedPaths;
- const QList<QDoubleVector2D> &visibleRegion = map.geoProjection().visibleRegion();
+ const QList<QDoubleVector2D> &visibleRegion = p.visibleGeometry();
if (visibleRegion.size()) {
clipper.clearClipper();
for (const Path &p: difference)
@@ -210,19 +211,19 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D
// Prevent the conversion to and from clipper from introducing negative offsets which
// in turn will make the geometry wrap around.
lb.setX(qMax(tl.x(), lb.x()));
- srcOrigin_ = map.geoProjection().mapProjectionToGeo(map.geoProjection().unwrapMapProjection(lb));
+ srcOrigin_ = p.mapProjectionToGeo(p.unwrapMapProjection(lb));
} else {
clippedPaths = QClipperUtils::pathsToQList(difference);
}
//3)
- QDoubleVector2D origin = map.geoProjection().wrappedMapProjectionToItemPosition(lb);
+ QDoubleVector2D origin = p.wrappedMapProjectionToItemPosition(lb);
QPainterPath ppi;
for (const QList<QDoubleVector2D> &path: clippedPaths) {
QDoubleVector2D lastAddedPoint;
for (int i = 0; i < path.size(); ++i) {
- QDoubleVector2D point = map.geoProjection().wrappedMapProjectionToItemPosition(path.at(i));
+ QDoubleVector2D point = p.wrappedMapProjectionToItemPosition(path.at(i));
//point = point - origin; // Do this using ppi.translate()
if (i == 0) {
@@ -483,9 +484,11 @@ QSGNode *QDeclarativeCircleMapItem::updateMapItemPaintNode(QSGNode *oldNode, Upd
*/
void QDeclarativeCircleMapItem::updatePolish()
{
- if (!map() || !circle_.isValid())
+ if (!map() || !circle_.isValid()
+ || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
@@ -533,7 +536,7 @@ void QDeclarativeCircleMapItem::updatePolish()
QDoubleVector2D borderLeftBoundWrapped;
QList<QList<QDoubleVector2D > > clippedPaths = borderGeometry_.clipPath(*map(), closedPath, borderLeftBoundWrapped);
if (clippedPaths.size()) {
- borderLeftBoundWrapped = map()->geoProjection().geoToWrappedMapProjection(geometryOrigin);
+ borderLeftBoundWrapped = p.geoToWrappedMapProjection(geometryOrigin);
borderGeometry_.pathToScreen(*map(), clippedPaths, borderLeftBoundWrapped);
borderGeometry_.updateScreenPoints(*map(), border_.width());
geoms << &borderGeometry_;
@@ -565,13 +568,15 @@ void QDeclarativeCircleMapItem::afterViewportChanged(const QGeoMapViewportChange
*/
void QDeclarativeCircleMapItem::updateCirclePath()
{
- if (!map())
+ if (!map() || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
+
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
QList<QGeoCoordinate> path;
calculatePeripheralPoints(path, circle_.center(), circle_.radius(), CircleSamples, leftBound_);
circlePath_.clear();
for (const QGeoCoordinate &c : path)
- circlePath_ << map()->geoProjection().geoToMapProjection(c);
+ circlePath_ << p.geoToMapProjection(c);
}
/*!
@@ -644,6 +649,7 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QDoubleVector
const QGeoCoordinate &center,
qreal distance)
{
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
const qreal poleLat = 90;
const qreal distanceToNorthPole = center.distanceTo(QGeoCoordinate(poleLat, 0));
const qreal distanceToSouthPole = center.distanceTo(QGeoCoordinate(-poleLat, 0));
@@ -651,11 +657,11 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QDoubleVector
bool crossSouthPole = distanceToSouthPole < distance;
QList<int> wrapPathIndex;
- QDoubleVector2D prev = map()->geoProjection().wrapMapProjection(path.at(0));
+ QDoubleVector2D prev = p.wrapMapProjection(path.at(0));
for (int i = 1; i <= path.count(); ++i) {
int index = i % path.count();
- QDoubleVector2D point = map()->geoProjection().wrapMapProjection(path.at(index));
+ QDoubleVector2D point = p.wrapMapProjection(path.at(index));
double diff = qAbs(point.x() - prev.x());
if (diff > 0.5) {
continue;
@@ -665,7 +671,7 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QDoubleVector
// 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(path.at(index));
+ QDoubleVector2D point = p.wrapMapProjection(path.at(index));
if ( (qAbs(point.x() - prev.x())) >= 0.5 ) {
wrapPathIndex << index;
if (wrapPathIndex.size() == 2 || !(crossNorthPole && crossSouthPole))
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp
index 42ed633d..c5d01ebd 100644
--- a/src/location/declarativemaps/qdeclarativegeomap.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomap.cpp
@@ -61,6 +61,15 @@
QT_BEGIN_NAMESPACE
+static qreal sanitizeBearing(qreal bearing)
+{
+ bearing = std::fmod(bearing, qreal(360.0));
+ if (bearing < 0.0)
+ bearing += 360.0;
+
+ return bearing;
+}
+
/*!
\qmltype Map
\instantiates QDeclarativeGeoMap
@@ -389,7 +398,7 @@ void QDeclarativeGeoMap::initialize()
QGeoCoordinate center = m_cameraData.center();
- if (qIsNaN(m_userMinimumZoomLevel))
+ if (!qIsFinite(m_userMinimumZoomLevel))
setMinimumZoomLevel(m_map->minimumZoom(), false);
else
setMinimumZoomLevel(qMax<qreal>(m_map->minimumZoom(), m_userMinimumZoomLevel), false);
@@ -681,7 +690,7 @@ void QDeclarativeGeoMap::onCameraCapabilitiesChanged(const QGeoCameraCapabilitie
if (m_cameraCapabilities.maximumZoomLevelAt256() < m_gestureArea->maximumZoomLevel()) {
setMaximumZoomLevel(m_cameraCapabilities.maximumZoomLevelAt256(), false);
} else if (m_cameraCapabilities.maximumZoomLevelAt256() > m_gestureArea->maximumZoomLevel()) {
- if (qIsNaN(m_userMaximumZoomLevel)) {
+ if (!qIsFinite(m_userMaximumZoomLevel)) {
// If the user didn't set anything
setMaximumZoomLevel(m_cameraCapabilities.maximumZoomLevelAt256(), false);
} else { // Try to set what the user requested
@@ -694,7 +703,7 @@ void QDeclarativeGeoMap::onCameraCapabilitiesChanged(const QGeoCameraCapabilitie
if (m_cameraCapabilities.minimumZoomLevelAt256() > m_gestureArea->minimumZoomLevel()) {
setMinimumZoomLevel(m_cameraCapabilities.minimumZoomLevelAt256(), false);
} else if (m_cameraCapabilities.minimumZoomLevelAt256() < m_gestureArea->minimumZoomLevel()) {
- if (qIsNaN(m_userMinimumZoomLevel)) {
+ if (!qIsFinite(m_userMinimumZoomLevel)) {
// If the user didn't set anything, trying to set the new caps.
setMinimumZoomLevel(m_cameraCapabilities.minimumZoomLevelAt256(), false);
} else { // Try to set what the user requested
@@ -710,7 +719,7 @@ void QDeclarativeGeoMap::onCameraCapabilitiesChanged(const QGeoCameraCapabilitie
if (m_cameraCapabilities.maximumTilt() < m_maximumTilt) {
setMaximumTilt(m_cameraCapabilities.maximumTilt(), false);
} else if (m_cameraCapabilities.maximumTilt() > m_maximumTilt) {
- if (qIsNaN(m_userMaximumTilt))
+ if (!qIsFinite(m_userMaximumTilt))
setMaximumTilt(m_cameraCapabilities.maximumTilt(), false);
else // Try to set what the user requested
setMaximumTilt(qMin<qreal>(m_cameraCapabilities.maximumTilt(), m_userMaximumTilt), false);
@@ -719,7 +728,7 @@ void QDeclarativeGeoMap::onCameraCapabilitiesChanged(const QGeoCameraCapabilitie
if (m_cameraCapabilities.minimumTilt() > m_minimumTilt) {
setMinimumTilt(m_cameraCapabilities.minimumTilt(), false);
} else if (m_cameraCapabilities.minimumTilt() < m_minimumTilt) {
- if (qIsNaN(m_userMinimumTilt))
+ if (!qIsFinite(m_userMinimumTilt))
setMinimumTilt(m_cameraCapabilities.minimumTilt(), false);
else // Try to set what the user requested
setMinimumTilt(qMax<qreal>(m_cameraCapabilities.minimumTilt(), m_userMinimumTilt), false);
@@ -729,7 +738,7 @@ void QDeclarativeGeoMap::onCameraCapabilitiesChanged(const QGeoCameraCapabilitie
if (m_cameraCapabilities.maximumFieldOfView() < m_maximumFieldOfView) {
setMaximumFieldOfView(m_cameraCapabilities.maximumFieldOfView(), false);
} else if (m_cameraCapabilities.maximumFieldOfView() > m_maximumFieldOfView) {
- if (qIsNaN(m_userMaximumFieldOfView))
+ if (!qIsFinite(m_userMaximumFieldOfView))
setMaximumFieldOfView(m_cameraCapabilities.maximumFieldOfView(), false);
else // Try to set what the user requested
setMaximumFieldOfView(qMin<qreal>(m_cameraCapabilities.maximumFieldOfView(), m_userMaximumFieldOfView), false);
@@ -738,7 +747,7 @@ void QDeclarativeGeoMap::onCameraCapabilitiesChanged(const QGeoCameraCapabilitie
if (m_cameraCapabilities.minimumFieldOfView() > m_minimumFieldOfView) {
setMinimumFieldOfView(m_cameraCapabilities.minimumFieldOfView(), false);
} else if (m_cameraCapabilities.minimumFieldOfView() < m_minimumFieldOfView) {
- if (qIsNaN(m_userMinimumFieldOfView))
+ if (!qIsFinite(m_userMinimumFieldOfView))
setMinimumFieldOfView(m_cameraCapabilities.minimumFieldOfView(), false);
else // Try to set what the user requested
setMinimumFieldOfView(qMax<qreal>(m_cameraCapabilities.minimumFieldOfView(), m_userMinimumFieldOfView), false);
@@ -1042,12 +1051,8 @@ qreal QDeclarativeGeoMap::zoomLevel() const
*/
void QDeclarativeGeoMap::setBearing(qreal bearing)
{
- bearing = std::fmod(bearing, qreal(360.0));
- if (bearing < 0.0)
- bearing += 360.0;
- if (m_map && !m_cameraCapabilities.supportsBearing())
- bearing = 0.0;
- if (m_cameraData.bearing() == bearing || bearing < 0.0)
+ bearing = sanitizeBearing(bearing);
+ if (m_cameraData.bearing() == bearing)
return;
m_cameraData.setBearing(bearing);
@@ -1056,6 +1061,45 @@ void QDeclarativeGeoMap::setBearing(qreal bearing)
emit bearingChanged(bearing);
}
+/*!
+ \qmlmethod void QtLocation::Map::setBearing(real bearing, coordinate coordinate)
+
+ Sets the bearing for the map to \a bearing, rotating it around \a coordinate.
+ If the Plugin used for the Map supports bearing, the valid range for \a bearing is between 0 and 360.
+ If the Plugin used for the Map does not support bearing, or if the map is tilted and \a coordinate happens
+ to be behind the camera, or if the map is not ready (see \l mapReady), calling this method will have no effect.
+
+ The release of this API with Qt 5.10 is a Technology Preview.
+
+ \since 5.10
+*/
+void QDeclarativeGeoMap::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
+{
+ if (!m_map)
+ return;
+
+ const QGeoCoordinate currentCenter = center();
+ const qreal currentBearing = QDeclarativeGeoMap::bearing();
+ bearing = sanitizeBearing(bearing);
+
+ if (!coordinate.isValid()
+ || !qIsFinite(bearing)
+ || (coordinate == currentCenter && bearing == currentBearing))
+ return;
+
+ if (m_map->capabilities() & QGeoMap::SupportsSetBearing) {
+ if (!m_map->setBearing(bearing, coordinate))
+ return;
+
+ m_cameraData = m_map->cameraData();
+
+ if (m_cameraData.center() != currentCenter)
+ emit centerChanged(m_cameraData.center());
+ if (m_cameraData.bearing() != currentBearing)
+ emit bearingChanged(bearing);
+ }
+}
+
qreal QDeclarativeGeoMap::bearing() const
{
return m_cameraData.bearing();
@@ -1351,23 +1395,23 @@ QGeoShape QDeclarativeGeoMap::visibleRegion() const
if (!m_map || !width() || !height())
return m_visibleRegion;
- const QList<QDoubleVector2D> &visibleRegion = m_map->geoProjection().visibleRegion();
- QGeoPolygon poly;
- for (int i = 0; i < visibleRegion.size(); ++i) {
- const QDoubleVector2D &c = visibleRegion.at(i);
- // If a segment spans more than half of the map longitudinally, split in 2.
- if (i && qAbs(visibleRegion.at(i-1).x() - c.x()) >= 0.5) { // This assumes a segment is never >= 1.0 (whole map span)
- QDoubleVector2D extraPoint = (visibleRegion.at(i-1) + c) * 0.5;
- poly.addCoordinate(m_map->geoProjection().wrappedMapProjectionToGeo(extraPoint));
- }
- poly.addCoordinate(m_map->geoProjection().wrappedMapProjectionToGeo(c));
- }
- if (visibleRegion.size() >= 2 && qAbs(visibleRegion.last().x() - visibleRegion.first().x()) >= 0.5) {
- QDoubleVector2D extraPoint = (visibleRegion.last() + visibleRegion.first()) * 0.5;
- poly.addCoordinate(m_map->geoProjection().wrappedMapProjectionToGeo(extraPoint));
+ if (m_map->capabilities() & QGeoMap::SupportsVisibleRegion) {
+ return m_map->visibleRegion();
+ } else {
+ // ToDo: handle projections not supporting visible region in a better way.
+ // This approach will fail when horizon is in the view or the map is greatly zoomed out.
+ QList<QGeoCoordinate> visiblePoly;
+ visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,0), false);
+ visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
+ 0), false);
+ visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_map->viewportWidth() - 1,
+ m_map->viewportHeight() - 1), false);
+ visiblePoly << m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(0,
+ m_map->viewportHeight() - 1), false);
+ QGeoPath path;
+ path.setPath(visiblePoly);
+ return path.boundingGeoRectangle();
}
-
- return poly;
}
/*!
@@ -1439,35 +1483,53 @@ bool QDeclarativeGeoMap::mapReady() const
// TODO: offer the possibility to specify the margins.
void QDeclarativeGeoMap::fitViewportToGeoShape()
{
- const int margins = 10;
- if (!m_map || !m_visibleRegion.isValid() || width() <= margins || height() <= margins)
- return;
-
- QDoubleVector2D topLeftPoint = m_map->geoProjection().geoToMapProjection(m_visibleRegion.topLeft());
- QDoubleVector2D bottomRightPoint = m_map->geoProjection().geoToMapProjection(m_visibleRegion.bottomRight());
- if (bottomRightPoint.x() < topLeftPoint.x()) // crossing the dateline
- bottomRightPoint.setX(bottomRightPoint.x() + 1.0);
-
- // find center of the bounding box
- QDoubleVector2D center = (topLeftPoint + bottomRightPoint) * 0.5;
- center.setX(center.x() > 1.0 ? center.x() - 1.0 : center.x());
- QGeoCoordinate centerCoordinate = m_map->geoProjection().mapProjectionToGeo(center);
-
- // position camera to the center of bounding box
- setProperty("center", QVariant::fromValue(centerCoordinate)); // not using setCenter(centerCoordinate) to honor a possible animation set on the center property
-
- // if the shape is empty we just change center position, not zoom
- double bboxWidth = (bottomRightPoint.x() - topLeftPoint.x()) * m_map->mapWidth();
- double bboxHeight = (bottomRightPoint.y() - topLeftPoint.y()) * m_map->mapHeight();
-
- if (bboxHeight == 0.0 && bboxWidth == 0.0)
- return;
-
- double zoomRatio = qMax(bboxWidth / (width() - margins),
- bboxHeight / (height() - margins));
- zoomRatio = std::log(zoomRatio) / std::log(2.0);
- double newZoom = qMax<double>(minimumZoomLevel(), zoomLevel() - zoomRatio);
- setProperty("zoomLevel", QVariant::fromValue(newZoom)); // not using setZoomLevel(newZoom) to honor a possible animation set on the zoomLevel property
+ 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 margins = 10;
+ if (!m_map || !m_visibleRegion.isValid() || width() <= margins || height() <= margins)
+ return;
+
+ QDoubleVector2D topLeftPoint = p.geoToMapProjection(m_visibleRegion.topLeft());
+ QDoubleVector2D bottomRightPoint = p.geoToMapProjection(m_visibleRegion.bottomRight());
+ if (bottomRightPoint.x() < topLeftPoint.x()) // crossing the dateline
+ bottomRightPoint.setX(bottomRightPoint.x() + 1.0);
+
+ // find center of the bounding box
+ QDoubleVector2D center = (topLeftPoint + bottomRightPoint) * 0.5;
+ center.setX(center.x() > 1.0 ? center.x() - 1.0 : center.x());
+ QGeoCoordinate centerCoordinate = p.mapProjectionToGeo(center);
+
+ // position camera to the center of bounding box
+ setProperty("center", QVariant::fromValue(centerCoordinate)); // not using setCenter(centerCoordinate) to honor a possible animation set on the center property
+
+ // if the shape is empty we just change center position, not zoom
+ double bboxWidth = (bottomRightPoint.x() - topLeftPoint.x()) * m_map->mapWidth();
+ double bboxHeight = (bottomRightPoint.y() - topLeftPoint.y()) * m_map->mapHeight();
+
+ if (bboxHeight == 0.0 && bboxWidth == 0.0)
+ return;
+
+ double zoomRatio = qMax(bboxWidth / (width() - margins),
+ bboxHeight / (height() - margins));
+ zoomRatio = std::log(zoomRatio) / std::log(2.0);
+ double newZoom = qMax<double>(minimumZoomLevel(), zoomLevel() - zoomRatio);
+ 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 act as a black box
+ const QGeoCoordinate currentCenter = center();
+ const qreal currentZoom = zoomLevel();
+
+ if (!m_map->fitViewportToGeoRectangle(m_visibleRegion))
+ return;
+
+ m_cameraData = m_map->cameraData();
+ if (m_cameraData.center() != currentCenter)
+ emit centerChanged(m_cameraData.center());
+ if (m_cameraData.zoomLevel() != currentZoom)
+ emit zoomLevelChanged(m_cameraData.zoomLevel());
+ }
}
@@ -1484,35 +1546,6 @@ QQmlListProperty<QDeclarativeGeoMapType> QDeclarativeGeoMap::supportedMapTypes()
}
/*!
- \qmlmethod void QtLocation::Map::setBearing(real bearing, coordinate coordinate)
-
- Sets the bearing for the map to \a bearing, rotating it around \a coordinate.
- If the Plugin used for the Map supports bearing, the valid range for \a bearing is between 0 and 360.
- If the Plugin used for the Map does not support bearing, or if the map is tilted and \a coordinate happens
- to be behind the camera, or if the map is not ready (see \l mapReady), calling this method will have no effect.
-
- The release of this API with Qt 5.10 is a Technology Preview.
-
- \since 5.10
-*/
-void QDeclarativeGeoMap::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
-{
- if (!m_map)
- return;
-
- const QDoubleVector2D coordWrapped = m_map->geoProjection().geoToWrappedMapProjection(coordinate);
- if (!m_map->geoProjection().isProjectable(coordWrapped))
- return;
-
- const QPointF rotationPoint = m_map->geoProjection().wrappedMapProjectionToItemPosition(coordWrapped).toPointF();
-
- // First set bearing
- setBearing(bearing);
- // then reanchor
- setCenter(m_map->geoProjection().anchorCoordinateToPoint(coordinate, rotationPoint));
-}
-
-/*!
\qmlmethod void QtLocation::Map::alignCoordinateToPoint(coordinate coordinate, QPointF point)
Aligns \a coordinate to \a point.
@@ -1532,10 +1565,23 @@ void QDeclarativeGeoMap::setBearing(qreal bearing, const QGeoCoordinate &coordin
*/
void QDeclarativeGeoMap::alignCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &point)
{
- if (!m_map)
+ if (!m_map || !(m_map->capabilities() & QGeoMap::SupportsAnchoringCoordinate))
+ return;
+
+ const QGeoCoordinate currentCenter = center();
+
+ if (!coordinate.isValid()
+ || !qIsFinite(point.x())
+ || !qIsFinite(point.y()))
return;
- setCenter(m_map->geoProjection().anchorCoordinateToPoint(coordinate, point));
+ if (!m_map->anchorCoordinateToPoint(coordinate, point))
+ return;
+
+ m_cameraData = m_map->cameraData();
+
+ if (m_cameraData.center() != currentCenter)
+ emit centerChanged(m_cameraData.center());
}
/*!
diff --git a/src/location/declarativemaps/qdeclarativegeomapitembase.cpp b/src/location/declarativemaps/qdeclarativegeomapitembase.cpp
index 729825fd..fed0a74b 100644
--- a/src/location/declarativemaps/qdeclarativegeomapitembase.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomapitembase.cpp
@@ -185,11 +185,19 @@ void QDeclarativeGeoMapItemBase::setPositionOnMap(const QGeoCoordinate &coordina
if (!map_ || !quickMap_)
return;
- QDoubleVector2D wrappedProjection = map_->geoProjection().geoToWrappedMapProjection(coordinate);
- if (!map_->geoProjection().isProjectable(wrappedProjection))
- return;
+ QDoubleVector2D pos;
+ if (map()->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
+ QDoubleVector2D wrappedProjection = p.geoToWrappedMapProjection(coordinate);
+ if (!p.isProjectable(wrappedProjection))
+ return;
+ pos = p.wrappedMapProjectionToItemPosition(wrappedProjection);
+ } else {
+ pos = map()->geoProjection().coordinateToItemPosition(coordinate, false);
+ if (qIsNaN(pos.x()))
+ return;
+ }
- QDoubleVector2D pos = map_->geoProjection().wrappedMapProjectionToItemPosition(wrappedProjection);
QPointF topLeft = pos.toPointF() - offset;
setPosition(topLeft);
diff --git a/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp b/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp
index 7c0764aa..43efc940 100644
--- a/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomapquickitem.cpp
@@ -210,9 +210,12 @@ void QDeclarativeGeoMapQuickItem::geometryChanged(const QRectF &newGeometry, con
QGeoCoordinate newCoordinate;
// with zoomLevel set the anchorPoint has to be factored into the transformation to properly transform around it.
- if (zoomLevel_ != 0.0) {
+ if (zoomLevel_ != 0.0
+ && map()->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
+
// When dragStartCoordinate_ can't be projected to screen, dragging must be disabled.
- if (!map()->geoProjection().isProjectable(map()->geoProjection().geoToWrappedMapProjection(dragStartCoordinate_)))
+ if (!p.isProjectable(p.geoToWrappedMapProjection(dragStartCoordinate_)))
return;
QDoubleVector2D pos = map()->geoProjection().coordinateToItemPosition(dragStartCoordinate_, false);
@@ -392,27 +395,42 @@ void QDeclarativeGeoMapQuickItem::updatePolish()
setWidth(sourceItem_.data()->width());
setHeight(sourceItem_.data()->height());
- if (zoomLevel_ != 0.0) { // zoom level initialized to 0.0. If it's different, it has been set explicitly.
+ if (zoomLevel_ != 0.0 // zoom level initialized to 0.0. If it's different, it has been set explicitly.
+ && map()->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) { // Currently unsupported on any other projection
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
+
if (!matrix_) {
matrix_ = new QMapQuickItemMatrix4x4(this);
matrix_->appendToItem(opacityContainer_);
}
- matrix_->setMatrix(map()->geoProjection().quickItemTransformation(coordinate(), anchorPoint_, zoomLevel_));
+ matrix_->setMatrix(p.quickItemTransformation(coordinate(), anchorPoint_, zoomLevel_));
setPosition(QPointF(0,0));
} else {
- // if the coordinate is behind the camera, we use the transformation to get the item out of the way
- if (map()->cameraData().tilt() > 0.0
- && !map()->geoProjection().isProjectable(map()->geoProjection().geoToWrappedMapProjection(coordinate()))) {
- if (!matrix_) {
- matrix_ = new QMapQuickItemMatrix4x4(this);
- matrix_->appendToItem(opacityContainer_);
+ if (map()->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
+ if (map()->cameraData().tilt() > 0.0
+ && !p.isProjectable(p.geoToWrappedMapProjection(coordinate()))) {
+ // if the coordinate is behind the camera, we use the transformation to get the item out of the way
+ if (!matrix_) {
+ matrix_ = new QMapQuickItemMatrix4x4(this);
+ matrix_->appendToItem(opacityContainer_);
+ }
+ matrix_->setMatrix(p.quickItemTransformation(coordinate(), anchorPoint_, map()->cameraData().zoomLevel()));
+ setPosition(QPointF(0,0));
+ } else { // All good, rendering screen-aligned
+ if (matrix_)
+ matrix_->setMatrix(QMatrix4x4());
+ setPositionOnMap(coordinate(), anchorPoint_);
+ }
+ } else { // On other projections we can only currently test if coordinateToItemPosition returns a valid position
+ if (map()->cameraData().tilt() > 0.0
+ && qIsNaN(map()->geoProjection().coordinateToItemPosition(coordinate(), false).x())) {
+ opacityContainer_->setVisible(false);
+ } else {
+ if (matrix_)
+ matrix_->setMatrix(QMatrix4x4());
+ setPositionOnMap(coordinate(), anchorPoint_);
}
- matrix_->setMatrix(map()->geoProjection().quickItemTransformation(coordinate(), anchorPoint_, map()->cameraData().zoomLevel()));
- setPosition(QPointF(0,0));
- } else {
- if (matrix_)
- matrix_->setMatrix(QMatrix4x4());
- setPositionOnMap(coordinate(), anchorPoint_);
}
}
}
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
index 8c7afc17..aa3a3bd9 100644
--- a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
@@ -147,14 +147,14 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
{
if (!sourceDirty_)
return;
-
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection());
srcPath_ = QPainterPath();
// build the actual path
// The approach is the same as described in QGeoMapPolylineGeometry::updateSourcePoints
srcOrigin_ = geoLeftBound_;
double unwrapBelowX = 0;
- QDoubleVector2D leftBoundWrapped = map.geoProjection().wrapMapProjection(map.geoProjection().geoToMapProjection(geoLeftBound_));
+ QDoubleVector2D leftBoundWrapped = p.wrapMapProjection(p.geoToMapProjection(geoLeftBound_));
if (preserveGeometry_)
unwrapBelowX = leftBoundWrapped.x();
@@ -164,7 +164,7 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
// 1)
for (int i = 0; i < path.size(); ++i) {
const QDoubleVector2D &coord = path.at(i);
- QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(coord);
+ QDoubleVector2D wrappedProjection = p.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
@@ -187,7 +187,7 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
// 2)
QList<QList<QDoubleVector2D> > clippedPaths;
- const QList<QDoubleVector2D> &visibleRegion = map.geoProjection().projectableRegion();
+ const QList<QDoubleVector2D> &visibleRegion = p.projectableGeometry();
if (visibleRegion.size()) {
c2t::clip2tri clipper;
clipper.addSubjectPath(QClipperUtils::qListToPath(wrappedPath), true);
@@ -210,17 +210,17 @@ void QGeoMapPolygonGeometry::updateSourcePoints(const QGeoMap &map,
// in turn will make the geometry wrap around.
lb.setX(qMax(wrappedLeftBound.x(), lb.x()));
leftBoundWrapped = lb;
- srcOrigin_ = map.geoProjection().mapProjectionToGeo(map.geoProjection().unwrapMapProjection(lb));
+ srcOrigin_ = p.mapProjectionToGeo(p.unwrapMapProjection(lb));
} else {
clippedPaths.append(wrappedPath);
}
// 3)
- QDoubleVector2D origin = map.geoProjection().wrappedMapProjectionToItemPosition(leftBoundWrapped);
+ QDoubleVector2D origin = p.wrappedMapProjectionToItemPosition(leftBoundWrapped);
for (const QList<QDoubleVector2D> &path: clippedPaths) {
QDoubleVector2D lastAddedPoint;
for (int i = 0; i < path.size(); ++i) {
- QDoubleVector2D point = map.geoProjection().wrappedMapProjectionToItemPosition(path.at(i));
+ QDoubleVector2D point = p.wrappedMapProjectionToItemPosition(path.at(i));
point = point - origin; // (0,0) if point == geoLeftBound_
if (i == 0) {
@@ -500,9 +500,11 @@ QSGNode *QDeclarativePolygonMapItem::updateMapItemPaintNode(QSGNode *oldNode, Up
*/
void QDeclarativePolygonMapItem::updatePolish()
{
- if (!map() || geopath_.path().length() == 0)
+ if (!map() || geopath_.path().length() == 0
+ || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
@@ -527,7 +529,7 @@ void QDeclarativePolygonMapItem::updatePolish()
QDoubleVector2D borderLeftBoundWrapped;
QList<QList<QDoubleVector2D > > clippedPaths = borderGeometry_.clipPath(*map(), closedPath, borderLeftBoundWrapped);
if (clippedPaths.size()) {
- borderLeftBoundWrapped = map()->geoProjection().geoToWrappedMapProjection(geometryOrigin);
+ borderLeftBoundWrapped = p.geoToWrappedMapProjection(geometryOrigin);
borderGeometry_.pathToScreen(*map(), clippedPaths, borderLeftBoundWrapped);
borderGeometry_.updateScreenPoints(*map(), border_.width());
@@ -571,12 +573,13 @@ void QDeclarativePolygonMapItem::afterViewportChanged(const QGeoMapViewportChang
*/
void QDeclarativePolygonMapItem::regenerateCache()
{
- if (!map())
+ if (!map() || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
geopathProjected_.clear();
geopathProjected_.reserve(geopath_.path().size());
for (const QGeoCoordinate &c : geopath_.path())
- geopathProjected_ << map()->geoProjection().geoToMapProjection(c);
+ geopathProjected_ << p.geoToMapProjection(c);
}
/*!
@@ -584,9 +587,10 @@ void QDeclarativePolygonMapItem::regenerateCache()
*/
void QDeclarativePolygonMapItem::updateCache()
{
- if (!map())
+ if (!map() || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
- geopathProjected_ << map()->geoProjection().geoToMapProjection(geopath_.path().last());
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
+ geopathProjected_ << p.geoToMapProjection(geopath_.path().last());
}
/*!
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
index 7c1b922f..90ed95e4 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
@@ -189,11 +189,11 @@ QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &
* 2.1) recalculate the origin and geoLeftBound to prevent these parameters from ending in unprojectable areas
* 2.2) ensure the left bound does not wrap around due to QGeoCoordinate <-> clipper conversions
*/
-
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection());
srcOrigin_ = geoLeftBound_;
double unwrapBelowX = 0;
- leftBoundWrapped = map.geoProjection().wrapMapProjection(map.geoProjection().geoToMapProjection(geoLeftBound_));
+ leftBoundWrapped = p.wrapMapProjection(p.geoToMapProjection(geoLeftBound_));
if (preserveGeometry_)
unwrapBelowX = leftBoundWrapped.x();
@@ -203,7 +203,7 @@ QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &
// 1)
for (int i = 0; i < path.size(); ++i) {
const QDoubleVector2D &coord = path.at(i);
- QDoubleVector2D wrappedProjection = map.geoProjection().wrapMapProjection(coord);
+ QDoubleVector2D wrappedProjection = p.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
@@ -226,7 +226,7 @@ QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &
// 2)
QList<QList<QDoubleVector2D> > clippedPaths;
- const QList<QDoubleVector2D> &visibleRegion = map.geoProjection().projectableRegion();
+ const QList<QDoubleVector2D> &visibleRegion = p.projectableGeometry();
if (visibleRegion.size()) {
c2t::clip2tri clipper;
clipper.addSubjectPath(QClipperUtils::qListToPath(wrappedPath), false);
@@ -265,18 +265,19 @@ void QGeoMapPolylineGeometry::pathToScreen(const QGeoMap &map,
const QList<QList<QDoubleVector2D> > &clippedPaths,
const QDoubleVector2D &leftBoundWrapped)
{
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map.geoProjection());
// 3) project the resulting geometry to screen position and calculate screen bounds
double minX = qInf();
double minY = qInf();
double maxX = -qInf();
double maxY = -qInf();
- srcOrigin_ = map.geoProjection().mapProjectionToGeo(map.geoProjection().unwrapMapProjection(leftBoundWrapped));
- QDoubleVector2D origin = map.geoProjection().wrappedMapProjectionToItemPosition(leftBoundWrapped);
+ srcOrigin_ = p.mapProjectionToGeo(p.unwrapMapProjection(leftBoundWrapped));
+ QDoubleVector2D origin = p.wrappedMapProjectionToItemPosition(leftBoundWrapped);
for (const QList<QDoubleVector2D> &path: clippedPaths) {
QDoubleVector2D lastAddedPoint;
for (int i = 0; i < path.size(); ++i) {
- QDoubleVector2D point = map.geoProjection().wrappedMapProjectionToItemPosition(path.at(i));
+ QDoubleVector2D point = p.wrappedMapProjectionToItemPosition(path.at(i));
point = point - origin; // (0,0) if point == geoLeftBound_
@@ -722,12 +723,13 @@ void QDeclarativePolylineMapItem::afterViewportChanged(const QGeoMapViewportChan
*/
void QDeclarativePolylineMapItem::regenerateCache()
{
- if (!map())
+ if (!map() || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
geopathProjected_.clear();
geopathProjected_.reserve(geopath_.path().size());
for (const QGeoCoordinate &c : geopath_.path())
- geopathProjected_ << map()->geoProjection().geoToMapProjection(c);
+ geopathProjected_ << p.geoToMapProjection(c);
}
/*!
@@ -735,9 +737,10 @@ void QDeclarativePolylineMapItem::regenerateCache()
*/
void QDeclarativePolylineMapItem::updateCache()
{
- if (!map())
+ if (!map() || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
- geopathProjected_ << map()->geoProjection().geoToMapProjection(geopath_.path().last());
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
+ geopathProjected_ << p.geoToMapProjection(geopath_.path().last());
}
/*!
@@ -745,7 +748,8 @@ void QDeclarativePolylineMapItem::updateCache()
*/
void QDeclarativePolylineMapItem::updatePolish()
{
- if (!map() || geopath_.path().length() == 0)
+ if (!map() || geopath_.path().length() == 0
+ || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
QScopedValueRollback<bool> rollback(updatingGeometry_);
diff --git a/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp b/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
index 79750416..0206ac96 100644
--- a/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativerectanglemapitem.cpp
@@ -41,6 +41,7 @@
#include <qnumeric.h>
#include <QRectF>
#include <QPointF>
+#include <QtPositioning/private/qwebmercator_p.h>
#include <QtLocation/private/qgeomap_p.h>
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtCore/QScopedValueRollback>
@@ -272,9 +273,12 @@ QSGNode *QDeclarativeRectangleMapItem::updateMapItemPaintNode(QSGNode *oldNode,
*/
void QDeclarativeRectangleMapItem::updatePolish()
{
- if (!map() || !topLeft().isValid() || !bottomRight().isValid())
+ if (!map() || !topLeft().isValid() || !bottomRight().isValid()
+ || map()->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(map()->geoProjection());
+
QScopedValueRollback<bool> rollback(updatingGeometry_);
updatingGeometry_ = true;
@@ -299,7 +303,7 @@ void QDeclarativeRectangleMapItem::updatePolish()
QDoubleVector2D borderLeftBoundWrapped;
QList<QList<QDoubleVector2D > > clippedPaths = borderGeometry_.clipPath(*map(), closedPath, borderLeftBoundWrapped);
if (clippedPaths.size()) {
- borderLeftBoundWrapped = map()->geoProjection().geoToWrappedMapProjection(geometryOrigin);
+ borderLeftBoundWrapped = p.geoToWrappedMapProjection(geometryOrigin);
borderGeometry_.pathToScreen(*map(), clippedPaths, borderLeftBoundWrapped);
borderGeometry_.updateScreenPoints(*map(), border_.width());
@@ -355,11 +359,11 @@ void QDeclarativeRectangleMapItem::updatePath()
if (!map())
return;
pathMercator_.clear();
- pathMercator_ << map()->geoProjection().geoToMapProjection(rectangle_.topLeft());
- pathMercator_ << map()->geoProjection().geoToMapProjection(
+ pathMercator_ << QWebMercator::coordToMercator(rectangle_.topLeft());
+ pathMercator_ << QWebMercator::coordToMercator(
QGeoCoordinate(rectangle_.topLeft().latitude(), rectangle_.bottomRight().longitude()));
- pathMercator_ << map()->geoProjection().geoToMapProjection(rectangle_.bottomRight());
- pathMercator_ << map()->geoProjection().geoToMapProjection(
+ pathMercator_ << QWebMercator::coordToMercator(rectangle_.bottomRight());
+ pathMercator_ << QWebMercator::coordToMercator(
QGeoCoordinate(rectangle_.bottomRight().latitude(), rectangle_.topLeft().longitude()));
}
diff --git a/src/location/declarativemaps/qquickgeomapgesturearea.cpp b/src/location/declarativemaps/qquickgeomapgesturearea.cpp
index 2f095ee0..1703bcfa 100644
--- a/src/location/declarativemaps/qquickgeomapgesturearea.cpp
+++ b/src/location/declarativemaps/qquickgeomapgesturearea.cpp
@@ -969,7 +969,7 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event)
return;
}
- const QGeoCoordinate &wheelGeoPos = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(event->posF()), false);
+ const QGeoCoordinate &wheelGeoPos = m_declarativeMap->toCoordinate(event->posF(), false);
const QPointF &preZoomPoint = event->posF();
// Not using AltModifier as, for some reason, it causes angleDelta to be 0
@@ -977,9 +977,7 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event)
emit rotationStarted(&m_pinch.m_event);
// First set bearing
const double bearingDelta = event->angleDelta().y() * qreal(0.05);
- m_declarativeMap->setBearing(m_declarativeMap->bearing() + bearingDelta);
- // then reanchor
- m_declarativeMap->setCenter(m_map->geoProjection().anchorCoordinateToPoint(wheelGeoPos, preZoomPoint));
+ m_declarativeMap->setBearing(m_declarativeMap->bearing() + bearingDelta, wheelGeoPos);
emit rotationUpdated(&m_pinch.m_event);
emit rotationFinished(&m_pinch.m_event);
} else if (event->modifiers() & Qt::ControlModifier && tiltEnabled()) {
@@ -993,10 +991,10 @@ void QQuickGeoMapGestureArea::handleWheelEvent(QWheelEvent *event)
// Gesture area should always honor maxZL, but Map might not.
m_declarativeMap->setZoomLevel(qMin<qreal>(m_declarativeMap->zoomLevel() + zoomLevelDelta, maximumZoomLevel()),
false);
- const QPointF &postZoomPoint = m_map->geoProjection().coordinateToItemPosition(wheelGeoPos, false).toPointF();
+ const QPointF &postZoomPoint = m_declarativeMap->fromCoordinate(wheelGeoPos, false);
if (preZoomPoint != postZoomPoint) // need to re-anchor the wheel geoPos to the event position
- m_declarativeMap->setCenter(m_map->geoProjection().anchorCoordinateToPoint(wheelGeoPos, preZoomPoint));
+ m_declarativeMap->alignCoordinateToPoint(wheelGeoPos, preZoomPoint);
}
event->accept();
}
@@ -1134,7 +1132,7 @@ void QQuickGeoMapGestureArea::touchPointStateMachine()
if (m_allPoints.count() == 0) {
setTouchPointState(touchPoints0);
} else if (m_allPoints.count() == 2) {
- m_touchCenterCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_touchPointsCentroid), false);
+ m_touchCenterCoord = m_declarativeMap->toCoordinate(m_touchPointsCentroid, false);
startTwoTouchPoints();
setTouchPointState(touchPoints2);
}
@@ -1143,7 +1141,7 @@ void QQuickGeoMapGestureArea::touchPointStateMachine()
if (m_allPoints.count() == 0) {
setTouchPointState(touchPoints0);
} else if (m_allPoints.count() == 1) {
- m_touchCenterCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_touchPointsCentroid), false);
+ m_touchCenterCoord = m_declarativeMap->toCoordinate(m_touchPointsCentroid, false);
startOneTouchPoint();
setTouchPointState(touchPoints1);
}
@@ -1171,7 +1169,7 @@ void QQuickGeoMapGestureArea::startOneTouchPoint()
m_sceneStartPoint1 = mapFromScene(m_allPoints.at(0).scenePos());
m_lastPos = m_sceneStartPoint1;
m_lastPosTime.start();
- QGeoCoordinate startCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_sceneStartPoint1), false);
+ QGeoCoordinate startCoord = m_declarativeMap->toCoordinate(m_sceneStartPoint1, false);
// ensures a smooth transition for panning
m_startCoord.setLongitude(m_startCoord.longitude() + startCoord.longitude() -
m_touchCenterCoord.longitude());
@@ -1198,7 +1196,7 @@ void QQuickGeoMapGestureArea::startTwoTouchPoints()
QPointF startPos = (m_sceneStartPoint1 + m_sceneStartPoint2) * 0.5;
m_lastPos = startPos;
m_lastPosTime.start();
- QGeoCoordinate startCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(startPos), false);
+ QGeoCoordinate startCoord = m_declarativeMap->toCoordinate(startPos, false);
m_startCoord.setLongitude(m_startCoord.longitude() + startCoord.longitude() -
m_touchCenterCoord.longitude());
m_startCoord.setLatitude(m_startCoord.latitude() + startCoord.latitude() -
@@ -1668,7 +1666,7 @@ void QQuickGeoMapGestureArea::panStateMachine()
case flickInactive:
if (!isTiltActive() && canStartPan()) {
// Update startCoord_ to ensure smooth start for panning when going over startDragDistance
- QGeoCoordinate newStartCoord = m_map->geoProjection().itemPositionToCoordinate(QDoubleVector2D(m_touchPointsCentroid), false);
+ QGeoCoordinate newStartCoord = m_declarativeMap->toCoordinate(m_touchPointsCentroid, false);
m_startCoord.setLongitude(newStartCoord.longitude());
m_startCoord.setLatitude(newStartCoord.latitude());
m_declarativeMap->setKeepMouseGrab(true);
@@ -1743,8 +1741,7 @@ bool QQuickGeoMapGestureArea::canStartPan()
*/
void QQuickGeoMapGestureArea::updatePan()
{
- QGeoCoordinate animationStartCoordinate = m_map->geoProjection().anchorCoordinateToPoint(m_startCoord, m_touchPointsCentroid);
- m_declarativeMap->setCenter(animationStartCoordinate);
+ m_declarativeMap->alignCoordinateToPoint(m_startCoord, m_touchPointsCentroid);
}
/*!