diff options
Diffstat (limited to 'src/location/maps')
-rw-r--r-- | src/location/maps/qgeomap.cpp | 7 | ||||
-rw-r--r-- | src/location/maps/qgeomap_p.h | 3 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection.cpp | 72 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection_p.h | 25 | ||||
-rw-r--r-- | src/location/maps/qgeotiledmap.cpp | 4 |
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 |