summaryrefslogtreecommitdiff
path: root/src/location/maps
diff options
context:
space:
mode:
Diffstat (limited to 'src/location/maps')
-rw-r--r--src/location/maps/qgeomap.cpp7
-rw-r--r--src/location/maps/qgeomap_p.h3
-rw-r--r--src/location/maps/qgeoprojection.cpp72
-rw-r--r--src/location/maps/qgeoprojection_p.h25
-rw-r--r--src/location/maps/qgeotiledmap.cpp4
5 files changed, 100 insertions, 11 deletions
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index dc8aa2c8..51af9199 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -41,6 +41,7 @@
#include "qdeclarativegeomapitembase_p.h"
#include "qgeomapobject_p.h"
#include "qgeomapobject_p_p.h"
+#include <QtQuick/private/qquickitem_p.h>
#include <QDebug>
#include <QRectF>
@@ -310,6 +311,12 @@ QList<QObject *> QGeoMap::mapObjectsAt(const QGeoCoordinate &/*coordinate*/) con
return QList<QObject *>();
}
+void QGeoMap::setItemToWindowTransform(const QTransform &itemToWindowTransform)
+{
+ Q_D(QGeoMap);
+ d->m_geoProjection->setItemToWindowTransform(itemToWindowTransform);
+}
+
void QGeoMap::setVisibleArea(const QRectF &visibleArea)
{
Q_D(QGeoMap);
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index 216c8b64..e955b513 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -55,6 +55,7 @@
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtLocation/private/qgeoprojection_p.h>
#include <QtLocation/qgeoroute.h>
+#include <QTransform>
QT_BEGIN_NAMESPACE
@@ -67,6 +68,7 @@ class QQuickWindow;
class QGeoMapParameter;
class QDeclarativeGeoMapItemBase;
class QGeoMapObject;
+class QDeclarativeGeoMap;
class Q_LOCATION_PRIVATE_EXPORT QGeoMap : public QObject
{
@@ -155,6 +157,7 @@ public:
virtual void setCopyrightVisible(bool visible);
virtual void removeMapObject(QGeoMapObject *obj);
virtual QList<QObject *> mapObjectsAt(const QGeoCoordinate &coordinate) const;
+ virtual void setItemToWindowTransform(const QTransform &itemToWindowTransform);
void setVisibleArea(const QRectF &visibleArea);
QRectF visibleArea() const;
diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp
index f64060e2..ff6a0b77 100644
--- a/src/location/maps/qgeoprojection.cpp
+++ b/src/location/maps/qgeoprojection.cpp
@@ -118,6 +118,19 @@ bool QGeoProjection::setBearing(qreal bearing, const QGeoCoordinate &coordinate)
return false;
}
+void QGeoProjection::setItemToWindowTransform(const QTransform &itemToWindowTransform)
+{
+ if (m_itemToWindowTransform == itemToWindowTransform)
+ return;
+ m_qsgTransformDirty = true;
+ m_itemToWindowTransform = itemToWindowTransform;
+}
+
+QTransform QGeoProjection::itemToWindowTransform() const
+{
+ return m_itemToWindowTransform;
+}
+
/*
* QGeoProjectionWebMercator implementation
@@ -188,6 +201,31 @@ double QGeoProjectionWebMercator::minimumZoom() const
return m_minimumZoom;
}
+QMatrix4x4 QGeoProjectionWebMercator::projectionTransformation() const
+{
+ return toMatrix4x4(m_transformation);
+}
+
+QMatrix4x4 QGeoProjectionWebMercator::projectionTransformation_centered() const
+{
+ return toMatrix4x4(m_transformation0);
+}
+
+const QMatrix4x4 &QGeoProjectionWebMercator::qsgTransform() const
+{
+ if (m_qsgTransformDirty) {
+ m_qsgTransformDirty = false;
+ m_qsgTransform = QMatrix4x4(m_itemToWindowTransform) * toMatrix4x4(m_transformation0);
+// qDebug() << "QGeoProjectionWebMercator::qsgTransform" << m_itemToWindowTransform << toMatrix4x4(m_transformation0);
+ }
+ return m_qsgTransform;
+}
+
+QDoubleVector3D QGeoProjectionWebMercator::centerMercator() const
+{
+ return geoToMapProjection(m_cameraData.center()).toVector3D();
+}
+
// This method recalculates the "no-trespassing" limits for the map center.
// This has to be used when:
// 1) the map is resized, because the meters per pixel remain the same, but
@@ -273,19 +311,23 @@ QGeoCoordinate QGeoProjectionWebMercator::mapProjectionToGeo(const QDoubleVector
return QWebMercator::mercatorToCoord(projection);
}
-//wraps around center
-QDoubleVector2D QGeoProjectionWebMercator::wrapMapProjection(const QDoubleVector2D &projection) const
+int QGeoProjectionWebMercator::projectionWrapFactor(const QDoubleVector2D &projection) const
{
- double x = projection.x();
+ const double &x = projection.x();
if (m_cameraCenterXMercator < 0.5) {
if (x - m_cameraCenterXMercator > 0.5 )
- x -= 1.0;
+ return -1;
} else if (m_cameraCenterXMercator > 0.5) {
if (x - m_cameraCenterXMercator < -0.5 )
- x += 1.0;
+ return 1;
}
+ return 0;
+}
- return QDoubleVector2D(x, projection.y());
+//wraps around center
+QDoubleVector2D QGeoProjectionWebMercator::wrapMapProjection(const QDoubleVector2D &projection) const
+{
+ return QDoubleVector2D(projection.x() + double(projectionWrapFactor(projection)), projection.y());
}
QDoubleVector2D QGeoProjectionWebMercator::unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const
@@ -547,6 +589,7 @@ QGeoProjection::ProjectionType QGeoProjectionWebMercator::projectionType() const
void QGeoProjectionWebMercator::setupCamera()
{
+ m_qsgTransformDirty = true;
m_centerMercator = geoToMapProjection(m_cameraData.center());
m_cameraCenterXMercator = m_centerMercator.x();
m_cameraCenterYMercator = m_centerMercator.y();
@@ -571,6 +614,10 @@ void QGeoProjectionWebMercator::setupCamera()
// And in mercator space
m_eyeMercator = m_centerMercator;
m_eyeMercator.setZ(altitude_mercator / m_aperture);
+ m_eyeMercator0 = QDoubleVector3D(0,0,0);
+ m_eyeMercator0.setZ(altitude_mercator / m_aperture);
+ QDoubleVector3D eye0(0,0,0);
+ eye0.setZ(altitude * defaultTileSize / m_aperture);
m_view = m_eye - m_center;
QDoubleVector3D side = QDoubleVector3D::normal(m_view, QDoubleVector3D(0.0, 1.0, 0.0));
@@ -599,11 +646,13 @@ void QGeoProjectionWebMercator::setupCamera()
QDoubleMatrix4x4 mTilt;
mTilt.rotate(-m_cameraData.tilt(), m_side);
m_eye = mTilt * m_view + m_center;
+ eye0 = mTilt * m_view;
// In mercator space too
QDoubleMatrix4x4 mTiltMercator;
mTiltMercator.rotate(-m_cameraData.tilt(), m_sideMercator);
m_eyeMercator = mTiltMercator * m_viewMercator + m_centerMercator;
+ m_eyeMercator0 = mTiltMercator * m_viewMercator;
}
m_view = m_eye - m_center; // ToDo: this should be inverted (center - eye), and the rest should follow
@@ -634,8 +683,10 @@ void QGeoProjectionWebMercator::setupCamera()
double verticalHalfFOV = QLocationUtils::degrees(atan(m_aperture));
- QDoubleMatrix4x4 cameraMatrix;
- cameraMatrix.lookAt(m_eye, m_center, m_up);
+ m_cameraMatrix.setToIdentity();
+ m_cameraMatrix.lookAt(m_eye, m_center, m_up);
+ m_cameraMatrix0.setToIdentity();
+ m_cameraMatrix0.lookAt(eye0, QDoubleVector3D(0,0,0), m_up);
QDoubleMatrix4x4 projectionMatrix;
projectionMatrix.frustum(-m_halfWidth, m_halfWidth, -m_halfHeight, m_halfHeight, m_nearPlane, m_farPlane);
@@ -656,10 +707,13 @@ void QGeoProjectionWebMercator::setupCamera()
matScreenTransformation(0,3) = (0.5 + offsetPct.x()) * m_viewportWidth;
matScreenTransformation(1,3) = (0.5 + offsetPct.y()) * m_viewportHeight;
- m_transformation = matScreenTransformation * projectionMatrix * cameraMatrix;
+ m_transformation = matScreenTransformation * projectionMatrix * m_cameraMatrix;
m_quickItemTransformation = m_transformation;
m_transformation.scale(m_sideLengthPixels, m_sideLengthPixels, 1.0);
+ m_transformation0 = matScreenTransformation * projectionMatrix * m_cameraMatrix0;
+ m_transformation0.scale(m_sideLengthPixels, m_sideLengthPixels, 1.0);
+
m_centerNearPlane = m_eye - m_viewNormalized;
m_centerNearPlaneMercator = m_eyeMercator - m_viewNormalized * m_nearPlaneMercator;
diff --git a/src/location/maps/qgeoprojection_p.h b/src/location/maps/qgeoprojection_p.h
index 2e1af8c5..9a75246a 100644
--- a/src/location/maps/qgeoprojection_p.h
+++ b/src/location/maps/qgeoprojection_p.h
@@ -52,6 +52,8 @@
#include <QtLocation/private/qgeocameradata_p.h>
#include <QtPositioning/private/qdoublematrix4x4_p.h>
#include <QtPositioning/QGeoShape>
+#include <QMatrix4x4>
+#include <QTransform>
QT_BEGIN_NAMESPACE
@@ -107,6 +109,17 @@ public:
virtual QGeoShape visibleRegion() const;
virtual bool setBearing(qreal bearing, const QGeoCoordinate &coordinate);
+ virtual QMatrix4x4 projectionTransformation() const = 0; // This brings a mercator coord into the correct viewport coordinate.
+ virtual QMatrix4x4 projectionTransformation_centered() const = 0; // Same as projectionTransformation, but the center of the camera is around 0,0.
+ // Requires subsequent shifting of the geometry to fit such camera.
+ virtual const QMatrix4x4 &qsgTransform() const = 0;
+ virtual QDoubleVector3D centerMercator() const = 0;
+
+ void setItemToWindowTransform(const QTransform &itemToWindowTransform);
+ virtual QTransform itemToWindowTransform() const;
+
+ QTransform m_itemToWindowTransform;
+ mutable bool m_qsgTransformDirty = true;
};
class Q_LOCATION_PRIVATE_EXPORT QGeoProjectionWebMercator : public QGeoProjection
@@ -117,6 +130,11 @@ public:
// From QGeoProjection
double minimumZoom() const override;
+ QMatrix4x4 projectionTransformation() const override;
+ QMatrix4x4 projectionTransformation_centered() const override;
+ const QMatrix4x4 &qsgTransform() const override;
+ QDoubleVector3D centerMercator() const override;
+
double maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const override;
double minimumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const override;
@@ -144,6 +162,7 @@ public:
QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const;
QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const;
+ int projectionWrapFactor(const QDoubleVector2D &projection) const;
QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const;
QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const;
@@ -213,7 +232,10 @@ protected:
double m_1_viewportWidth;
double m_1_viewportHeight;
+ QDoubleMatrix4x4 m_cameraMatrix;
+ QDoubleMatrix4x4 m_cameraMatrix0;
QDoubleMatrix4x4 m_transformation;
+ QDoubleMatrix4x4 m_transformation0;
QDoubleMatrix4x4 m_quickItemTransformation;
QDoubleVector3D m_eye;
QDoubleVector3D m_up;
@@ -234,6 +256,7 @@ protected:
// For the clipping region
QDoubleVector3D m_centerMercator;
QDoubleVector3D m_eyeMercator;
+ QDoubleVector3D m_eyeMercator0;
QDoubleVector3D m_viewMercator;
QDoubleVector3D m_upMercator;
QDoubleVector3D m_sideMercator;
@@ -245,6 +268,8 @@ protected:
QList<QDoubleVector2D> m_visibleRegionExpanded;
QList<QDoubleVector2D> m_projectableRegion;
bool m_visibleRegionDirty;
+
+ mutable QMatrix4x4 m_qsgTransform;
QRectF m_visibleArea;
Q_DISABLE_COPY(QGeoProjectionWebMercator)
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index 74346fdb..e6c91042 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -329,7 +329,7 @@ void QGeoTiledMapPrivate::changeCameraData(const QGeoCameraData &cameraData)
m_mapScene->setCameraData(cam);
updateScene();
- q->sgNodeChanged();
+ q->sgNodeChanged(); // ToDo: explain why emitting twice
}
void QGeoTiledMapPrivate::updateScene()
@@ -371,7 +371,7 @@ void QGeoTiledMapPrivate::setVisibleArea(const QRectF &visibleArea)
if (m_copyrightVisible)
q->evaluateCopyrights(m_mapScene->visibleTiles());
updateScene();
- q->sgNodeChanged();
+ q->sgNodeChanged(); // ToDo: explain why emitting twice
}
QRectF QGeoTiledMapPrivate::visibleArea() const