summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-12-10 15:55:26 +0100
committerLiang Qi <liang.qi@qt.io>2018-12-10 15:55:26 +0100
commitf364284e2a7e52bf31eb6ed7fbaff1e7c43ebee6 (patch)
tree431c875c7b59dfe00996d8f7099d3b34ef1df3be
parent41e1fb33ab89a2b00927677cfec09ba6cf22e29d (diff)
parentb4966afc91fa82315f0ae9b11f54f52f20183e9b (diff)
downloadqtlocation-f364284e2a7e52bf31eb6ed7fbaff1e7c43ebee6.tar.gz
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts: .qmake.conf Change-Id: I00453b819d65460dabf771617e6181275461cc78
-rw-r--r--.qmake.conf5
-rw-r--r--dist/changes-5.11.332
-rw-r--r--dist/changes-5.12.052
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap.cpp16
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem.cpp13
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem_p.h1
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp10
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem_p.h11
-rw-r--r--src/location/declarativemaps/qquickgeomapgesturearea.cpp1
-rw-r--r--src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp29
-rw-r--r--src/location/maps/maps.pri3
-rw-r--r--src/location/maps/qgeocameratiles.cpp90
-rw-r--r--src/location/maps/qgeocameratiles_p.h2
-rw-r--r--src/location/maps/qgeocameratiles_p_p.h152
-rw-r--r--src/location/maps/qgeomap_p.h1
-rw-r--r--src/location/maps/qgeomap_p_p.h4
-rw-r--r--src/location/maps/qgeoprojection.cpp14
-rw-r--r--src/location/maps/qgeoprojection_p.h8
-rw-r--r--src/location/maps/qgeoserviceprovider.cpp12
-rw-r--r--src/location/maps/qgeotiledmap_p_p.h4
-rw-r--r--src/location/maps/qgeotiledmapscene.cpp154
-rw-r--r--src/location/maps/qgeotiledmapscene_p_p.h193
-rw-r--r--src/plugins/geoservices/mapbox/qplacesearchreplymapbox.cpp7
-rw-r--r--src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp10
-rw-r--r--src/plugins/position/android/src/qgeopositioninfosource_android.cpp4
-rw-r--r--src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp2
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp211
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h8
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp19
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h4
-rw-r--r--src/positioning/qgeopath.cpp2
-rw-r--r--src/positioning/qgeopath.h2
-rw-r--r--tests/auto/declarative_core/tst_categorymodel.qml5
-rw-r--r--tests/auto/qgeopath/tst_qgeopath.cpp2
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),
[&copyrightString](const QString &copy){ copyrightString = copy; });
QMetaObject::Connection copyrightImageCatcherConnection =
- connect(m_map,
+ connect(m_map.data(),
QOverload<const QImage &>::of(&QGeoMap::copyrightsChanged),
[&copyrightImage](const QImage &copy){ 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 &parameters)
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());
}