diff options
author | Liang Qi <liang.qi@qt.io> | 2018-12-10 15:55:26 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-12-10 15:55:26 +0100 |
commit | f364284e2a7e52bf31eb6ed7fbaff1e7c43ebee6 (patch) | |
tree | 431c875c7b59dfe00996d8f7099d3b34ef1df3be | |
parent | 41e1fb33ab89a2b00927677cfec09ba6cf22e29d (diff) | |
parent | b4966afc91fa82315f0ae9b11f54f52f20183e9b (diff) | |
download | qtlocation-f364284e2a7e52bf31eb6ed7fbaff1e7c43ebee6.tar.gz |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
.qmake.conf
Change-Id: I00453b819d65460dabf771617e6181275461cc78
34 files changed, 747 insertions, 336 deletions
diff --git a/.qmake.conf b/.qmake.conf index 834b1d2d..d4a60528 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -2,3 +2,8 @@ load(qt_build_config) CONFIG += warning_clean MODULE_VERSION = 5.13.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/dist/changes-5.11.3 b/dist/changes-5.11.3 new file mode 100644 index 00000000..9b09a0c0 --- /dev/null +++ b/dist/changes-5.11.3 @@ -0,0 +1,32 @@ +Qt 5.11.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0 through 5.11.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Qt 5.11.3 Changes * +**************************************************************************** + + QtLocation + ---------- + + - [QTBUG-69617] Fixed Qt.labs.location not linking statically on iOS. + - [QTBUG-71355] Fixed crash when calling QGeoPath::length() on empty + QGeoPath instance. + - Fixed place search matching based on category in mapbox plugin. Previously, + the search results contained places which did not have any category set. + diff --git a/dist/changes-5.12.0 b/dist/changes-5.12.0 new file mode 100644 index 00000000..4fd5b693 --- /dev/null +++ b/dist/changes-5.12.0 @@ -0,0 +1,52 @@ +Qt 5.12 introduces many new features and improvements as well as bugfixes +over the 5.11.x series. For more details, refer to the online documentation +included in this distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* QtLocation * +**************************************************************************** + + + - Added QDeclarativeGeoRoute::equals to perform deep comparisons in QML. + - MapItemView now exposes add and remove transitions, so that they can + be changed (defaults are none for add, and item fade out for remove). + - Enabled incremental updates in PlaceSearchModel, which prevents previousPage or + nextPage from resetting the model, but rather appending the new data to it. + - [QTBUG-68966] Added Map.visibleArea property. + - [QTBUG-62683][QTBUG-62397] Enabled nesting of MapItemView. This required + a behavioral change, as MapItemView is now a MapItemGroup, not anymore a + plain QObject. Due to a bug, MapItemView was previously not a Qt Quick + Item, making it possible to create it as a child of any QObject. This + has now been fixed, so if you happen to have a MapItemView in your scene + which is not a child of a Qt Quick Item, you will get an error message. + - Enabled asynchronous incremental updates of QPlaceReply. + - Changed QDeclarativeGeoMapItemBase::geoShape property from read-only into R/W. + - Added support for route legs. + - [QTBUG-70499] Fixed HERE plugin requesting the route incorrectly. + - Added ESRI place search manager to the ESRI plugin. + +**************************************************************************** +* QtPositioning * +**************************************************************************** + + - Exposed mercatorToCoord and coordToMercator to QML. + - [QTBUG-62875] QGeoPath can now be cleared directly using clearPath. + - Added QGeoPolygon::perimeter property. + - Added holes support to QGeoPolygon. Currently visualized only when using + in a MapPolygon with the MapboxGL plugin. + - [QTBUG-43435] Added Geoclue2 position plugin. + - [QTBUG-52660] QtPositioning now properly checks for authorization on iOS. + diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp index b0adc54c..63587efe 100644 --- a/src/location/declarativemaps/qdeclarativegeomap.cpp +++ b/src/location/declarativemaps/qdeclarativegeomap.cpp @@ -360,7 +360,7 @@ void QDeclarativeGeoMap::initialize() center.setLatitude(qBound(m_minimumViewportLatitude, center.latitude(), m_maximumViewportLatitude)); cameraData.setCenter(center); - connect(m_map, &QGeoMap::cameraDataChanged, + connect(m_map.data(), &QGeoMap::cameraDataChanged, this, &QDeclarativeGeoMap::onCameraDataChanged); m_map->setCameraData(cameraData); @@ -371,7 +371,7 @@ void QDeclarativeGeoMap::initialize() if (visibleAreaHasChanged) emit visibleAreaChanged(); - connect(m_map, &QGeoMap::visibleAreaChanged, this, &QDeclarativeGeoMap::visibleAreaChanged); + connect(m_map.data(), &QGeoMap::visibleAreaChanged, this, &QDeclarativeGeoMap::visibleAreaChanged); emit mapReadyChanged(true); @@ -657,11 +657,11 @@ void QDeclarativeGeoMap::mappingManagerInitialized() QImage copyrightImage; if (!m_initialized && width() > 0 && height() > 0) { QMetaObject::Connection copyrightStringCatcherConnection = - connect(m_map, + connect(m_map.data(), QOverload<const QString &>::of(&QGeoMap::copyrightsChanged), [©rightString](const QString ©){ copyrightString = copy; }); QMetaObject::Connection copyrightImageCatcherConnection = - connect(m_map, + connect(m_map.data(), QOverload<const QImage &>::of(&QGeoMap::copyrightsChanged), [©rightImage](const QImage ©){ copyrightImage = copy; }); m_map->setViewportSize(QSize(width(), height())); @@ -672,9 +672,9 @@ void QDeclarativeGeoMap::mappingManagerInitialized() /* COPYRIGHT SIGNALS REWIRING */ - connect(m_map, SIGNAL(copyrightsChanged(QImage)), + connect(m_map.data(), SIGNAL(copyrightsChanged(QImage)), this, SIGNAL(copyrightsChanged(QImage))); - connect(m_map, SIGNAL(copyrightsChanged(QString)), + connect(m_map.data(), SIGNAL(copyrightsChanged(QString)), this, SIGNAL(copyrightsChanged(QString))); if (!copyrightString.isEmpty()) emit m_map->copyrightsChanged(copyrightString); @@ -682,8 +682,8 @@ void QDeclarativeGeoMap::mappingManagerInitialized() emit m_map->copyrightsChanged(copyrightImage); - connect(m_map, &QGeoMap::sgNodeChanged, this, &QQuickItem::update); - connect(m_map, &QGeoMap::cameraCapabilitiesChanged, this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged); + connect(m_map.data(), &QGeoMap::sgNodeChanged, this, &QQuickItem::update); + connect(m_map.data(), &QGeoMap::cameraCapabilitiesChanged, this, &QDeclarativeGeoMap::onCameraCapabilitiesChanged); // This prefetches a buffer around the map m_map->prefetchData(); diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp index b692bc76..f4cdc6bf 100644 --- a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp +++ b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp @@ -320,18 +320,9 @@ QDeclarativePolygonMapItem::QDeclarativePolygonMapItem(QQuickItem *parent) { setFlag(ItemHasContents, true); QObject::connect(&border_, SIGNAL(colorChanged(QColor)), - this, SLOT(handleBorderUpdated())); + this, SLOT(markSourceDirtyAndUpdate())); QObject::connect(&border_, SIGNAL(widthChanged(qreal)), - this, SLOT(handleBorderUpdated())); -} - -/*! - \internal -*/ -void QDeclarativePolygonMapItem::handleBorderUpdated() -{ - borderGeometry_.markSourceDirty(); - polishAndUpdate(); + this, SLOT(markSourceDirtyAndUpdate())); } QDeclarativePolygonMapItem::~QDeclarativePolygonMapItem() diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h index a68b6315..87d72307 100644 --- a/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h +++ b/src/location/declarativemaps/qdeclarativepolygonmapitem_p.h @@ -120,7 +120,6 @@ protected: protected Q_SLOTS: void markSourceDirtyAndUpdate(); - void handleBorderUpdated(); virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) override; private: 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/declarativemaps/qquickgeomapgesturearea.cpp b/src/location/declarativemaps/qquickgeomapgesturearea.cpp index b15dbc4d..88a766f5 100644 --- a/src/location/declarativemaps/qquickgeomapgesturearea.cpp +++ b/src/location/declarativemaps/qquickgeomapgesturearea.cpp @@ -1087,6 +1087,7 @@ void QQuickGeoMapGestureArea::update() m_allPoints << m_touchPoints; if (m_allPoints.isEmpty() && !m_mousePoint.isNull()) m_allPoints << *m_mousePoint.data(); + std::sort(m_allPoints.begin(), m_allPoints.end(), [](const QTouchEvent::TouchPoint &tp1, const QTouchEvent::TouchPoint &tp2) { return tp1.id() < tp2.id(); }); touchPointStateMachine(); diff --git a/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp b/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp index b7c6e319..3bc45c4f 100644 --- a/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp +++ b/src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp @@ -39,6 +39,7 @@ #include "qdeclarativeplaceicon_p.h" #include "qgeoserviceprovider.h" #include "error_messages_p.h" +#include <QtCore/private/qobject_p.h> #include <QCoreApplication> #include <QtQml/QQmlInfo> @@ -121,6 +122,15 @@ QT_BEGIN_NAMESPACE */ /*! + \qmlmethod void QtLocation::CategoryModel::update() + \internal + + Updates the model. + + \note The CategoryModel auto updates automatically when needed. Calling this method explicitly is normally not necessary. +*/ + +/*! \internal \enum QDeclarativeSupportedCategoriesModel::Roles */ @@ -143,6 +153,8 @@ QDeclarativeSupportedCategoriesModel::~QDeclarativeSupportedCategoriesModel() void QDeclarativeSupportedCategoriesModel::componentComplete() { m_complete = true; + if (m_plugin) // do not try to load or change status when trying to update in componentComplete() if the plugin hasn't been set yet even once. + update(); } /*! @@ -255,6 +267,7 @@ void QDeclarativeSupportedCategoriesModel::setPlugin(QDeclarativeGeoServiceProvi //disconnect the manager of the old plugin if we have one if (m_plugin) { + disconnect(m_plugin, nullptr, this, nullptr); QGeoServiceProvider *serviceProvider = m_plugin->sharedGeoServiceProvider(); if (serviceProvider) { QPlaceManager *placeManager = serviceProvider->placeManager(); @@ -273,14 +286,17 @@ void QDeclarativeSupportedCategoriesModel::setPlugin(QDeclarativeGeoServiceProvi m_plugin = plugin; - // handle plugin name changes -> update categories + // handle plugin attached changes -> update categories if (m_plugin) { - connect(m_plugin, SIGNAL(nameChanged(QString)), this, SLOT(connectNotificationSignals())); - connect(m_plugin, SIGNAL(nameChanged(QString)), this, SLOT(update())); + if (m_plugin->isAttached()) { + connectNotificationSignals(); + update(); + } else { + connect(m_plugin, &QDeclarativeGeoServiceProvider::attached, this, &QDeclarativeSupportedCategoriesModel::update); + connect(m_plugin, &QDeclarativeGeoServiceProvider::attached, this, &QDeclarativeSupportedCategoriesModel::connectNotificationSignals); + } } - connectNotificationSignals(); - if (m_complete) emit pluginChanged(); } @@ -499,6 +515,9 @@ void QDeclarativeSupportedCategoriesModel::connectNotificationSignals() */ void QDeclarativeSupportedCategoriesModel::update() { + if (!m_complete) + return; + if (m_response) return; 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.h b/src/location/maps/qgeomap_p.h index f19f847a..874b300f 100644 --- a/src/location/maps/qgeomap_p.h +++ b/src/location/maps/qgeomap_p.h @@ -177,7 +177,6 @@ Q_SIGNALS: private: Q_DISABLE_COPY(QGeoMap) friend class QDeclarativeGeoMap; //updateSceneGraph - friend class QGeoMapPrivate; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGeoMap::ItemTypes) 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/qgeoserviceprovider.cpp b/src/location/maps/qgeoserviceprovider.cpp index c6b9d742..d25c379a 100644 --- a/src/location/maps/qgeoserviceprovider.cpp +++ b/src/location/maps/qgeoserviceprovider.cpp @@ -362,7 +362,7 @@ template <> QNavigationManagerEngine *createEngine<QNavigationManagerEngine>(QGe { if (!d_ptr->factoryV2) return nullptr; - return d_ptr->factoryV2->createNavigationManagerEngine(d_ptr->cleanedParameterMap, &(d_ptr->placeError), &(d_ptr->placeErrorString)); + return d_ptr->factoryV2->createNavigationManagerEngine(d_ptr->cleanedParameterMap, &(d_ptr->navigationError), &(d_ptr->navigationErrorString)); } /* Template for generating the code for each of the geocodingManager(), @@ -381,11 +381,15 @@ Manager *QGeoServiceProviderPrivate::manager(QGeoServiceProvider::Error *_error, this->loadPlugin(this->parameterMap); } - if (!this->factory || error != QGeoServiceProvider::NoError) + if (!this->factory) { + error = this->error; + errorString = this->errorString; return 0; + } if (!manager) { - Engine *engine = createEngine<Engine>(this); + Engine *engine = createEngine<Engine>(this); // this sets the specific error variables directly, + // from now on the local error, errorString refs should be set. if (engine) { engine->setManagerName( @@ -753,7 +757,7 @@ void QGeoServiceProviderPrivate::loadPlugin(const QVariantMap ¶meters) QObject *instance = loader()->instance(idx); if (!instance) { error = QGeoServiceProvider::LoaderError; - errorString = QLatin1String("loader()->instance(idx) failed to return an instance"); + errorString = QLatin1String("loader()->instance(idx) failed to return an instance. Set the environment variable QT_DEBUG_PLUGINS to see more details."); return; } factoryV3 = qobject_cast<QGeoServiceProviderFactoryV3 *>(instance); 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 diff --git a/src/plugins/geoservices/mapbox/qplacesearchreplymapbox.cpp b/src/plugins/geoservices/mapbox/qplacesearchreplymapbox.cpp index a79af1cb..b2f2f043 100644 --- a/src/plugins/geoservices/mapbox/qplacesearchreplymapbox.cpp +++ b/src/plugins/geoservices/mapbox/qplacesearchreplymapbox.cpp @@ -188,19 +188,18 @@ void QPlaceSearchReplyMapbox::onReplyFinished() if (!categories.isEmpty()) { const QList<QPlaceCategory> placeCategories = placeResult.place().categories(); + bool categoryMatch = false; if (!placeCategories.isEmpty()) { - bool categoryMatch = false; for (const QPlaceCategory &placeCategory : placeCategories) { if (categories.contains(placeCategory)) { categoryMatch = true; break; } } - if (!categoryMatch) - continue; } + if (!categoryMatch) + continue; } - placeResult.setDistance(searchCenter.distanceTo(placeResult.place().location().coordinate())); results.append(placeResult); } diff --git a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp index ab575463..5094b72e 100644 --- a/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp +++ b/src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp @@ -52,6 +52,7 @@ #include <QtCore/QJsonArray> #include <QtCore/QJsonDocument> #include <QtCore/QJsonObject> +#include <QtCore/QRegularExpression> #include <QtCore/QStandardPaths> #include <QtCore/QUrlQuery> #include <QtNetwork/QNetworkProxy> @@ -690,13 +691,14 @@ QPlaceIcon QPlaceManagerEngineNokiaV2::icon(const QString &remotePath, QPlaceIcon icon; QVariantMap params; - QRegExp rx("(.*)(/icons/categories/.*)"); + QRegularExpression rx("(.*)(/icons/categories/.*)"); + QRegularExpressionMatch match = rx.match(remotePath); QString iconPrefix; QString nokiaIcon; - if (rx.indexIn(remotePath) != -1 && !rx.cap(1).isEmpty() && !rx.cap(2).isEmpty()) { - iconPrefix = rx.cap(1); - nokiaIcon = rx.cap(2); + if (match.hasMatch() && !match.capturedRef(1).isEmpty() && !match.capturedRef(2).isEmpty()) { + iconPrefix = match.captured(1); + nokiaIcon = match.captured(2); if (QFile::exists(m_localDataPath + nokiaIcon)) iconPrefix = QString::fromLatin1("file://") + m_localDataPath; diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp index 7b4706d8..59b8beab 100644 --- a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp +++ b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp @@ -223,7 +223,7 @@ void QGeoPositionInfoSourceAndroid::requestTimeout() const QGeoPositionInfo info = queuedSingleUpdates[i]; //anything newer by 20s is always better - const int timeDelta = best.timestamp().secsTo(info.timestamp()); + const qint64 timeDelta = best.timestamp().secsTo(info.timestamp()); if (abs(timeDelta) > 20) { if (timeDelta > 0) best = info; @@ -232,7 +232,7 @@ void QGeoPositionInfoSourceAndroid::requestTimeout() //compare accuracy if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) && - info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) + best.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) { best = info.attribute(QGeoPositionInfo::HorizontalAccuracy) < best.attribute(QGeoPositionInfo::HorizontalAccuracy) ? info : best; diff --git a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp index cd514d30..10484e3b 100644 --- a/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp +++ b/src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp @@ -264,7 +264,7 @@ void QGeoPositionInfoSourceGeoclue2::createClient() setError(AccessError); delete m_client; } else { - connect(m_client, &OrgFreedesktopGeoClue2ClientInterface::LocationUpdated, + connect(m_client.data(), &OrgFreedesktopGeoClue2ClientInterface::LocationUpdated, this, &QGeoPositionInfoSourceGeoclue2::handleNewLocation); if (configureClient()) diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp index 046d862e..139a6b3d 100644 --- a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp +++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp @@ -36,11 +36,12 @@ #include "qgeopositioninfosource_winrt_p.h" -#include <QCoreApplication> -#include <QMutex> -#include <qfunctions_winrt.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qfunctions_winrt.h> +#include <QtCore/qloggingcategory.h> +#include <QtCore/qmutex.h> #ifdef Q_OS_WINRT -#include <private/qeventdispatcher_winrt_p.h> +#include <QtCore/private/qeventdispatcher_winrt_p.h> #endif #include <functional> @@ -56,10 +57,11 @@ using namespace ABI::Windows::Foundation; using namespace ABI::Windows::Foundation::Collections; typedef ITypedEventHandler<Geolocator *, PositionChangedEventArgs *> GeoLocatorPositionHandler; -typedef ITypedEventHandler<Geolocator *, StatusChangedEventArgs *> GeoLocatorStatusHandler; typedef IAsyncOperationCompletedHandler<Geoposition*> PositionHandler; typedef IAsyncOperationCompletedHandler<GeolocationAccessStatus> AccessHandler; +Q_DECLARE_LOGGING_CATEGORY(lcPositioningWinRT) + QT_BEGIN_NAMESPACE #ifndef Q_OS_WINRT @@ -70,7 +72,36 @@ HRESULT runOnXamlThread(const std::function<HRESULT ()> &delegate, bool waitForR return delegate(); } } -#endif + +static inline HRESULT await(const ComPtr<IAsyncOperation<GeolocationAccessStatus>> &asyncOp, + GeolocationAccessStatus *result) +{ + ComPtr<IAsyncInfo> asyncInfo; + HRESULT hr = asyncOp.As(&asyncInfo); + if (FAILED(hr)) + return hr; + + AsyncStatus status; + while (SUCCEEDED(hr = asyncInfo->get_Status(&status)) && status == AsyncStatus::Started) + QThread::yieldCurrentThread(); + + if (FAILED(hr) || status != AsyncStatus::Completed) { + HRESULT ec; + hr = asyncInfo->get_ErrorCode(&ec); + if (FAILED(hr)) + return hr; + hr = asyncInfo->Close(); + if (FAILED(hr)) + return hr; + return ec; + } + + if (FAILED(hr)) + return hr; + + return asyncOp->GetResults(result); +} +#endif // !Q_OS_WINRT class QGeoPositionInfoSourceWinRTPrivate { public: @@ -83,13 +114,37 @@ public: EventRegistrationToken positionToken; QMutex mutex; bool updatesOngoing; + int minimumUpdateInterval; + + PositionStatus nativeStatus() const; }; +PositionStatus QGeoPositionInfoSourceWinRTPrivate::nativeStatus() const +{ +#ifdef Q_OS_WINRT + qCDebug(lcPositioningWinRT) << __FUNCTION__; + + PositionStatus status; + HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, &status]() { + return locator->get_LocationStatus(&status); + }); + if (FAILED(hr)) { + qErrnoWarning(hr, "Could not query status"); + return PositionStatus_NotAvailable; + } + return status; +#else + return PositionStatus_Ready; +#endif +} + QGeoPositionInfoSourceWinRT::QGeoPositionInfoSourceWinRT(QObject *parent) : QGeoPositionInfoSource(parent) , d_ptr(new QGeoPositionInfoSourceWinRTPrivate) { + qCDebug(lcPositioningWinRT) << __FUNCTION__; + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); Q_D(QGeoPositionInfoSourceWinRT); d->positionError = QGeoPositionInfoSource::NoError; d->updatesOngoing = false; @@ -97,10 +152,13 @@ QGeoPositionInfoSourceWinRT::QGeoPositionInfoSourceWinRT(QObject *parent) QGeoPositionInfoSourceWinRT::~QGeoPositionInfoSourceWinRT() { + qCDebug(lcPositioningWinRT) << __FUNCTION__; + CoUninitialize(); } int QGeoPositionInfoSourceWinRT::init() { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); if (!requestAccess()) { qWarning ("Location access failed."); @@ -111,13 +169,11 @@ int QGeoPositionInfoSourceWinRT::init() &d->locator); RETURN_HR_IF_FAILED("Could not initialize native location services."); - hr = d->locator->add_StatusChanged(Callback<GeoLocatorStatusHandler>(this, - &QGeoPositionInfoSourceWinRT::onStatusChanged).Get(), - &d->statusToken); - RETURN_HR_IF_FAILED("Could not add status callback."); - - hr = d->locator->put_ReportInterval(1000); - RETURN_HR_IF_FAILED("Could not initialize report interval."); + UINT32 interval; + hr = d->locator->get_ReportInterval(&interval); + RETURN_HR_IF_FAILED("Could not retrieve report interval."); + d->minimumUpdateInterval = static_cast<int>(interval); + setUpdateInterval(d->minimumUpdateInterval); return hr; }); @@ -137,7 +193,6 @@ int QGeoPositionInfoSourceWinRT::init() d->positionToken.value = 0; d->periodicTimer.setSingleShot(true); - d->periodicTimer.setInterval(minimumUpdateInterval()); connect(&d->periodicTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::virtualPositionUpdate); d->singleUpdateTimer.setSingleShot(true); @@ -151,6 +206,7 @@ int QGeoPositionInfoSourceWinRT::init() QGeoPositionInfo QGeoPositionInfoSourceWinRT::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(const QGeoPositionInfoSourceWinRT); Q_UNUSED(fromSatellitePositioningMethodsOnly) return d->lastPosition; @@ -160,13 +216,8 @@ QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinRT::supporte { Q_D(const QGeoPositionInfoSourceWinRT); - PositionStatus status; - HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, &status]() { - HRESULT hr = d->locator->get_LocationStatus(&status); - return hr; - }); - if (FAILED(hr)) - return QGeoPositionInfoSource::NoPositioningMethods; + PositionStatus status = d->nativeStatus(); + qCDebug(lcPositioningWinRT) << __FUNCTION__ << status; switch (status) { case PositionStatus::PositionStatus_NoData: @@ -180,6 +231,7 @@ QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinRT::supporte void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods) { + qCDebug(lcPositioningWinRT) << __FUNCTION__ << methods; Q_D(QGeoPositionInfoSourceWinRT); PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); @@ -187,7 +239,7 @@ void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInf if (previousPreferredPositioningMethods == preferredPositioningMethods()) return; - bool needsRestart = d->positionToken.value != 0; + const bool needsRestart = d->positionToken.value != 0; if (needsRestart) stopHandler(); @@ -207,19 +259,20 @@ void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInf void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) { + qCDebug(lcPositioningWinRT) << __FUNCTION__ << msec; Q_D(QGeoPositionInfoSourceWinRT); - // Windows Phone 8.1 and Windows 10 do not support 0 interval -#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) - if (msec == 0) - msec = minimumUpdateInterval(); -#endif - - // If msec is 0 we send updates as data becomes available, otherwise we force msec to be equal - // to or larger than the minimum update interval. + // minimumUpdateInterval is initialized to the lowest possible update interval in init(). + // Passing 0 will cause an error on Windows 10. + // See https://docs.microsoft.com/en-us/uwp/api/windows.devices.geolocation.geolocator.reportinterval if (msec != 0 && msec < minimumUpdateInterval()) msec = minimumUpdateInterval(); - HRESULT hr = d->locator->put_ReportInterval(msec); + const bool needsRestart = d->positionToken.value != 0; + + if (needsRestart) + stopHandler(); + + HRESULT hr = d->locator->put_ReportInterval(static_cast<UINT32>(msec)); if (FAILED(hr)) { setError(QGeoPositionInfoSource::UnknownSourceError); qErrnoWarning(hr, "Failed to set update interval"); @@ -229,17 +282,20 @@ void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec) d->periodicTimer.setInterval(qMax(msec, minimumUpdateInterval())); QGeoPositionInfoSource::setUpdateInterval(msec); + + if (needsRestart) + startHandler(); } int QGeoPositionInfoSourceWinRT::minimumUpdateInterval() const { - // We use one second to reduce potential timer events - // in case the platform itself stops reporting - return 1000; + Q_D(const QGeoPositionInfoSourceWinRT); + return d->minimumUpdateInterval; } void QGeoPositionInfoSourceWinRT::startUpdates() { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); if (d->updatesOngoing) @@ -253,6 +309,7 @@ void QGeoPositionInfoSourceWinRT::startUpdates() void QGeoPositionInfoSourceWinRT::stopUpdates() { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); stopHandler(); @@ -262,6 +319,7 @@ void QGeoPositionInfoSourceWinRT::stopUpdates() bool QGeoPositionInfoSourceWinRT::startHandler() { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); // Check if already attached @@ -301,6 +359,7 @@ bool QGeoPositionInfoSourceWinRT::startHandler() void QGeoPositionInfoSourceWinRT::stopHandler() { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); if (!d->positionToken.value) @@ -314,6 +373,7 @@ void QGeoPositionInfoSourceWinRT::stopHandler() void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout) { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); if (timeout != 0 && timeout < minimumUpdateInterval()) { @@ -330,6 +390,7 @@ void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout) void QGeoPositionInfoSourceWinRT::virtualPositionUpdate() { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_D(QGeoPositionInfoSourceWinRT); QMutexLocker locker(&d->mutex); @@ -367,6 +428,7 @@ void QGeoPositionInfoSourceWinRT::singleUpdateTimeOut() void QGeoPositionInfoSourceWinRT::updateSynchronized(QGeoPositionInfo currentInfo) { + qCDebug(lcPositioningWinRT) << __FUNCTION__ << currentInfo; Q_D(QGeoPositionInfoSourceWinRT); QMutexLocker locker(&d->mutex); @@ -388,11 +450,13 @@ void QGeoPositionInfoSourceWinRT::updateSynchronized(QGeoPositionInfo currentInf QGeoPositionInfoSource::Error QGeoPositionInfoSourceWinRT::error() const { Q_D(const QGeoPositionInfoSourceWinRT); + qCDebug(lcPositioningWinRT) << __FUNCTION__ << d->positionError; return d->positionError; } void QGeoPositionInfoSourceWinRT::setError(QGeoPositionInfoSource::Error positionError) { + qCDebug(lcPositioningWinRT) << __FUNCTION__ << positionError; Q_D(QGeoPositionInfoSourceWinRT); if (positionError == d->positionError) @@ -404,14 +468,9 @@ void QGeoPositionInfoSourceWinRT::setError(QGeoPositionInfoSource::Error positio bool QGeoPositionInfoSourceWinRT::checkNativeState() { Q_D(QGeoPositionInfoSourceWinRT); + qCDebug(lcPositioningWinRT) << __FUNCTION__; - PositionStatus status; - HRESULT hr = d->locator->get_LocationStatus(&status); - if (FAILED(hr)) { - setError(QGeoPositionInfoSource::UnknownSourceError); - qErrnoWarning(hr, "Could not query status"); - return false; - } + PositionStatus status = d->nativeStatus(); bool result = false; switch (status) { @@ -432,41 +491,53 @@ bool QGeoPositionInfoSourceWinRT::checkNativeState() HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args) { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_UNUSED(locator); HRESULT hr; - ComPtr<IGeoposition> pos; - hr = args->get_Position(&pos); + ComPtr<IGeoposition> position; + hr = args->get_Position(&position); RETURN_HR_IF_FAILED("Could not access position object."); QGeoPositionInfo currentInfo; ComPtr<IGeocoordinate> coord; - hr = pos->get_Coordinate(&coord); + hr = position->get_Coordinate(&coord); if (FAILED(hr)) qErrnoWarning(hr, "Could not access coordinate"); - DOUBLE lat; - hr = coord->get_Latitude(&lat); + ComPtr<IGeocoordinateWithPoint> pointCoordinate; + hr = coord.As(&pointCoordinate); if (FAILED(hr)) - qErrnoWarning(hr, "Could not access latitude"); + qErrnoWarning(hr, "Could not cast coordinate."); - DOUBLE lon; - hr = coord->get_Longitude(&lon); + ComPtr<IGeopoint> point; + hr = pointCoordinate->get_Point(&point); if (FAILED(hr)) - qErrnoWarning(hr, "Could not access longitude"); - - // Depending on data source altitude can - // be identified or not - IReference<double> *alt; - hr = coord->get_Altitude(&alt); - if (SUCCEEDED(hr) && alt) { - double altd; - hr = alt->get_Value(&altd); - currentInfo.setCoordinate(QGeoCoordinate(lat, lon, altd)); - } else { - currentInfo.setCoordinate(QGeoCoordinate(lat, lon)); + qErrnoWarning(hr, "Could not obtain coordinate's point."); + + BasicGeoposition pos; + hr = point->get_Position(&pos); + if (FAILED(hr)) + qErrnoWarning(hr, "Could not obtain point's position."); + + DOUBLE lat = pos.Latitude; + DOUBLE lon = pos.Longitude; + DOUBLE alt = pos.Altitude; + + bool altitudeAvailable = false; + ComPtr<IGeoshape> shape; + hr = point.As(&shape); + if (SUCCEEDED(hr) && shape) { + AltitudeReferenceSystem altitudeSystem; + hr = shape->get_AltitudeReferenceSystem(&altitudeSystem); + if (SUCCEEDED(hr) && altitudeSystem == AltitudeReferenceSystem_Geoid) + altitudeAvailable = true; } + if (altitudeAvailable) + currentInfo.setCoordinate(QGeoCoordinate(lat, lon, alt)); + else + currentInfo.setCoordinate(QGeoCoordinate(lat, lon)); DOUBLE accuracy; hr = coord->get_Accuracy(&accuracy); @@ -477,7 +548,7 @@ HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPo hr = coord->get_AltitudeAccuracy(&altAccuracy); if (SUCCEEDED(hr) && altAccuracy) { double value; - hr = alt->get_Value(&value); + hr = altAccuracy->get_Value(&value); currentInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy, value); } @@ -525,16 +596,9 @@ HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPo return S_OK; } -HRESULT QGeoPositionInfoSourceWinRT::onStatusChanged(IGeolocator*, IStatusChangedEventArgs *args) -{ - PositionStatus st; - args->get_Status(&st); - return S_OK; -} - bool QGeoPositionInfoSourceWinRT::requestAccess() const { -#ifdef Q_OS_WINRT + qCDebug(lcPositioningWinRT) << __FUNCTION__; static GeolocationAccessStatus accessStatus = GeolocationAccessStatus_Unspecified; static ComPtr<IGeolocatorStatics> statics; @@ -557,11 +621,12 @@ bool QGeoPositionInfoSourceWinRT::requestAccess() const Q_ASSERT_SUCCEEDED(hr); // We cannot wait inside the XamlThread as that would deadlock +#ifdef Q_OS_WINRT QWinRTFunctions::await(op, &accessStatus); +#else + await(op, &accessStatus); +#endif return accessStatus == GeolocationAccessStatus_Allowed; -#else // Q_OS_WINRT - return true; -#endif // Q_OS_WINRT } QT_END_NAMESPACE diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h index 9f3a1c7f..4319ccae 100644 --- a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h +++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h @@ -51,7 +51,7 @@ #include "qgeopositioninfosource.h" #include "qgeopositioninfo.h" -#include <QTimer> +#include <QtCore/qtimer.h> #include <EventToken.h> #include <wrl.h> @@ -62,7 +62,6 @@ namespace ABI { namespace Geolocation{ struct IGeolocator; struct IPositionChangedEventArgs; - struct IStatusChangedEventArgs; } } } @@ -76,7 +75,7 @@ class QGeoPositionInfoSourceWinRT : public QGeoPositionInfoSource { Q_OBJECT public: - QGeoPositionInfoSourceWinRT(QObject *parent = 0); + QGeoPositionInfoSourceWinRT(QObject *parent = nullptr); ~QGeoPositionInfoSourceWinRT(); int init(); @@ -92,9 +91,6 @@ public: HRESULT onPositionChanged(ABI::Windows::Devices::Geolocation::IGeolocator *locator, ABI::Windows::Devices::Geolocation::IPositionChangedEventArgs *args); - HRESULT onStatusChanged(ABI::Windows::Devices::Geolocation::IGeolocator*, - ABI::Windows::Devices::Geolocation::IStatusChangedEventArgs *args); - bool requestAccess() const; Q_SIGNALS: void nativePositionUpdate(const QGeoPositionInfo); diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp index e58744a0..b1ec6fb3 100644 --- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp +++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp @@ -37,24 +37,37 @@ #include "qgeopositioninfosourcefactory_winrt.h" #include "qgeopositioninfosource_winrt_p.h" +#include <QtCore/qloggingcategory.h> + +Q_LOGGING_CATEGORY(lcPositioningWinRT, "qt.positioning.winrt") + +QT_BEGIN_NAMESPACE + QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinRT::positionInfoSource(QObject *parent) { + qCDebug(lcPositioningWinRT) << __FUNCTION__; QGeoPositionInfoSourceWinRT *src = new QGeoPositionInfoSourceWinRT(parent); if (src->init() < 0) { + qCDebug(lcPositioningWinRT) << __FUNCTION__ << "Source initialization failed."; delete src; - src = 0; + return nullptr; } + qCDebug(lcPositioningWinRT) << __FUNCTION__ << "Created position info source."; return src; } QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryWinRT::satelliteInfoSource(QObject *parent) { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_UNUSED(parent); - return 0; + return nullptr; } QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryWinRT::areaMonitor(QObject *parent) { + qCDebug(lcPositioningWinRT) << __FUNCTION__; Q_UNUSED(parent); - return 0; + return nullptr; } + +QT_END_NAMESPACE diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h index 46cd3853..d09ddb64 100644 --- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h +++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h @@ -37,8 +37,8 @@ #ifndef QGEOPOSITIONINFOSOURCEFACTORY_WINRT_H #define QGEOPOSITIONINFOSOURCEFACTORY_WINRT_H -#include <QObject> -#include <QGeoPositionInfoSourceFactory> +#include <QtCore/qobject.h> +#include <QtPositioning/qgeopositioninfosourcefactory.h> QT_BEGIN_NAMESPACE diff --git a/src/positioning/qgeopath.cpp b/src/positioning/qgeopath.cpp index beb43692..0c3d0c1c 100644 --- a/src/positioning/qgeopath.cpp +++ b/src/positioning/qgeopath.cpp @@ -204,7 +204,7 @@ const QList<QGeoCoordinate> &QGeoPath::path() const \since 5.12 */ -void QGeoPath::clear() +void QGeoPath::clearPath() { Q_D(QGeoPath); d->clearPath(); diff --git a/src/positioning/qgeopath.h b/src/positioning/qgeopath.h index cda6f277..e4af2add 100644 --- a/src/positioning/qgeopath.h +++ b/src/positioning/qgeopath.h @@ -72,7 +72,7 @@ public: void setPath(const QList<QGeoCoordinate> &path); const QList<QGeoCoordinate> &path() const; - void clear(); + void clearPath(); void setVariantPath(const QVariantList &path); QVariantList variantPath() const; diff --git a/tests/auto/declarative_core/tst_categorymodel.qml b/tests/auto/declarative_core/tst_categorymodel.qml index 0b6e50a3..86d0fd4c 100644 --- a/tests/auto/declarative_core/tst_categorymodel.qml +++ b/tests/auto/declarative_core/tst_categorymodel.qml @@ -221,7 +221,7 @@ TestCase { //iteration. //try updating with an uninitialized plugin instance. - testModel.plugin = uninitializedPlugin; + testModel.plugin = uninitializedPlugin; // uninitialized does not trigger update on setPlugin testModel.update(); tryCompare(statusChangedSpy, "count", 2); compare(testModel.status, CategoryModel.Error); @@ -229,8 +229,9 @@ TestCase { //try searching with plugin a instance //that has been provided a non-existent name + tryCompare(statusChangedSpy, "count", 0); testModel.plugin = nonExistantPlugin; - testModel.update(); +// testModel.update(); //QTBUG-70254 tryCompare(statusChangedSpy, "count", 2); compare(testModel.status, CategoryModel.Error); } diff --git a/tests/auto/qgeopath/tst_qgeopath.cpp b/tests/auto/qgeopath/tst_qgeopath.cpp index 213af0ad..47badf73 100644 --- a/tests/auto/qgeopath/tst_qgeopath.cpp +++ b/tests/auto/qgeopath/tst_qgeopath.cpp @@ -182,7 +182,7 @@ void tst_QGeoPath::path() QCOMPARE(p.path().contains(c), true); } - p.clear(); + p.clearPath(); QCOMPARE(p.path().size(), 0); QVERIFY(p.boundingGeoRectangle().isEmpty()); } |