summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2018-11-11 14:16:49 +0100
committerPaolo Angelelli <paolo.angelelli@qt.io>2018-11-28 18:45:36 +0000
commitbe0658bfdb37de213f6b54837706aabc2d088d62 (patch)
tree99444eee90e4e69e787289c280218d2474f787aa
parent9307404d2dcb0b53d0dfcad6c28677cc2aba4a12 (diff)
downloadqtlocation-be0658bfdb37de213f6b54837706aabc2d088d62.tar.gz
Make tiled renderer and QGeoProjectionWebMercator debuggable
This patch introduces a new macro, QT_LOCATION_DEBUG, that, when fed via qmake command line, changes the scope of some members, adds some extra members and some extra data dumping into these members. In this way external code can inspect the state of the renderer in order to debug it. The patch also moves a few classes into separate files, as well as privately exporting them. Change-Id: I32a042863f78dcd10f94b0b7fe8b90f3fc486891 Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
-rw-r--r--.qmake.conf5
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp10
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem_p.h11
-rw-r--r--src/location/maps/maps.pri3
-rw-r--r--src/location/maps/qgeocameratiles.cpp90
-rw-r--r--src/location/maps/qgeocameratiles_p.h2
-rw-r--r--src/location/maps/qgeocameratiles_p_p.h152
-rw-r--r--src/location/maps/qgeomap_p_p.h4
-rw-r--r--src/location/maps/qgeoprojection.cpp14
-rw-r--r--src/location/maps/qgeoprojection_p.h8
-rw-r--r--src/location/maps/qgeotiledmap_p_p.h4
-rw-r--r--src/location/maps/qgeotiledmapscene.cpp154
-rw-r--r--src/location/maps/qgeotiledmapscene_p_p.h193
13 files changed, 444 insertions, 206 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 3566a973..0815e3b5 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,3 +2,8 @@ load(qt_build_config)
CONFIG += warning_clean
MODULE_VERSION = 5.12.0
+
+# Adds a way to debug location. The define is needed for multiple subprojects as they
+# include the essential headers.
+# Alternatively, the define can be passed directly to qmake
+# DEFINES+=QT_LOCATION_DEBUG
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
index aeb7b718..2fb3098d 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
@@ -398,6 +398,10 @@ QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &
wrappedPath.append(wrappedProjection);
}
+#ifdef QT_LOCATION_DEBUG
+ m_wrappedPath = wrappedPath;
+#endif
+
// 2)
QList<QList<QDoubleVector2D> > clippedPaths;
const QList<QDoubleVector2D> &visibleRegion = p.projectableGeometry();
@@ -428,6 +432,10 @@ QList<QList<QDoubleVector2D> > QGeoMapPolylineGeometry::clipPath(const QGeoMap &
clippedPaths.append(wrappedPath);
}
+#ifdef QT_LOCATION_DEBUG
+ m_clippedPaths = clippedPaths;
+#endif
+
return clippedPaths;
}
@@ -441,14 +449,12 @@ void QGeoMapPolylineGeometry::pathToScreen(const QGeoMap &map,
double minY = qInf();
double maxX = -qInf();
double maxY = -qInf();
-
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 = p.wrappedMapProjectionToItemPosition(path.at(i));
-
point = point - origin; // (0,0) if point == geoLeftBound_
minX = qMin(point.x(), minX);
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
index 392841dd..1105bb13 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem_p.h
@@ -48,6 +48,7 @@
// We mean it.
//
+#include <QtLocation/private/qlocationglobal_p.h>
#include <QtLocation/private/qdeclarativegeomapitembase_p.h>
#include <QtLocation/private/qgeomapitemgeometry_p.h>
@@ -110,10 +111,15 @@ public:
const QList<QList<QDoubleVector2D> > &clippedPaths,
const QDoubleVector2D &leftBoundWrapped);
-private:
+public:
QVector<qreal> srcPoints_;
QVector<QPainterPath::ElementType> srcPointTypes_;
+#ifdef QT_LOCATION_DEBUG
+ QList<QDoubleVector2D> m_wrappedPath;
+ QList<QList<QDoubleVector2D>> m_clippedPaths;
+#endif
+
friend class QDeclarativeCircleMapItem;
friend class QDeclarativePolygonMapItem;
friend class QDeclarativeRectangleMapItem;
@@ -171,6 +177,9 @@ private:
void regenerateCache();
void updateCache();
+#ifdef QT_LOCATION_DEBUG
+public:
+#endif
QGeoPath geopath_;
QList<QDoubleVector2D> geopathProjected_;
QDeclarativeMapLineProperties line_;
diff --git a/src/location/maps/maps.pri b/src/location/maps/maps.pri
index b5be4601..68e80442 100644
--- a/src/location/maps/maps.pri
+++ b/src/location/maps/maps.pri
@@ -62,6 +62,8 @@ PRIVATE_HEADERS += \
maps/qgeoprojection_p.h \
maps/qnavigationmanagerengine_p.h \
maps/qnavigationmanager_p.h \
+ maps/qgeocameratiles_p_p.h \
+ maps/qgeotiledmapscene_p_p.h \
maps/qcache3q_p.h
SOURCES += \
@@ -100,3 +102,4 @@ SOURCES += \
maps/qnavigationmanagerengine.cpp \
maps/qnavigationmanager.cpp \
maps/qgeoprojection.cpp
+
diff --git a/src/location/maps/qgeocameratiles.cpp b/src/location/maps/qgeocameratiles.cpp
index b7eac306..3a2732b2 100644
--- a/src/location/maps/qgeocameratiles.cpp
+++ b/src/location/maps/qgeocameratiles.cpp
@@ -34,6 +34,7 @@
**
****************************************************************************/
#include "qgeocameratiles_p.h"
+#include "qgeocameratiles_p_p.h"
#include "qgeocameradata_p.h"
#include "qgeotilespec_p.h"
#include "qgeomaptype_p.h"
@@ -63,76 +64,6 @@ static QDoubleVector3D toDoubleVector3D(const QVector3D& in)
QT_BEGIN_NAMESPACE
-struct Frustum
-{
- QDoubleVector3D apex;
- QDoubleVector3D topLeftNear;
- QDoubleVector3D topLeftFar;
- QDoubleVector3D topRightNear;
- QDoubleVector3D topRightFar;
- QDoubleVector3D bottomLeftNear;
- QDoubleVector3D bottomLeftFar;
- QDoubleVector3D bottomRightNear;
- QDoubleVector3D bottomRightFar;
-};
-
-typedef QVector<QDoubleVector3D> PolygonVector;
-
-class QGeoCameraTilesPrivate
-{
-public:
- QGeoCameraTilesPrivate();
- ~QGeoCameraTilesPrivate();
-
- QString m_pluginString;
- QGeoMapType m_mapType;
- int m_mapVersion;
- QGeoCameraData m_camera;
- QSize m_screenSize;
- QRectF m_visibleArea;
- int m_tileSize;
- QSet<QGeoTileSpec> m_tiles;
-
- int m_intZoomLevel;
- int m_sideLength;
-
- bool m_dirtyGeometry;
- bool m_dirtyMetadata;
-
- double m_viewExpansion;
- void updateMetadata();
- void updateGeometry();
-
- Frustum createFrustum(double viewExpansion) const;
-
- struct ClippedFootprint
- {
- ClippedFootprint(const PolygonVector &left_, const PolygonVector &mid_, const PolygonVector &right_)
- : left(left_), mid(mid_), right(right_)
- {}
- PolygonVector left;
- PolygonVector mid;
- PolygonVector right;
- };
-
- PolygonVector frustumFootprint(const Frustum &frustum) const;
-
- QPair<PolygonVector, PolygonVector> splitPolygonAtAxisValue(const PolygonVector &polygon, int axis, double value) const;
- ClippedFootprint clipFootprintToMap(const PolygonVector &footprint) const;
-
- QList<QPair<double, int> > tileIntersections(double p1, int t1, double p2, int t2) const;
- QSet<QGeoTileSpec> tilesFromPolygon(const PolygonVector &polygon) const;
-
- struct TileMap
- {
- TileMap();
-
- void add(int tileX, int tileY);
-
- QMap<int, QPair<int, int> > data;
- };
-};
-
QGeoCameraTiles::QGeoCameraTiles()
: d_ptr(new QGeoCameraTilesPrivate()) {}
@@ -277,12 +208,22 @@ void QGeoCameraTilesPrivate::updateGeometry()
// Find the frustum from the camera / screen / viewport information
// The larger frustum when stationary is a form of prefetching
Frustum f = createFrustum(m_viewExpansion);
+#ifdef QT_LOCATION_DEBUG
+ m_frustum = f;
+#endif
// Find the polygon where the frustum intersects the plane of the map
PolygonVector footprint = frustumFootprint(f);
+#ifdef QT_LOCATION_DEBUG
+ m_frustumFootprint = footprint;
+#endif
// Clip the polygon to the map, split it up if it cross the dateline
ClippedFootprint polygons = clipFootprintToMap(footprint);
+#ifdef QT_LOCATION_DEBUG
+ m_clippedFootprint = polygons;
+#endif
+
if (!polygons.left.isEmpty()) {
QSet<QGeoTileSpec> tilesLeft = tilesFromPolygon(polygons.left);
@@ -306,6 +247,10 @@ Frustum QGeoCameraTilesPrivate::createFrustum(double viewExpansion) const
if (m_camera.fieldOfView() != 90.0) //aperture(90 / 2) = 1
apertureSize = tan(QLocationUtils::radians(m_camera.fieldOfView()) * 0.5);
QDoubleVector3D center = m_sideLength * QWebMercator::coordToMercator(m_camera.center());
+#ifdef QT_LOCATION_DEBUG
+ m_createFrustum_center = center;
+#endif
+
double f = m_screenSize.height();
@@ -335,7 +280,7 @@ Frustum QGeoCameraTilesPrivate::createFrustum(double viewExpansion) const
side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0));
up = QDoubleVector3D::normal(view, side2);
- double nearPlane = 1 / (4.0 * m_tileSize );
+ double nearPlane = 1.0 / 32.0; // The denominator used to be (4.0 * m_tileSize ), which produces an extremely narrow and tiny near plane.
// farPlane plays a role on how much gets clipped when the map gets tilted. It used to be altitude + 1.0
// The value of 8.0 has been chosen as an acceptable compromise.
// TODO: use m_camera.clipDistance(); when this will be introduced
@@ -367,6 +312,9 @@ Frustum QGeoCameraTilesPrivate::createFrustum(double viewExpansion) const
Frustum frustum;
frustum.apex = eye;
+#ifdef QT_LOCATION_DEBUG
+ m_createFrustum_eye = eye;
+#endif
QRectF va = m_visibleArea;
if (va.isNull())
diff --git a/src/location/maps/qgeocameratiles_p.h b/src/location/maps/qgeocameratiles_p.h
index f95db44d..4b6f3234 100644
--- a/src/location/maps/qgeocameratiles_p.h
+++ b/src/location/maps/qgeocameratiles_p.h
@@ -79,6 +79,8 @@ public:
protected:
QScopedPointer<QGeoCameraTilesPrivate> d_ptr;
+
+ friend class QGeoCameraTilesPrivate;
Q_DISABLE_COPY(QGeoCameraTiles)
};
diff --git a/src/location/maps/qgeocameratiles_p_p.h b/src/location/maps/qgeocameratiles_p_p.h
new file mode 100644
index 00000000..846d95f2
--- /dev/null
+++ b/src/location/maps/qgeocameratiles_p_p.h
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QGEOCAMERATILES_P_P_H
+#define QGEOCAMERATILES_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgeocameratiles_p.h"
+#include <QtPositioning/private/qwebmercator_p.h>
+#include <QtPositioning/private/qdoublevector2d_p.h>
+#include <QtPositioning/private/qdoublevector3d_p.h>
+#include "qgeomaptype_p.h"
+#include "qgeocameradata_p.h"
+#include "qgeotilespec_p.h"
+
+#include <QtCore/qvector.h>
+#include <QtCore/qset.h>
+
+QT_BEGIN_NAMESPACE
+
+struct Q_LOCATION_PRIVATE_EXPORT Frustum
+{
+ QDoubleVector3D apex;
+ QDoubleVector3D topLeftNear;
+ QDoubleVector3D topLeftFar;
+ QDoubleVector3D topRightNear;
+ QDoubleVector3D topRightFar;
+ QDoubleVector3D bottomLeftNear;
+ QDoubleVector3D bottomLeftFar;
+ QDoubleVector3D bottomRightNear;
+ QDoubleVector3D bottomRightFar;
+};
+
+typedef QVector<QDoubleVector3D> PolygonVector;
+
+class Q_LOCATION_PRIVATE_EXPORT QGeoCameraTilesPrivate
+{
+public:
+ struct ClippedFootprint
+ {
+ ClippedFootprint()
+ {}
+ ClippedFootprint(const PolygonVector &left_, const PolygonVector &mid_, const PolygonVector &right_)
+ : left(left_), mid(mid_), right(right_)
+ {}
+ PolygonVector left;
+ PolygonVector mid;
+ PolygonVector right;
+ };
+
+ struct TileMap
+ {
+ TileMap();
+
+ void add(int tileX, int tileY);
+
+ QMap<int, QPair<int, int> > data;
+ };
+
+ QGeoCameraTilesPrivate();
+ ~QGeoCameraTilesPrivate();
+
+
+ void updateMetadata();
+ void updateGeometry();
+
+ Frustum createFrustum(double viewExpansion) const;
+ PolygonVector frustumFootprint(const Frustum &frustum) const;
+
+ QPair<PolygonVector, PolygonVector> splitPolygonAtAxisValue(const PolygonVector &polygon, int axis, double value) const;
+ ClippedFootprint clipFootprintToMap(const PolygonVector &footprint) const;
+
+ QList<QPair<double, int> > tileIntersections(double p1, int t1, double p2, int t2) const;
+ QSet<QGeoTileSpec> tilesFromPolygon(const PolygonVector &polygon) const;
+
+ static QGeoCameraTilesPrivate *get(QGeoCameraTiles *o) {
+ return o->d_ptr.data();
+ }
+
+public:
+ QString m_pluginString;
+ QGeoMapType m_mapType;
+ int m_mapVersion;
+ QGeoCameraData m_camera;
+ QSize m_screenSize;
+ QRectF m_visibleArea;
+ int m_tileSize;
+ QSet<QGeoTileSpec> m_tiles;
+
+ int m_intZoomLevel;
+ int m_sideLength;
+ bool m_dirtyGeometry;
+ bool m_dirtyMetadata;
+ double m_viewExpansion;
+
+#ifdef QT_LOCATION_DEBUG
+ // updateGeometry
+ ClippedFootprint m_clippedFootprint;
+ PolygonVector m_frustumFootprint;
+ Frustum m_frustum;
+
+ // createFrustum
+ mutable QDoubleVector3D m_createFrustum_center;
+ mutable QDoubleVector3D m_createFrustum_eye;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOCAMERATILES_P_P_H
diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h
index 7bda316d..331697b2 100644
--- a/src/location/maps/qgeomap_p_p.h
+++ b/src/location/maps/qgeomap_p_p.h
@@ -110,7 +110,11 @@ protected:
QRectF clampVisibleArea(const QRectF &visibleArea) const;
+#ifdef QT_LOCATION_DEBUG
+public:
+#else
protected:
+#endif
QSize m_viewportSize;
QGeoProjection *m_geoProjection;
QPointer<QGeoMappingManagerEngine> m_engine;
diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp
index 7961ec70..0fdb5f0b 100644
--- a/src/location/maps/qgeoprojection.cpp
+++ b/src/location/maps/qgeoprojection.cpp
@@ -164,7 +164,7 @@ QGeoProjectionWebMercator::QGeoProjectionWebMercator()
m_viewportHeight(1),
m_1_viewportWidth(0),
m_1_viewportHeight(0),
- m_sideLength(256),
+ m_sideLengthPixels(256),
m_aperture(0.0),
m_nearPlane(0.0),
m_farPlane(0.0),
@@ -389,7 +389,7 @@ QMatrix4x4 QGeoProjectionWebMercator::quickItemTransformation(const QGeoCoordina
const QDoubleVector2D anchorMercator = anchorScaled / mapWidth();
const QDoubleVector2D coordAnchored = coordWrapped - anchorMercator;
- const QDoubleVector2D coordAnchoredScaled = coordAnchored * m_sideLength;
+ const QDoubleVector2D coordAnchoredScaled = coordAnchored * m_sideLengthPixels;
QDoubleMatrix4x4 matTranslateScale;
matTranslateScale.translate(coordAnchoredScaled.x(), coordAnchoredScaled.y(), 0.0);
@@ -416,7 +416,7 @@ bool QGeoProjectionWebMercator::isProjectable(const QDoubleVector2D &wrappedProj
if (m_cameraData.tilt() == 0.0)
return true;
- QDoubleVector3D pos = wrappedProjection * m_sideLength;
+ QDoubleVector3D pos = wrappedProjection * m_sideLengthPixels;
// use m_centerNearPlane in order to add an offset to m_eye.
QDoubleVector3D p = m_centerNearPlane - pos;
double dot = QDoubleVector3D::dotProduct(p , m_viewNormalized);
@@ -491,7 +491,7 @@ QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const
QDoubleVector3D ray = m_eye - p;
ray.normalize();
- return (xyPlane.lineIntersection(m_eye, ray, s) / m_sideLength).toVector2D();
+ return (xyPlane.lineIntersection(m_eye, ray, s) / m_sideLengthPixels).toVector2D();
}
/*
@@ -552,8 +552,8 @@ void QGeoProjectionWebMercator::setupCamera()
m_cameraCenterYMercator = m_centerMercator.y();
int intZoomLevel = static_cast<int>(std::floor(m_cameraData.zoomLevel()));
- m_sideLength = (1 << intZoomLevel) * defaultTileSize;
- m_center = m_centerMercator * m_sideLength;
+ m_sideLengthPixels = (1 << intZoomLevel) * defaultTileSize;
+ m_center = m_centerMercator * m_sideLengthPixels;
//aperture(90 / 2) = 1
m_aperture = tan(QLocationUtils::radians(m_cameraData.fieldOfView()) * 0.5);
@@ -658,7 +658,7 @@ void QGeoProjectionWebMercator::setupCamera()
m_transformation = matScreenTransformation * projectionMatrix * cameraMatrix;
m_quickItemTransformation = m_transformation;
- m_transformation.scale(m_sideLength, m_sideLength, 1.0);
+ m_transformation.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 e33ae880..2e1af8c5 100644
--- a/src/location/maps/qgeoprojection_p.h
+++ b/src/location/maps/qgeoprojection_p.h
@@ -195,7 +195,11 @@ public:
QDoubleVector3D m_normal;
};
-private:
+#ifdef QT_LOCATION_DEBUG
+public:
+#else
+protected:
+#endif
QGeoCameraData m_cameraData;
double m_mapEdgeSize;
double m_minimumZoom;
@@ -218,7 +222,7 @@ private:
QDoubleVector3D m_viewNormalized;
QDoubleVector3D m_side;
QDoubleVector3D m_centerNearPlane;
- double m_sideLength; // map edge size at integer zoom level
+ double m_sideLengthPixels; // map edge size at integer zoom level
double m_aperture;
double m_nearPlane;
double m_farPlane;
diff --git a/src/location/maps/qgeotiledmap_p_p.h b/src/location/maps/qgeotiledmap_p_p.h
index 0ba349ca..80f658e0 100644
--- a/src/location/maps/qgeotiledmap_p_p.h
+++ b/src/location/maps/qgeotiledmap_p_p.h
@@ -94,7 +94,11 @@ protected:
void setVisibleArea(const QRectF &visibleArea) override;
QRectF visibleArea() const override;
+#ifdef QT_LOCATION_DEBUG
+public:
+#else
protected:
+#endif
QAbstractGeoTileCache *m_cache;
QGeoCameraTiles *m_visibleTiles;
QGeoCameraTiles *m_prefetchTiles;
diff --git a/src/location/maps/qgeotiledmapscene.cpp b/src/location/maps/qgeotiledmapscene.cpp
index 4709a48f..074b67c6 100644
--- a/src/location/maps/qgeotiledmapscene.cpp
+++ b/src/location/maps/qgeotiledmapscene.cpp
@@ -35,15 +35,14 @@
**
****************************************************************************/
#include "qgeotiledmapscene_p.h"
+#include "qgeotiledmapscene_p_p.h"
#include "qgeocameradata_p.h"
#include "qabstractgeotilecache_p.h"
#include "qgeotilespec_p.h"
#include <QtPositioning/private/qdoublevector3d_p.h>
#include <QtPositioning/private/qwebmercator_p.h>
#include <QtCore/private/qobject_p.h>
-#include <QtQuick/QSGImageNode>
#include <QtQuick/QQuickWindow>
-#include <QtQuick/private/qsgdefaultimagenode_p.h>
#include <QtGui/QVector3D>
#include <cmath>
#include <QtPositioning/private/qlocationutils_p.h>
@@ -57,61 +56,6 @@ static QVector3D toVector3D(const QDoubleVector3D& in)
QT_BEGIN_NAMESPACE
-class QGeoTiledMapScenePrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QGeoTiledMapScene)
-public:
- QGeoTiledMapScenePrivate();
- ~QGeoTiledMapScenePrivate();
-
- QSize m_screenSize; // in pixels
- int m_tileSize; // the pixel resolution for each tile
- QGeoCameraData m_cameraData;
- QRectF m_visibleArea;
- QSet<QGeoTileSpec> m_visibleTiles;
-
- QDoubleVector3D m_cameraUp;
- QDoubleVector3D m_cameraEye;
- QDoubleVector3D m_cameraCenter;
- QMatrix4x4 m_projectionMatrix;
-
- // scales up the tile geometry and the camera altitude, resulting in no visible effect
- // other than to control the accuracy of the render by keeping the values in a sensible range
- double m_scaleFactor;
-
- // rounded down, positive zoom is zooming in, corresponding to reduced altitude
- int m_intZoomLevel;
-
- // mercatorToGrid transform
- // the number of tiles in each direction for the whole map (earth) at the current zoom level.
- // it is 1<<zoomLevel
- int m_sideLength;
- double m_mapEdgeSize;
-
- QHash<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > m_textures;
- QVector<QGeoTileSpec> m_updatedTextures;
-
- // tilesToGrid transform
- int m_minTileX; // the minimum tile index, i.e. 0 to sideLength which is 1<< zoomLevel
- int m_minTileY;
- int m_maxTileX;
- int m_maxTileY;
- int m_tileXWrapsBelow; // the wrap point as a tile index
-
- bool m_linearScaling;
-
- bool m_dropTextures;
-
- void addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture);
-
- void setVisibleTiles(const QSet<QGeoTileSpec> &visibleTiles);
- void removeTiles(const QSet<QGeoTileSpec> &oldTiles);
- bool buildGeometry(const QGeoTileSpec &spec, QSGImageNode *imageNode, bool &overzooming);
- void updateTileBounds(const QSet<QGeoTileSpec> &tiles);
- void setupCamera();
- inline bool isTiltedOrRotated() { return (m_cameraData.tilt() > 0.0) || (m_cameraData.bearing() > 0.0); }
-};
-
QGeoTiledMapScene::QGeoTiledMapScene(QObject *parent)
: QObject(*new QGeoTiledMapScenePrivate(),parent)
{
@@ -201,7 +145,11 @@ void QGeoTiledMapScene::clearTexturedTiles()
QGeoTiledMapScenePrivate::QGeoTiledMapScenePrivate()
: QObjectPrivate(),
m_tileSize(0),
+#ifdef QT_LOCATION_DEBUG
+ m_scaleFactor(1.0),
+#else
m_scaleFactor(10.0),
+#endif
m_intZoomLevel(0),
m_sideLength(0),
m_minTileX(-1),
@@ -503,71 +451,6 @@ void QGeoTiledMapScenePrivate::setupCamera()
nearPlane, farPlane);
}
-class QGeoTiledMapTileContainerNode : public QSGTransformNode
-{
-public:
- void addChild(const QGeoTileSpec &spec, QSGImageNode *node)
- {
- tiles.insert(spec, node);
- appendChildNode(node);
- }
- QHash<QGeoTileSpec, QSGImageNode *> tiles;
-};
-
-class QGeoTiledMapRootNode : public QSGClipNode
-{
-public:
- QGeoTiledMapRootNode()
- : isTextureLinear(false)
- , geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
- , root(new QSGTransformNode())
- , tiles(new QGeoTiledMapTileContainerNode())
- , wrapLeft(new QGeoTiledMapTileContainerNode())
- , wrapRight(new QGeoTiledMapTileContainerNode())
- {
- setIsRectangular(true);
- setGeometry(&geometry);
- root->appendChildNode(tiles);
- root->appendChildNode(wrapLeft);
- root->appendChildNode(wrapRight);
- appendChildNode(root);
- }
-
- ~QGeoTiledMapRootNode()
- {
- qDeleteAll(textures);
- }
-
- void setClipRect(const QRect &rect)
- {
- if (rect != clipRect) {
- QSGGeometry::updateRectGeometry(&geometry, rect);
- QSGClipNode::setClipRect(rect);
- clipRect = rect;
- markDirty(DirtyGeometry);
- }
- }
-
- void updateTiles(QGeoTiledMapTileContainerNode *root,
- QGeoTiledMapScenePrivate *d,
- double camAdjust,
- QQuickWindow *window,
- bool ogl);
-
- bool isTextureLinear;
-
- QSGGeometry geometry;
- QRect clipRect;
-
- QSGTransformNode *root;
-
- QGeoTiledMapTileContainerNode *tiles; // The majority of the tiles
- QGeoTiledMapTileContainerNode *wrapLeft; // When zoomed out, the tiles that wrap around on the left.
- QGeoTiledMapTileContainerNode *wrapRight; // When zoomed out, the tiles that wrap around on the right
-
- QHash<QGeoTileSpec, QSGTexture *> textures;
-};
-
static bool qgeotiledmapscene_isTileInViewport_Straight(const QRectF &tileRect, const QMatrix4x4 &matrix)
{
const QRectF boundingRect = QRectF(matrix * tileRect.topLeft(), matrix * tileRect.bottomRight());
@@ -621,6 +504,9 @@ void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
bool straight = !d->isTiltedOrRotated();
bool overzooming;
qreal pixelRatio = window->effectiveDevicePixelRatio();
+#ifdef QT_LOCATION_DEBUG
+ QList<QGeoTileSpec> droppedTiles;
+#endif
for (QHash<QGeoTileSpec, QSGImageNode *>::iterator it = root->tiles.begin();
it != root->tiles.end(); ) {
QSGImageNode *node = it.value();
@@ -630,6 +516,9 @@ void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
QSGNode::DirtyState dirtyBits = 0;
if (!ok) {
+#ifdef QT_LOCATION_DEBUG
+ droppedTiles.append(it.key());
+#endif
it = root->tiles.erase(it);
delete node;
} else {
@@ -656,8 +545,12 @@ void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
for (const QGeoTileSpec &s : toAdd) {
QGeoTileTexture *tileTexture = d->m_textures.value(s).data();
- if (!tileTexture || tileTexture->image.isNull())
+ if (!tileTexture || tileTexture->image.isNull()) {
+#ifdef QT_LOCATION_DEBUG
+ droppedTiles.append(s);
+#endif
continue;
+ }
QSGImageNode *tileNode = window->createImageNode();
// note: setTexture will update coordinates so do it here, before we buildGeometry
tileNode->setTexture(textures.value(s));
@@ -675,9 +568,16 @@ void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
#endif
root->addChild(s, tileNode);
} else {
+#ifdef QT_LOCATION_DEBUG
+ droppedTiles.append(s);
+#endif
delete tileNode;
}
}
+
+#ifdef QT_LOCATION_DEBUG
+ m_droppedTiles[camAdjust] = droppedTiles;
+#endif
}
QSGNode *QGeoTiledMapScene::updateSceneGraph(QSGNode *oldNode, QQuickWindow *window)
@@ -695,6 +595,11 @@ QSGNode *QGeoTiledMapScene::updateSceneGraph(QSGNode *oldNode, QQuickWindow *win
if (!mapRoot)
mapRoot = new QGeoTiledMapRootNode();
+#ifdef QT_LOCATION_DEBUG
+ mapRoot->m_droppedTiles.clear();
+ d->m_mapRoot = mapRoot;
+#endif
+
// Setting clip rect to fullscreen, as now the map can never be smaller than the viewport.
mapRoot->setClipRect(QRect(0, 0, w, h));
@@ -749,6 +654,9 @@ QSGNode *QGeoTiledMapScene::updateSceneGraph(QSGNode *oldNode, QQuickWindow *win
}
double sideLength = d->m_scaleFactor * d->m_tileSize * d->m_sideLength;
+#ifdef QT_LOCATION_DEBUG
+ d->m_sideLengthPixel = sideLength;
+#endif
mapRoot->updateTiles(mapRoot->tiles, d, 0, window, isOpenGL);
mapRoot->updateTiles(mapRoot->wrapLeft, d, +sideLength, window, isOpenGL);
mapRoot->updateTiles(mapRoot->wrapRight, d, -sideLength, window, isOpenGL);
diff --git a/src/location/maps/qgeotiledmapscene_p_p.h b/src/location/maps/qgeotiledmapscene_p_p.h
new file mode 100644
index 00000000..5d98abd5
--- /dev/null
+++ b/src/location/maps/qgeotiledmapscene_p_p.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPLv3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QGEOTILEDMAPSCENE_P_P_H
+#define QGEOTILEDMAPSCENE_P_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qgeotiledmapscene_p.h"
+#include <QtCore/private/qobject_p.h>
+#include <QtPositioning/private/qdoublevector3d_p.h>
+#include <QtQuick/QSGImageNode>
+#include <QtQuick/private/qsgdefaultimagenode_p.h>
+#include <QtQuick/QQuickWindow>
+#include "qgeocameradata_p.h"
+#include "qgeotilespec_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class Q_LOCATION_PRIVATE_EXPORT QGeoTiledMapTileContainerNode : public QSGTransformNode
+{
+public:
+ void addChild(const QGeoTileSpec &spec, QSGImageNode *node)
+ {
+ tiles.insert(spec, node);
+ appendChildNode(node);
+ }
+ QHash<QGeoTileSpec, QSGImageNode *> tiles;
+};
+
+class Q_LOCATION_PRIVATE_EXPORT QGeoTiledMapRootNode : public QSGClipNode
+{
+public:
+ QGeoTiledMapRootNode()
+ : isTextureLinear(false)
+ , geometry(QSGGeometry::defaultAttributes_Point2D(), 4)
+ , root(new QSGTransformNode())
+ , tiles(new QGeoTiledMapTileContainerNode())
+ , wrapLeft(new QGeoTiledMapTileContainerNode())
+ , wrapRight(new QGeoTiledMapTileContainerNode())
+ {
+ setIsRectangular(true);
+ setGeometry(&geometry);
+ root->appendChildNode(tiles);
+ root->appendChildNode(wrapLeft);
+ root->appendChildNode(wrapRight);
+ appendChildNode(root);
+ }
+
+ ~QGeoTiledMapRootNode()
+ {
+ qDeleteAll(textures);
+ }
+
+ void setClipRect(const QRect &rect)
+ {
+ if (rect != clipRect) {
+ QSGGeometry::updateRectGeometry(&geometry, rect);
+ QSGClipNode::setClipRect(rect);
+ clipRect = rect;
+ markDirty(DirtyGeometry);
+ }
+ }
+
+ void updateTiles(QGeoTiledMapTileContainerNode *root,
+ QGeoTiledMapScenePrivate *d,
+ double camAdjust,
+ QQuickWindow *window,
+ bool ogl);
+
+ bool isTextureLinear;
+
+ QSGGeometry geometry;
+ QRect clipRect;
+
+ QSGTransformNode *root;
+
+ QGeoTiledMapTileContainerNode *tiles; // The majority of the tiles
+ QGeoTiledMapTileContainerNode *wrapLeft; // When zoomed out, the tiles that wrap around on the left.
+ QGeoTiledMapTileContainerNode *wrapRight; // When zoomed out, the tiles that wrap around on the right
+
+ QHash<QGeoTileSpec, QSGTexture *> textures;
+
+#ifdef QT_LOCATION_DEBUG
+ double m_sideLengthPixel;
+ QMap<double, QList<QGeoTileSpec>> m_droppedTiles;
+#endif
+};
+
+class Q_LOCATION_PRIVATE_EXPORT QGeoTiledMapScenePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QGeoTiledMapScene)
+public:
+ QGeoTiledMapScenePrivate();
+ ~QGeoTiledMapScenePrivate();
+
+ void addTile(const QGeoTileSpec &spec, QSharedPointer<QGeoTileTexture> texture);
+
+ void setVisibleTiles(const QSet<QGeoTileSpec> &visibleTiles);
+ void removeTiles(const QSet<QGeoTileSpec> &oldTiles);
+ bool buildGeometry(const QGeoTileSpec &spec, QSGImageNode *imageNode, bool &overzooming);
+ void updateTileBounds(const QSet<QGeoTileSpec> &tiles);
+ void setupCamera();
+ inline bool isTiltedOrRotated() { return (m_cameraData.tilt() > 0.0) || (m_cameraData.bearing() > 0.0); }
+
+public:
+
+ QSize m_screenSize; // in pixels
+ int m_tileSize; // the pixel resolution for each tile
+ QGeoCameraData m_cameraData;
+ QRectF m_visibleArea;
+ QSet<QGeoTileSpec> m_visibleTiles;
+
+ QDoubleVector3D m_cameraUp;
+ QDoubleVector3D m_cameraEye;
+ QDoubleVector3D m_cameraCenter;
+ QMatrix4x4 m_projectionMatrix;
+
+ // scales up the tile geometry and the camera altitude, resulting in no visible effect
+ // other than to control the accuracy of the render by keeping the values in a sensible range
+ double m_scaleFactor;
+
+ // rounded down, positive zoom is zooming in, corresponding to reduced altitude
+ int m_intZoomLevel;
+
+ // mercatorToGrid transform
+ // the number of tiles in each direction for the whole map (earth) at the current zoom level.
+ // it is 1<<zoomLevel
+ int m_sideLength;
+ double m_mapEdgeSize;
+
+ QHash<QGeoTileSpec, QSharedPointer<QGeoTileTexture> > m_textures;
+ QVector<QGeoTileSpec> m_updatedTextures;
+
+ // tilesToGrid transform
+ int m_minTileX; // the minimum tile index, i.e. 0 to sideLength which is 1<< zoomLevel
+ int m_minTileY;
+ int m_maxTileX;
+ int m_maxTileY;
+ int m_tileXWrapsBelow; // the wrap point as a tile index
+ bool m_linearScaling;
+ bool m_dropTextures;
+
+#ifdef QT_LOCATION_DEBUG
+ double m_sideLengthPixel;
+ QGeoTiledMapRootNode *m_mapRoot = nullptr;
+#endif
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOTILEDMAPSCENE_P_P_H