diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/location/declarativemaps/qdeclarativepolylinemapitem.cpp | 10 | ||||
-rw-r--r-- | src/location/declarativemaps/qdeclarativepolylinemapitem_p.h | 11 | ||||
-rw-r--r-- | src/location/maps/maps.pri | 3 | ||||
-rw-r--r-- | src/location/maps/qgeocameratiles.cpp | 90 | ||||
-rw-r--r-- | src/location/maps/qgeocameratiles_p.h | 2 | ||||
-rw-r--r-- | src/location/maps/qgeocameratiles_p_p.h | 152 | ||||
-rw-r--r-- | src/location/maps/qgeomap_p_p.h | 4 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection.cpp | 14 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection_p.h | 8 | ||||
-rw-r--r-- | src/location/maps/qgeotiledmap_p_p.h | 4 | ||||
-rw-r--r-- | src/location/maps/qgeotiledmapscene.cpp | 154 | ||||
-rw-r--r-- | src/location/maps/qgeotiledmapscene_p_p.h | 193 |
12 files changed, 439 insertions, 206 deletions
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 |