summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
-rw-r--r--src/location/maps/qgeomap.cpp59
-rw-r--r--src/location/maps/qgeomap_p.h18
-rw-r--r--src/location/maps/qgeomap_p_p.h3
-rw-r--r--src/location/maps/qgeoprojection.cpp95
-rw-r--r--src/location/maps/qgeoprojection_p.h118
-rw-r--r--src/location/maps/qgeotiledmap.cpp7
-rw-r--r--src/location/maps/qgeotiledmap_p.h1
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp7
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h1
-rw-r--r--src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp6
18 files changed, 515 insertions, 235 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);
}
/*!
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index 529ebf82..4ac36fed 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -91,7 +91,7 @@ void QGeoMap::setCameraData(const QGeoCameraData &cameraData)
if (cameraData == d->m_cameraData)
return;
d->m_cameraData = cameraData;
- d->m_geoProjection->setCameraData(cameraData);
+ d->m_geoProjection->setCameraData(cameraData, false);
d->changeCameraData(cameraData);
emit cameraDataChanged(d->m_cameraData);
}
@@ -108,6 +108,40 @@ bool QGeoMap::handleEvent(QEvent *event)
return false;
}
+bool QGeoMap::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
+{
+ Q_D(QGeoMap);
+ bool res = d->m_geoProjection->setBearing(bearing, coordinate);
+ if (!res)
+ return false;
+
+ setCameraData(geoProjection().cameraData());
+ return true;
+}
+
+bool QGeoMap::anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint)
+{
+ QGeoCoordinate newCenter = geoProjection().anchorCoordinateToPoint(coordinate, anchorPoint);
+ QGeoCameraData data = cameraData();
+ if (data.center() != newCenter) {
+ data.setCenter(newCenter);
+ setCameraData(data);
+ return true;
+ }
+ return false;
+}
+
+bool QGeoMap::fitViewportToGeoRectangle(const QGeoRectangle &rectangle)
+{
+ Q_UNUSED(rectangle)
+ return false;
+}
+
+QGeoShape QGeoMap::visibleRegion() const
+{
+ return geoProjection().visibleRegion();
+}
+
QGeoCameraData QGeoMap::cameraData() const
{
Q_D(const QGeoMap);
@@ -146,13 +180,13 @@ double QGeoMap::maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) co
double QGeoMap::mapWidth() const
{
Q_D(const QGeoMap);
- return d->m_geoProjection->mapWidth();
+ return d->mapWidth();
}
double QGeoMap::mapHeight() const
{
Q_D(const QGeoMap);
- return d->m_geoProjection->mapHeight();
+ return d->mapHeight();
}
const QGeoProjection &QGeoMap::geoProjection() const
@@ -167,6 +201,11 @@ QGeoCameraCapabilities QGeoMap::cameraCapabilities() const
return d->m_cameraCapabilities;
}
+QGeoMap::Capabilities QGeoMap::capabilities() const
+{
+ return Capabilities(QGeoMap::SupportsNothing);
+}
+
void QGeoMap::prefetchData()
{
@@ -337,4 +376,18 @@ QList<QGeoMapObject *> QGeoMapPrivate::mapObjects() const
return QList<QGeoMapObject *>();
}
+double QGeoMapPrivate::mapWidth() const
+{
+ if (m_geoProjection->projectionType() == QGeoProjection::ProjectionWebMercator)
+ return static_cast<const QGeoProjectionWebMercator *>(m_geoProjection)->mapWidth();
+ return 0; // override this for maps supporting other projections
+}
+
+double QGeoMapPrivate::mapHeight() const
+{
+ if (m_geoProjection->projectionType() == QGeoProjection::ProjectionWebMercator)
+ return static_cast<const QGeoProjectionWebMercator *>(m_geoProjection)->mapHeight();
+ return 0; // override this for maps supporting other projections
+}
+
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index 7c7825f2..b2382099 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -73,6 +73,8 @@ class Q_LOCATION_PRIVATE_EXPORT QGeoMap : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QGeoMap)
+ Q_ENUMS(Capability)
+ Q_FLAGS(Capabilities)
public:
enum ItemType {
NoItem = 0x0000,
@@ -86,6 +88,16 @@ public:
Q_DECLARE_FLAGS(ItemTypes, ItemType)
+ enum Capability {
+ SupportsNothing = 0x0000,
+ SupportsVisibleRegion = 0x0001,
+ SupportsSetBearing = 0x0002,
+ SupportsAnchoringCoordinate = 0x0004,
+ SupportsFittingViewportToGeoRectangle = 0x0008
+ };
+
+ Q_DECLARE_FLAGS(Capabilities, Capability)
+
virtual ~QGeoMap();
// Sets the display size
@@ -97,6 +109,7 @@ public:
QGeoCameraData cameraData() const;
QGeoCameraCapabilities cameraCapabilities() const;
+ virtual Capabilities capabilities() const;
void setActiveMapType(const QGeoMapType mapType);
const QGeoMapType activeMapType() const;
@@ -132,6 +145,11 @@ public:
virtual void setAcceptedGestures(bool pan, bool flick, bool pinch, bool rotate, bool tilt);
virtual bool handleEvent(QEvent *event);
+ 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);
+
protected:
QGeoMap(QGeoMapPrivate &dd, QObject *parent = 0);
void setCameraData(const QGeoCameraData &cameraData);
diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h
index 80fc70d2..d6ab40b6 100644
--- a/src/location/maps/qgeomap_p_p.h
+++ b/src/location/maps/qgeomap_p_p.h
@@ -96,6 +96,9 @@ protected:
virtual void changeCameraData(const QGeoCameraData &oldCameraData) = 0; // called by QGeoMap::setCameraData()
virtual void changeActiveMapType(const QGeoMapType mapType) = 0; // called by QGeoMap::setActiveMapType()
+ virtual double mapWidth() const;
+ virtual double mapHeight() const;
+
protected:
QSize m_viewportSize;
QGeoProjection *m_geoProjection;
diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp
index 1df174fb..1ab9970b 100644
--- a/src/location/maps/qgeoprojection.cpp
+++ b/src/location/maps/qgeoprojection.cpp
@@ -38,6 +38,7 @@
#include <QtPositioning/private/qwebmercator_p.h>
#include <QtPositioning/private/qlocationutils_p.h>
#include <QtPositioning/private/qclipperutils_p.h>
+#include <QtPositioning/QGeoPolygon>
#include <QSize>
#include <QtGui/QMatrix4x4>
#include <cmath>
@@ -75,6 +76,30 @@ QGeoProjection::~QGeoProjection()
QGeoCoordinate QGeoProjection::anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const
{
+ Q_UNUSED(coordinate)
+ Q_UNUSED(anchorPoint)
+ return QGeoCoordinate();
+}
+
+QGeoShape QGeoProjection::visibleRegion() const
+{
+ return QGeoShape();
+}
+
+bool QGeoProjection::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
+{
+ Q_UNUSED(bearing)
+ Q_UNUSED(coordinate)
+ return false;
+}
+
+
+/*
+ * QGeoProjectionWebMercator implementation
+*/
+
+QGeoCoordinate QGeoProjectionWebMercator::anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const
+{
// Approach: find the displacement in (wrapped) mercator space, and apply that to the center
QDoubleVector2D centerProj = geoToWrappedMapProjection(cameraData().center());
QDoubleVector2D coordProj = geoToWrappedMapProjection(coordinate);
@@ -84,9 +109,25 @@ QGeoCoordinate QGeoProjection::anchorCoordinateToPoint(const QGeoCoordinate &coo
return wrappedMapProjectionToGeo(centerProj + coordProj - anchorProj);
}
-/*
- * QGeoProjectionWebMercator implementation
-*/
+bool QGeoProjectionWebMercator::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
+{
+ const QDoubleVector2D coordWrapped = geoToWrappedMapProjection(coordinate);
+ if (!isProjectable(coordWrapped))
+ return false;
+ const QPointF rotationPoint = wrappedMapProjectionToItemPosition(coordWrapped).toPointF();
+
+ QGeoCameraData camera = cameraData();
+ // first set bearing
+ camera.setBearing(bearing);
+ setCameraData(camera);
+ camera = cameraData();
+
+ // then reanchor
+ const QGeoCoordinate center = anchorCoordinateToPoint(coordinate, rotationPoint);
+ camera.setCenter(center);
+ setCameraData(camera);
+ return true;
+}
QGeoProjectionWebMercator::QGeoProjectionWebMercator()
: QGeoProjection(),
@@ -154,6 +195,9 @@ double QGeoProjectionWebMercator::mapHeight() const
void QGeoProjectionWebMercator::setViewportSize(const QSize &size)
{
+ if (int(m_viewportWidth) == size.width() && int(m_viewportHeight) == size.height())
+ return;
+
m_viewportWidth = size.width();
m_viewportHeight = size.height();
m_1_viewportWidth = 1.0 / m_viewportWidth;
@@ -162,8 +206,11 @@ void QGeoProjectionWebMercator::setViewportSize(const QSize &size)
setupCamera();
}
-void QGeoProjectionWebMercator::setCameraData(const QGeoCameraData &cameraData)
+void QGeoProjectionWebMercator::setCameraData(const QGeoCameraData &cameraData, bool force)
{
+ if (m_cameraData == cameraData && !force)
+ return;
+
m_cameraData = cameraData;
m_mapEdgeSize = std::pow(2.0, cameraData.zoomLevel()) * defaultTileSize;
setupCamera();
@@ -331,20 +378,41 @@ bool QGeoProjectionWebMercator::isProjectable(const QDoubleVector2D &wrappedProj
return true;
}
-QList<QDoubleVector2D> QGeoProjectionWebMercator::visibleRegion() const
+QList<QDoubleVector2D> QGeoProjectionWebMercator::visibleGeometry() const
{
if (m_visibleRegionDirty)
const_cast<QGeoProjectionWebMercator *>(this)->updateVisibleRegion();
return m_visibleRegion;
}
-QList<QDoubleVector2D> QGeoProjectionWebMercator::projectableRegion() const
+QList<QDoubleVector2D> QGeoProjectionWebMercator::projectableGeometry() const
{
if (m_visibleRegionDirty)
const_cast<QGeoProjectionWebMercator *>(this)->updateVisibleRegion();
return m_projectableRegion;
}
+QGeoShape QGeoProjectionWebMercator::visibleRegion() const
+{
+ const QList<QDoubleVector2D> &visibleRegion = visibleGeometry();
+ 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(wrappedMapProjectionToGeo(extraPoint));
+ }
+ poly.addCoordinate(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(wrappedMapProjectionToGeo(extraPoint));
+ }
+
+ return poly;
+}
+
QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const
{
double s;
@@ -369,6 +437,21 @@ QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const
return (xyPlane.lineIntersection(m_eye, ray, s) / m_sideLength).toVector2D();
}
+QGeoProjection::ProjectionGroup QGeoProjectionWebMercator::projectionGroup() const
+{
+ return QGeoProjection::ProjectionCylindrical;
+}
+
+QGeoProjection::Datum QGeoProjectionWebMercator::datum() const
+{
+ return QGeoProjection::DatumWGS84;
+}
+
+QGeoProjection::ProjectionType QGeoProjectionWebMercator::projectionType() const
+{
+ return QGeoProjection::ProjectionWebMercator;
+}
+
void QGeoProjectionWebMercator::setupCamera()
{
m_centerMercator = geoToMapProjection(m_cameraData.center());
diff --git a/src/location/maps/qgeoprojection_p.h b/src/location/maps/qgeoprojection_p.h
index ca81df3a..dc05d4d1 100644
--- a/src/location/maps/qgeoprojection_p.h
+++ b/src/location/maps/qgeoprojection_p.h
@@ -51,53 +51,60 @@
#include <QtLocation/private/qlocationglobal_p.h>
#include <QtLocation/private/qgeocameradata_p.h>
#include <QtPositioning/private/qdoublematrix4x4_p.h>
+#include <QtPositioning/QGeoShape>
QT_BEGIN_NAMESPACE
class Q_LOCATION_PRIVATE_EXPORT QGeoProjection
{
public:
+ enum ProjectionGroup {
+ ProjectionOther,
+ ProjectionCylindrical,
+ ProjectionPseudocylindrical,
+ ProjectionAzimuthal,
+ ProjectionPseudoazimuthal,
+ ProjectionConic,
+ ProjectionPseudoconic
+ //Polyhedral
+ //Retroazimuthal
+ };
+
+ enum Datum {
+ DatumUnknown,
+ DatumWGS84,
+ DatumSphere
+ };
+
+ enum ProjectionType {
+ ProjectionUnknown,
+ ProjectionGeneralPerspective,
+ ProjectionWebMercator
+ };
+
QGeoProjection();
virtual ~QGeoProjection();
virtual void setViewportSize(const QSize &size) = 0;
- virtual void setCameraData(const QGeoCameraData &cameraData) = 0;
+ virtual void setCameraData(const QGeoCameraData &cameraData, bool force = true) = 0;
+ virtual QGeoCameraData cameraData() const = 0;
// returns the minimum zoom at the current viewport size
virtual double minimumZoom() const = 0;
virtual double maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const = 0;
- // returns the size of the underlying map, at the current zoom level.
- virtual double mapWidth() const = 0;
- virtual double mapHeight() const = 0;
-
- virtual bool isProjectable(const QDoubleVector2D &wrappedProjection) const = 0;
- virtual QList<QDoubleVector2D> visibleRegion() const = 0;
- virtual QList<QDoubleVector2D> projectableRegion() const = 0;
-
- // Conversion methods for QGeoCoordinate <-> screen.
- // This currently assumes that the "MapProjection" space is [0, 1][0, 1] for every type of possibly supported map projection
- virtual QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const = 0;
- virtual QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const = 0;
-
- virtual QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const = 0;
- virtual QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const = 0;
-
- virtual QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const = 0;
- virtual QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const = 0;
-
- // Convenience methods to avoid the chain itemPositionToWrappedProjection(wrapProjection(geoToProjection()))
virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const = 0;
virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const = 0;
- virtual QDoubleVector2D geoToWrappedMapProjection(const QGeoCoordinate &coordinate) const = 0;
- virtual QGeoCoordinate wrappedMapProjectionToGeo(const QDoubleVector2D &wrappedProjection) const = 0;
- virtual QMatrix4x4 quickItemTransformation(const QGeoCoordinate &coordinate, const QPointF &anchorPoint, qreal zoomLevel) const = 0;
+
+ virtual ProjectionGroup projectionGroup() const = 0;
+ virtual Datum datum() const = 0;
+ virtual ProjectionType projectionType() const = 0;
// Returns the new map center after anchoring coordinate to anchorPoint on the screen
- QGeoCoordinate anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const;
+ virtual QGeoCoordinate anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const;
-private:
- virtual QGeoCameraData cameraData() const = 0;
+ virtual QGeoShape visibleRegion() const;
+ virtual bool setBearing(qreal bearing, const QGeoCoordinate &coordinate);
};
class Q_LOCATION_PRIVATE_EXPORT QGeoProjectionWebMercator : public QGeoProjection
@@ -106,40 +113,53 @@ public:
QGeoProjectionWebMercator();
~QGeoProjectionWebMercator();
- double minimumZoom() const Q_DECL_OVERRIDE;
- double maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const Q_DECL_OVERRIDE;
+ // From QGeoProjection
+ double minimumZoom() const override;
+ double maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const override;
+
+ void setViewportSize(const QSize &size) override;
+ void setCameraData(const QGeoCameraData &cameraData, bool force = true) override;
+ QGeoCameraData cameraData() const override;
- // The size of the underlying map, at the current zoom level.
- double mapWidth() const Q_DECL_OVERRIDE;
- double mapHeight() const Q_DECL_OVERRIDE;
+ QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const override;
+ QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const override;
- void setViewportSize(const QSize &size) Q_DECL_OVERRIDE;
- void setCameraData(const QGeoCameraData &cameraData) Q_DECL_OVERRIDE;
+ QGeoProjection::ProjectionGroup projectionGroup() const override;
+ QGeoProjection::Datum datum() const override;
+ QGeoProjection::ProjectionType projectionType() const override;
- QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const Q_DECL_OVERRIDE;
- QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const Q_DECL_OVERRIDE;
+ QGeoCoordinate anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const override;
+ bool setBearing(qreal bearing, const QGeoCoordinate &coordinate) override;
- QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const Q_DECL_OVERRIDE;
- QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE;
+ QGeoShape visibleRegion() const override;
- QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE;
- QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const Q_DECL_OVERRIDE;
+ // Specific to QGeoProjectionWebMercator
+ double mapWidth() const; // The size of the underlying map, at the current zoom level.
+ double mapHeight() const;
- QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const Q_DECL_OVERRIDE;
- QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const Q_DECL_OVERRIDE;
- QDoubleVector2D geoToWrappedMapProjection(const QGeoCoordinate &coordinate) const Q_DECL_OVERRIDE;
- QGeoCoordinate wrappedMapProjectionToGeo(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE;
- QMatrix4x4 quickItemTransformation(const QGeoCoordinate &coordinate, const QPointF &anchorPoint, qreal zoomLevel) const Q_DECL_OVERRIDE;
+ QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const;
+ QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const;
+
+ QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const;
+ QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const;
+
+ QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const;
+ QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const;
+
+ QDoubleVector2D geoToWrappedMapProjection(const QGeoCoordinate &coordinate) const;
+ QGeoCoordinate wrappedMapProjectionToGeo(const QDoubleVector2D &wrappedProjection) const;
+ QMatrix4x4 quickItemTransformation(const QGeoCoordinate &coordinate, const QPointF &anchorPoint, qreal zoomLevel) const;
+
+ bool isProjectable(const QDoubleVector2D &wrappedProjection) const;
+ QList<QDoubleVector2D> visibleGeometry() const;
+ QList<QDoubleVector2D> projectableGeometry() const;
- bool isProjectable(const QDoubleVector2D &wrappedProjection) const Q_DECL_OVERRIDE;
- QList<QDoubleVector2D> visibleRegion() const Q_DECL_OVERRIDE;
- QList<QDoubleVector2D> projectableRegion() const Q_DECL_OVERRIDE;
inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const;
inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition, double &s) const;
+
private:
void setupCamera();
void updateVisibleRegion();
- QGeoCameraData cameraData() const Q_DECL_OVERRIDE;
public:
struct Line2D
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index 0eeb189d..81eb3b14 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -143,6 +143,13 @@ void QGeoTiledMap::clearData()
d->m_mapScene->clearTexturedTiles();
}
+QGeoMap::Capabilities QGeoTiledMap::capabilities() const
+{
+ return Capabilities(SupportsVisibleRegion
+ | SupportsSetBearing
+ | SupportsAnchoringCoordinate);
+}
+
void QGeoTiledMap::clearScene(int mapId)
{
Q_D(QGeoTiledMap);
diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h
index b709cb57..6152d60d 100644
--- a/src/location/maps/qgeotiledmap_p.h
+++ b/src/location/maps/qgeotiledmap_p.h
@@ -86,6 +86,7 @@ public:
void prefetchData() Q_DECL_OVERRIDE;
void clearData() Q_DECL_OVERRIDE;
+ Capabilities capabilities() const override;
public Q_SLOTS:
virtual void clearScene(int mapId);
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
index dd5c9a86..c04aa5e3 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
+++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
@@ -372,6 +372,13 @@ void QGeoMapMapboxGL::setMapItemsBefore(const QString &before)
d->m_mapItemsBefore = before;
}
+QGeoMap::Capabilities QGeoMapMapboxGL::capabilities() const
+{
+ return Capabilities(SupportsVisibleRegion
+ | SupportsSetBearing
+ | SupportsAnchoringCoordinate);
+}
+
QSGNode *QGeoMapMapboxGL::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
{
Q_D(QGeoMapMapboxGL);
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
index 73cfd75a..df76fcab 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
+++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
@@ -57,6 +57,7 @@ public:
void setMapboxGLSettings(const QMapboxGLSettings &);
void setUseFBO(bool);
void setMapItemsBefore(const QString &);
+ Capabilities capabilities() const override;
private Q_SLOTS:
// QMapboxGL
diff --git a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp
index f39bfae3..4835c201 100644
--- a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp
+++ b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp
@@ -89,18 +89,18 @@ QMapbox::Feature featureFromMapRectangle(QDeclarativeRectangleMapItem *mapItem)
QMapbox::Feature featureFromMapCircle(QDeclarativeCircleMapItem *mapItem)
{
static const int circleSamples = 128;
-
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(mapItem->map()->geoProjection());
QList<QGeoCoordinate> path;
QGeoCoordinate leftBound;
QDeclarativeCircleMapItem::calculatePeripheralPoints(path, mapItem->center(), mapItem->radius(), circleSamples, leftBound);
QList<QDoubleVector2D> pathProjected;
for (const QGeoCoordinate &c : qAsConst(path))
- pathProjected << mapItem->map()->geoProjection().geoToMapProjection(c);
+ pathProjected << p.geoToMapProjection(c);
if (QDeclarativeCircleMapItem::crossEarthPole(mapItem->center(), mapItem->radius()))
mapItem->preserveCircleGeometry(pathProjected, mapItem->center(), mapItem->radius());
path.clear();
for (const QDoubleVector2D &c : qAsConst(pathProjected))
- path << mapItem->map()->geoProjection().mapProjectionToGeo(c);
+ path << p.mapProjectionToGeo(c);
QMapbox::Coordinates coordinates;