summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf5
-rw-r--r--config.tests/winrt/winrt.pro2
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap.cpp16
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitemview.cpp85
-rw-r--r--src/location/declarativemaps/qdeclarativegeomapitemview_p.h12
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp147
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem_p.h11
-rw-r--r--src/location/declarativeplaces/qdeclarativesupportedcategoriesmodel.cpp29
-rw-r--r--src/location/doc/src/plugins/mapboxgl.qdoc5
-rw-r--r--src/location/doc/src/qtlocation-qml.qdoc138
-rw-r--r--src/location/doc/src/qtlocation.qdoc8
-rw-r--r--src/location/labs/qdeclarativenavigator.cpp7
-rw-r--r--src/location/labs/qdeclarativenavigator_p_p.h2
-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.cpp17
-rw-r--r--src/location/maps/qgeoprojection_p.h8
-rw-r--r--src/location/maps/qgeoserviceprovider.cpp21
-rw-r--r--src/location/maps/qgeoserviceprovider.h3
-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/location/maps/qnavigationmanagerengine.cpp1
-rw-r--r--src/location/maps/qnavigationmanagerengine_p.h1
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp9
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h2
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp65
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h1
-rw-r--r--src/plugins/geoservices/nokia/qplacemanagerengine_nokiav2.cpp10
-rw-r--r--src/plugins/position/geoclue2/qgeopositioninfosource_geoclue2.cpp2
-rw-r--r--src/plugins/position/position.pro4
-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/doc/src/qtpositioning-qml.qdoc54
-rw-r--r--tests/auto/declarative_core/tst_categorymodel.qml5
41 files changed, 1025 insertions, 490 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 3566a973..0815e3b5 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -2,3 +2,8 @@ load(qt_build_config)
CONFIG += warning_clean
MODULE_VERSION = 5.12.0
+
+# Adds a way to debug location. The define is needed for multiple subprojects as they
+# include the essential headers.
+# Alternatively, the define can be passed directly to qmake
+# DEFINES+=QT_LOCATION_DEBUG
diff --git a/config.tests/winrt/winrt.pro b/config.tests/winrt/winrt.pro
index 1476abc9..06c2249e 100644
--- a/config.tests/winrt/winrt.pro
+++ b/config.tests/winrt/winrt.pro
@@ -1,5 +1,5 @@
SOURCES += main.cpp
-win32-msvc201* {
+msvc {
LIBS += runtimeobject.lib
CONFIG += console
}
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/qdeclarativegeomapitemview.cpp b/src/location/declarativemaps/qdeclarativegeomapitemview.cpp
index 4461d2e0..41ab3453 100644
--- a/src/location/declarativemaps/qdeclarativegeomapitemview.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomapitemview.cpp
@@ -135,8 +135,8 @@ void QDeclarativeGeoMapItemView::classBegin()
connect(m_delegateModel, &QQmlInstanceModel::modelUpdated, this, &QDeclarativeGeoMapItemView::modelUpdated);
connect(m_delegateModel, &QQmlInstanceModel::createdItem, this, &QDeclarativeGeoMapItemView::createdItem);
- connect(m_delegateModel, &QQmlInstanceModel::destroyingItem, this, &QDeclarativeGeoMapItemView::destroyingItem);
- connect(m_delegateModel, &QQmlInstanceModel::initItem, this, &QDeclarativeGeoMapItemView::initItem);
+// connect(m_delegateModel, &QQmlInstanceModel::destroyingItem, this, &QDeclarativeGeoMapItemView::destroyingItem);
+// connect(m_delegateModel, &QQmlInstanceModel::initItem, this, &QDeclarativeGeoMapItemView::initItem);
}
void QDeclarativeGeoMapItemView::destroyingItem(QObject */*object*/)
@@ -156,16 +156,21 @@ void QDeclarativeGeoMapItemView::createdItem(int index, QObject */*object*/)
// createdItem is emitted on asynchronous creation. In which case, object has to be invoked again.
// See QQmlDelegateModel::object for further info.
- if (m_incubationMode == QQmlIncubator::Synchronous) {
- qWarning() << "createdItem invoked on Synchronous incubation";
+ // DelegateModel apparently triggers this method in any case, that is:
+ // 1. Synchronous incubation, delegate instantiated on the first object() call (during the object() call!)
+ // 2. Async incubation, delegate not instantiated on the first object() call
+ // 3. Async incubation, delegate present in the cache, and returned on the first object() call.
+ // createdItem also called during the object() call.
+ if (m_creatingObject) {
+ // Falling into case 1. or 3. Returning early to prevent double referencing the delegate instance.
return;
}
QQuickItem *item = qobject_cast<QQuickItem *>(m_delegateModel->object(index, m_incubationMode));
if (item)
- addDelegateToMap(item, index);
+ addDelegateToMap(item, index, true);
else
- qWarning() << "createdItem for " << index << " produced a null item";
+ qWarning() << "QQmlDelegateModel:: object called in createdItem for " << index << " produced a null item";
}
void QDeclarativeGeoMapItemView::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
@@ -189,9 +194,12 @@ void QDeclarativeGeoMapItemView::modelUpdated(const QQmlChangeSet &changeSet, bo
}
}
+ QBoolBlocker createBlocker(m_creatingObject, true);
for (const QQmlChangeSet::Change &c: changeSet.inserts()) {
- for (int idx = c.start(); idx < c.end(); idx++)
- addDelegateToMap(qobject_cast<QQuickItem *>(m_delegateModel->object(idx, m_incubationMode)), idx);
+ for (int idx = c.start(); idx < c.end(); idx++) {
+ QObject *delegateInstance = m_delegateModel->object(idx, m_incubationMode);
+ addDelegateToMap(qobject_cast<QQuickItem *>(delegateInstance), idx);
+ }
}
fitViewport();
@@ -316,8 +324,11 @@ void QDeclarativeGeoMapItemView::instantiateAllItems()
return;
// If here, m_delegateModel may contain data, but QQmlInstanceModel::object for each row hasn't been called yet.
- for (int i = 0; i < m_delegateModel->count(); i++)
- addDelegateToMap(qobject_cast<QQuickItem *>(m_delegateModel->object(i, m_incubationMode)), i);
+ QBoolBlocker createBlocker(m_creatingObject, true);
+ for (int i = 0; i < m_delegateModel->count(); i++) {
+ QObject *delegateInstance = m_delegateModel->object(i, m_incubationMode);
+ addDelegateToMap(qobject_cast<QQuickItem *>(delegateInstance), i);
+ }
fitViewport();
}
@@ -346,15 +357,12 @@ void QDeclarativeGeoMapItemView::removeDelegateFromMap(int index, bool transitio
{
if (index >= 0 && index < m_instantiatedItems.size()) {
QQuickItem *item = m_instantiatedItems.takeAt(index);
- if (!item) {
- if (m_incubatingItems.contains(index)) {
- // cancel request
- m_delegateModel->cancel(index);
- m_incubatingItems.remove(index);
- }
+ if (!item) { // not yet incubated
+ // Don't cancel incubation explicitly, as DelegateModel apparently takes care of incubating elements when the model
+ // remove those indices.
return;
}
- // item can be either a QDeclarativeGeoMapItemBase or a QDeclarativeGeoMapItemGroup
+ // item can be either a QDeclarativeGeoMapItemBase or a QDeclarativeGeoMapItemGroup (subclass)
if (m_exit && m_map && transition) {
transitionItemOut(item);
} else {
@@ -443,16 +451,14 @@ void QDeclarativeGeoMapItemView::exitTransitionFinished()
#endif
}
-void QDeclarativeGeoMapItemView::addItemToMap(QDeclarativeGeoMapItemBase *item, int index)
+void QDeclarativeGeoMapItemView::addItemToMap(QDeclarativeGeoMapItemBase *item, int index, bool createdItem)
{
- if (m_map && item) { // belonging to another map??
- if (item->quickMap() == m_map)
- return;
- }
+ if (m_map && item->quickMap() == m_map) // test for *item done in the caller
+ return;
if (m_map) {
- insertInstantiatedItem(index, item);
+ insertInstantiatedItem(index, item, createdItem);
item->setParentItem(this);
m_map->addMapItem(item);
if (m_enter) {
@@ -466,23 +472,21 @@ void QDeclarativeGeoMapItemView::addItemToMap(QDeclarativeGeoMapItemBase *item,
}
}
-void QDeclarativeGeoMapItemView::insertInstantiatedItem(int index, QQuickItem *o)
+void QDeclarativeGeoMapItemView::insertInstantiatedItem(int index, QQuickItem *o, bool createdItem)
{
- if (m_incubatingItems.contains(index)) {
- m_incubatingItems.remove(index);
+ if (createdItem)
m_instantiatedItems.replace(index, o);
- } else {
+ else
m_instantiatedItems.insert(index, o);
- }
}
-void QDeclarativeGeoMapItemView::addItemViewToMap(QDeclarativeGeoMapItemView *item, int index)
+void QDeclarativeGeoMapItemView::addItemViewToMap(QDeclarativeGeoMapItemView *item, int index, bool createdItem)
{
- if (!item || (m_map && item->quickMap() == m_map))
+ if (m_map && item->quickMap() == m_map) // test for *item done in the caller
return;
if (m_map) {
- insertInstantiatedItem(index, item);
+ insertInstantiatedItem(index, item, createdItem);
item->setParentItem(this);
m_map->addMapItemView(item);
if (m_enter) {
@@ -496,13 +500,13 @@ void QDeclarativeGeoMapItemView::addItemViewToMap(QDeclarativeGeoMapItemView *it
}
}
-void QDeclarativeGeoMapItemView::addItemGroupToMap(QDeclarativeGeoMapItemGroup *item, int index)
+void QDeclarativeGeoMapItemView::addItemGroupToMap(QDeclarativeGeoMapItemGroup *item, int index, bool createdItem)
{
- if (!item || (m_map && item->quickMap() == m_map))
+ if (m_map && item->quickMap() == m_map) // test for *item done in the caller
return;
if (m_map) {
- insertInstantiatedItem(index, item);
+ insertInstantiatedItem(index, item, createdItem);
item->setParentItem(this);
m_map->addMapItemGroup(item);
if (m_enter) {
@@ -516,28 +520,29 @@ void QDeclarativeGeoMapItemView::addItemGroupToMap(QDeclarativeGeoMapItemGroup *
}
}
-void QDeclarativeGeoMapItemView::addDelegateToMap(QQuickItem *object, int index)
+void QDeclarativeGeoMapItemView::addDelegateToMap(QQuickItem *object, int index, bool createdItem)
{
if (!object) {
- m_incubatingItems.insert(index);
- m_instantiatedItems.insert(index, nullptr);
+ if (!createdItem)
+ m_instantiatedItems.insert(index, nullptr); // insert placeholder
return;
}
QDeclarativeGeoMapItemBase *item = qobject_cast<QDeclarativeGeoMapItemBase *>(object);
if (item) { // else createdItem will be emitted.
- addItemToMap(item, index);
+ addItemToMap(item, index, createdItem);
return;
}
QDeclarativeGeoMapItemView *view = qobject_cast<QDeclarativeGeoMapItemView *>(object);
if (view) {
- addItemViewToMap(view, index);
+ addItemViewToMap(view, index, createdItem);
return;
}
QDeclarativeGeoMapItemGroup *group = qobject_cast<QDeclarativeGeoMapItemGroup *>(object);
if (group) {
- addItemGroupToMap(group, index);
+ addItemGroupToMap(group, index, createdItem);
return;
}
+ qWarning() << "addDelegateToMap called with a "<< object->metaObject()->className();
}
QT_END_NAMESPACE
diff --git a/src/location/declarativemaps/qdeclarativegeomapitemview_p.h b/src/location/declarativemaps/qdeclarativegeomapitemview_p.h
index 58ef2835..43ca685a 100644
--- a/src/location/declarativemaps/qdeclarativegeomapitemview_p.h
+++ b/src/location/declarativemaps/qdeclarativegeomapitemview_p.h
@@ -131,11 +131,11 @@ private:
void removeDelegateFromMap(QQuickItem *o);
void transitionItemOut(QQuickItem *o);
- void insertInstantiatedItem(int index, QQuickItem *o);
- void addItemToMap(QDeclarativeGeoMapItemBase *item, int index);
- void addItemViewToMap(QDeclarativeGeoMapItemView *item, int index);
- void addItemGroupToMap(QDeclarativeGeoMapItemGroup *item, int index);
- void addDelegateToMap(QQuickItem *object, int index);
+ void insertInstantiatedItem(int index, QQuickItem *o, bool createdItem);
+ void addItemToMap(QDeclarativeGeoMapItemBase *item, int index, bool createdItem);
+ void addItemViewToMap(QDeclarativeGeoMapItemView *item, int index, bool createdItem);
+ void addItemGroupToMap(QDeclarativeGeoMapItemGroup *item, int index, bool createdItem);
+ void addDelegateToMap(QQuickItem *object, int index, bool createdItem = false);
bool m_componentCompleted;
QQmlIncubator::IncubationMode m_incubationMode = QQmlIncubator::Asynchronous;
@@ -143,8 +143,8 @@ private:
QVariant m_itemModel;
QDeclarativeGeoMap *m_map;
QList<QQuickItem *> m_instantiatedItems;
- QSet<int> m_incubatingItems;
bool m_fitViewport;
+ bool m_creatingObject = false;
QQmlDelegateModel *m_delegateModel;
QQuickTransition *m_enter = nullptr;
QQuickTransition *m_exit = nullptr;
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
index 70b4bc21..2fb3098d 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
@@ -398,9 +398,13 @@ 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.visibleGeometryExpanded();
+ const QList<QDoubleVector2D> &visibleRegion = p.projectableGeometry();
if (visibleRegion.size()) {
clippedPaths = clipLine(wrappedPath, visibleRegion);
@@ -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);
@@ -507,6 +513,120 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map,
pathToScreen(map, clippedPaths, leftBoundWrapped);
}
+// *** SCREEN CLIPPING *** //
+
+enum ClipPointType {
+ InsidePoint = 0x00,
+ LeftPoint = 0x01,
+ RightPoint = 0x02,
+ BottomPoint = 0x04,
+ TopPoint = 0x08
+};
+
+static inline int clipPointType(qreal x, qreal y, const QRectF &rect)
+{
+ int type = InsidePoint;
+ if (x < rect.left())
+ type |= LeftPoint;
+ else if (x > rect.right())
+ type |= RightPoint;
+ if (y < rect.top())
+ type |= TopPoint;
+ else if (y > rect.bottom())
+ type |= BottomPoint;
+ return type;
+}
+
+static void clipSegmentToRect(qreal x0, qreal y0, qreal x1, qreal y1,
+ const QRectF &clipRect,
+ QVector<qreal> &outPoints,
+ QVector<QPainterPath::ElementType> &outTypes)
+{
+ int type0 = clipPointType(x0, y0, clipRect);
+ int type1 = clipPointType(x1, y1, clipRect);
+ bool accept = false;
+
+ while (true) {
+ if (!(type0 | type1)) {
+ accept = true;
+ break;
+ } else if (type0 & type1) {
+ break;
+ } else {
+ qreal x = 0.0;
+ qreal y = 0.0;
+ int outsideType = type0 ? type0 : type1;
+
+ if (outsideType & BottomPoint) {
+ x = x0 + (x1 - x0) * (clipRect.bottom() - y0) / (y1 - y0);
+ y = clipRect.bottom() - 0.1;
+ } else if (outsideType & TopPoint) {
+ x = x0 + (x1 - x0) * (clipRect.top() - y0) / (y1 - y0);
+ y = clipRect.top() + 0.1;
+ } else if (outsideType & RightPoint) {
+ y = y0 + (y1 - y0) * (clipRect.right() - x0) / (x1 - x0);
+ x = clipRect.right() - 0.1;
+ } else if (outsideType & LeftPoint) {
+ y = y0 + (y1 - y0) * (clipRect.left() - x0) / (x1 - x0);
+ x = clipRect.left() + 0.1;
+ }
+
+ if (outsideType == type0) {
+ x0 = x;
+ y0 = y;
+ type0 = clipPointType(x0, y0, clipRect);
+ } else {
+ x1 = x;
+ y1 = y;
+ type1 = clipPointType(x1, y1, clipRect);
+ }
+ }
+ }
+
+ if (accept) {
+ if (outPoints.size() >= 2) {
+ qreal lastX, lastY;
+ lastY = outPoints.at(outPoints.size() - 1);
+ lastX = outPoints.at(outPoints.size() - 2);
+
+ if (!qFuzzyCompare(lastY, y0) || !qFuzzyCompare(lastX, x0)) {
+ outTypes << QPainterPath::MoveToElement;
+ outPoints << x0 << y0;
+ }
+ } else {
+ outTypes << QPainterPath::MoveToElement;
+ outPoints << x0 << y0;
+ }
+
+ outTypes << QPainterPath::LineToElement;
+ outPoints << x1 << y1;
+ }
+}
+
+static void clipPathToRect(const QVector<qreal> &points,
+ const QVector<QPainterPath::ElementType> &types,
+ const QRectF &clipRect,
+ QVector<qreal> &outPoints,
+ QVector<QPainterPath::ElementType> &outTypes)
+{
+ outPoints.clear();
+ outPoints.reserve(points.size());
+ outTypes.clear();
+ outTypes.reserve(types.size());
+
+ qreal lastX = 0;
+ qreal lastY = 0; // or else used uninitialized
+ for (int i = 0; i < types.size(); ++i) {
+ if (i > 0 && types[i] != QPainterPath::MoveToElement) {
+ qreal x = points[i * 2], y = points[i * 2 + 1];
+ clipSegmentToRect(lastX, lastY, x, y, clipRect, outPoints, outTypes);
+ }
+
+ lastX = points[i * 2];
+ lastY = points[i * 2 + 1];
+ }
+}
+
////////////////////////////////////////////////////////////////////////////
/*!
@@ -526,9 +646,24 @@ void QGeoMapPolylineGeometry::updateScreenPoints(const QGeoMap &map,
return;
}
- // The geometry has already been clipped against the visible region projection in wrapped mercator space.
- QVector<qreal> points = srcPoints_;
- QVector<QPainterPath::ElementType> types = srcPointTypes_;
+ // Create the viewport rect in the same coordinate system
+ // as the actual points
+ QRectF viewport(0, 0, map.viewportWidth(), map.viewportHeight());
+ viewport.adjust(-strokeWidth, -strokeWidth, strokeWidth, strokeWidth);
+ viewport.translate(-1 * origin);
+
+ QVector<qreal> points;
+ QVector<QPainterPath::ElementType> types;
+
+ if (clipToViewport_) {
+ // Although the geometry has already been clipped against the visible region in wrapped mercator space.
+ // This is currently still needed to prevent a number of artifacts deriving from QTriangulatingStroker processing
+ // very large lines (that is, polylines that span many pixels in screen space)
+ clipPathToRect(srcPoints_, srcPointTypes_, viewport, points, types);
+ } else {
+ points = srcPoints_;
+ types = srcPointTypes_;
+ }
QVectorPath vp(points.data(), types.size(), types.data());
QTriangulatingStroker ts;
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/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/doc/src/plugins/mapboxgl.qdoc b/src/location/doc/src/plugins/mapboxgl.qdoc
index 51b49f93..b1d721bf 100644
--- a/src/location/doc/src/plugins/mapboxgl.qdoc
+++ b/src/location/doc/src/plugins/mapboxgl.qdoc
@@ -88,6 +88,11 @@ The following table lists optional parameters that can be passed to the Mapbox p
\l{https://www.mapbox.com/tos}{Terms of Services} and must not be used in production. This property has
no effect on styles hosted outside the Mapbox servers.
\row
+ \li mapboxgl.china
+ \li Use Mapbox China API base URLs and styles.
+ Please notice that Mapbox China requires a specific access token. Contact \l
+ {https://www.mapbox.com/contact/sales/} {Mapbox sales} for more information.
+\row
\li mapboxgl.mapping.additional_style_urls
\li Additional, comma separated, Mapbox \l{https://www.mapbox.com/help/define-style-url}
{style URLs} to be added to the available style URLs. Additional styles will be prepended to
diff --git a/src/location/doc/src/qtlocation-qml.qdoc b/src/location/doc/src/qtlocation-qml.qdoc
index 38f43ef1..90f19c5a 100644
--- a/src/location/doc/src/qtlocation-qml.qdoc
+++ b/src/location/doc/src/qtlocation-qml.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -26,83 +26,103 @@
****************************************************************************/
/*!
- \qmlmodule QtLocation 5.11
+ \qmlmodule QtLocation \QtVer
\title Qt Location QML Types
\ingroup qmlmodules
- \brief Provides QML types for mapping and location information
+ \brief Provides QML types for mapping and location information.
-\section1 Overview
+ \section1 Overview
-Provided that a position has been obtained, this module can add a
-\l{QtLocation::Map}{Map} with Places of Interest (POI) and
-\l{QtLocation::Place}{Places}. The user can be made aware of nearby features
-and related information, displayed graphically. Features on the \l Map can be
-places of business, entertainment, and so on. They may include paths, roads,
-or forms of transport, enabling navigation optimization and assistance.
+ Provided that a position has been obtained, the Qt Location module
+ can add a \l{QtLocation::}{Map} with Places of Interest (POI) and
+ \l{QtLocation::Place}{Places}. The user can be made aware of nearby
+ features and related information, displayed on the map. These features
+ can be places of business, entertainment, and so on. They may include
+ paths, roads, or forms of transport, enabling navigation optimization
+ and assistance.
-To perform navigation we need \l {Route}s from start to destination. These routes
-are made up of segments, where each \l {QtLocation::RouteSegment}{RouteSegment}
-can be considered a navigation subtask: drive 100 meters, turn left. The beginning and
-end of each segment is a \e waypoint, that is, one part of our journey.
+ To perform navigation we need \l {Route}s from start to destination.
+ These routes are made up of segments, where each \l {QtLocation::}
+ {RouteSegment} can be considered a navigation subtask; for example,
+ "drive 100 meters", or "turn left". The beginning and end of each
+ segment is a \e waypoint, that is, one part of the journey.
-A typical use case for the API is a user looking for a particular type of
-place, say a restaurant. The user could enter a search string into the map
-application and respond to a list or display of results for restaurants
-"near" the device. The application could then be used to navigate to the
-restaurant using an optimized route that is aware of features in the
-environment that can help or hinder the journey. The navigation then
-proceeds with the user's progress monitored by means of the current
-\l Location. In the context of this API the map application would be aware
-of the location and size of various places and the location of the user.
-Plugins would supply the data required by the application to determine routes
-and navigation instructions. The \l Place types would hold information about the
-destination and surrounding objects including displayable representations.
-The \l Map type would enable this information to be displayed, panned,
-zoomed and so on. The \l Route would be determined by a plugin with each
-\l RouteSegment holding the navigation instructions guided by the updated
-current \l Location.
+ A typical use case for the API is a user looking for a particular type of
+ place, such as a restaurant; the user enters a search string into the map
+ application and is presented with a list of results for restaurants
+ "near" the device. The application can then be used to navigate to the
+ chosen destination using a route that is optimized according to features
+ in the environment that may help or hinder the journey. The navigation then
+ proceeds with the user's progress monitored by means of the current
+ location.
-\l {Plugin}s are a means of specifying which location-based service to use. For
-example, a plugin may allow connection to a provider's service that provides
-geocoding and routing information, which can be consumed by the application.
-There may be various GeoServices plugins for various tasks with some plugins
-providing more than one service. One QML \l Plugin must be created for each
-required GeoService plugin. Plugins are required for maps, routing and geocoding,
-and places, however the default plugin handles all four of these services. A plugin may
-require online access or may support on-board maps and data.
+ In short, the main QML types and their roles are as follows:
-\note Plugins may not provide features such as paging or relevance hints.
+ \list
-The following links provide more detailed information about maps and places:
+ \li The \l [QML] Place instances hold information about the
+ destination and surrounding objects, including displayable
+ representations.
-\table
- \row
- \li \l {Maps and Navigation (QML)}{Maps and Navigation}
- \li Displaying maps and finding routes.
- \row
- \li \l {QML PLaces API} {Places}
- \li Searching for and managing points of interest.
-\endtable
+ \li The \l [QML] Map enables the information contained in
+ \l [QML] {Place} objects to be displayed, panned, zoomed,
+ and so on.
-\section1 Common QML Types
+ \li The \l [QML] Route is be determined by a \e plugin, with each
+ \l [QML] RouteSegment holding the navigation instructions,
+ guided by the continuously updated current \l [QML] Location.
-\annotatedlist qml-QtLocation5-common
+ \endlist
-\section1 Maps QML Types
+ \section2 Plugins
-\annotatedlist qml-QtLocation5-maps
+ \l {Plugin}s supply the data required to calculate routes and navigation
+ instructions, and they are typically tied to a specific location-based
+ service. For example, a plugin may allow connecting to a service that
+ provides geocoding and routing information, which can be consumed by the
+ application.
-\section1 Navigation and Routing QML Types
+ There may be various GeoServices plugins for various tasks, with some
+ plugins providing more than one service. One QML \l Plugin instance must
+ be created for each GeoService plugin. Plugins are required for routing
+ and geocoding, maps, and places, however the default plugin handles all
+ four of these services. A plugin may require online access or it may
+ support on-board maps and data.
-\annotatedlist qml-QtLocation5-routing
+ \note Plugins may not provide features such as paging or relevance hints.
-\section1 Geocoding QML Types
+ \section2 Related Information
-\annotatedlist qml-QtLocation5-geocoding
+ The following links provide more information about maps and places:
-\section1 Places QML Types
+ \table
+ \row
+ \li \l {Maps and Navigation (QML)}{Maps and Navigation}
+ \li Displaying maps and finding routes
+ \row
+ \li \l {QML Places API} {Places}
+ \li Searching for and managing points of interest
+ \endtable
-\annotatedlist qml-QtLocation5-places
+ \section1 Common QML Types
-\section1 Alphabetical Listing of All QML Types
+ \annotatedlist qml-QtLocation5-common
+
+ \section1 Maps QML Types
+
+ \annotatedlist qml-QtLocation5-maps
+
+ \section1 Navigation and Routing QML Types
+
+ \annotatedlist qml-QtLocation5-routing
+
+ \section1 Geocoding QML Types
+
+ \annotatedlist qml-QtLocation5-geocoding
+
+ \section1 Places QML Types
+
+ \annotatedlist qml-QtLocation5-places
+
+ \section1 Alphabetical Listing of All QML Types
*/
diff --git a/src/location/doc/src/qtlocation.qdoc b/src/location/doc/src/qtlocation.qdoc
index 77c2cd99..059d03f2 100644
--- a/src/location/doc/src/qtlocation.qdoc
+++ b/src/location/doc/src/qtlocation.qdoc
@@ -87,10 +87,10 @@ The Qt Location API enables you to:
To load the Qt Location module, add the following statement to your .qml files
-\code
- import QtPositioning 5.11
- import QtLocation 5.11
-\endcode
+\qml \QtVer
+import QtPositioning \1
+import QtLocation \1
+\endqml
The QtLocation QML module depends on the QtPositioning QML module.
Therefore every QML application that imports the QtLocation QML module must always
diff --git a/src/location/labs/qdeclarativenavigator.cpp b/src/location/labs/qdeclarativenavigator.cpp
index b06681d9..0bf5035f 100644
--- a/src/location/labs/qdeclarativenavigator.cpp
+++ b/src/location/labs/qdeclarativenavigator.cpp
@@ -296,15 +296,15 @@ bool QDeclarativeNavigator::navigatorReady() const
bool QDeclarativeNavigator::trackPositionSource() const
{
- return d_ptr->m_trackPositionSource;
+ return d_ptr->m_params->m_trackPositionSource;
}
void QDeclarativeNavigator::setTrackPositionSource(bool trackPositionSource)
{
- if (trackPositionSource == d_ptr->m_trackPositionSource)
+ if (trackPositionSource == d_ptr->m_params->m_trackPositionSource)
return;
- d_ptr->m_trackPositionSource = trackPositionSource;
+ d_ptr->m_params->m_trackPositionSource = trackPositionSource;
emit trackPositionSourceChanged(trackPositionSource);
}
@@ -414,6 +414,7 @@ bool QDeclarativeNavigator::ensureEngine()
d_ptr->m_active = active;
emit activeChanged(active);
});
+ connect(this, &QDeclarativeNavigator::trackPositionSourceChanged, d_ptr->m_navigator.get(), &QAbstractNavigator::setTrackPosition);
emit navigatorReadyChanged(true);
return true;
}
diff --git a/src/location/labs/qdeclarativenavigator_p_p.h b/src/location/labs/qdeclarativenavigator_p_p.h
index 6c07a0ca..229ead1e 100644
--- a/src/location/labs/qdeclarativenavigator_p_p.h
+++ b/src/location/labs/qdeclarativenavigator_p_p.h
@@ -73,6 +73,7 @@ public:
QGeoRoute m_geoRoute;
QPointer<QDeclarativePositionSource> m_positionSource;
QList<QPointer<QGeoMapParameter>> m_parameters;
+ bool m_trackPositionSource = true;
};
class QDeclarativeNavigatorPrivate
@@ -90,7 +91,6 @@ public:
bool m_active = false;
bool m_completed = false;
bool m_ready = false;
- bool m_trackPositionSource = true;
};
QT_END_NAMESPACE
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 a456f80e..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);
@@ -624,7 +624,8 @@ void QGeoProjectionWebMercator::setupCamera()
m_viewMercator = m_eyeMercator - m_centerMercator;
m_upMercator = QDoubleVector3D::normal(m_viewMercator, m_sideMercator);
- m_nearPlaneMercator = 1.0 / m_sideLength;
+ m_nearPlaneMercator = 0.000002; // this value works until ZL 18. Above that, a better progressive formula is needed, or
+ // else, this clips too much.
double aspectRatio = 1.0 * m_viewportWidth / m_viewportHeight;
@@ -657,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 11b1c28d..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(
@@ -534,9 +538,13 @@ QPlaceManager *QGeoServiceProvider::placeManager() const
*/
QNavigationManager *QGeoServiceProvider::navigationManager() const
{
- return d_ptr->manager<QNavigationManager, QNavigationManagerEngine>(
+ QNavigationManager * mgr = d_ptr->manager<QNavigationManager, QNavigationManagerEngine>(
&(d_ptr->navigationError), &(d_ptr->navigationErrorString),
&(d_ptr->navigationManager));
+ if (!mgr) {
+ qDebug() << d_ptr->navigationError << d_ptr->navigationErrorString;
+ }
+ return mgr;
}
/*!
@@ -747,6 +755,11 @@ void QGeoServiceProviderPrivate::loadPlugin(const QVariantMap &parameters)
// load the actual plugin
QObject *instance = loader()->instance(idx);
+ if (!instance) {
+ error = QGeoServiceProvider::LoaderError;
+ 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);
if (!factoryV3) {
factoryV2 = qobject_cast<QGeoServiceProviderFactoryV2 *>(instance);
diff --git a/src/location/maps/qgeoserviceprovider.h b/src/location/maps/qgeoserviceprovider.h
index 8e594977..b2e0be05 100644
--- a/src/location/maps/qgeoserviceprovider.h
+++ b/src/location/maps/qgeoserviceprovider.h
@@ -69,7 +69,8 @@ public:
NotSupportedError,
UnknownParameterError,
MissingRequiredParameterError,
- ConnectionError
+ ConnectionError,
+ LoaderError
};
enum RoutingFeature {
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/location/maps/qnavigationmanagerengine.cpp b/src/location/maps/qnavigationmanagerengine.cpp
index 1f82b4a1..770e30a6 100644
--- a/src/location/maps/qnavigationmanagerengine.cpp
+++ b/src/location/maps/qnavigationmanagerengine.cpp
@@ -54,7 +54,6 @@ class QAbstractNavigatorPrivate
public:
QLocale locale;
QLocale::MeasurementSystem measurementSystem;
- bool initialized = false;
};
QAbstractNavigator::QAbstractNavigator(QObject *parent)
diff --git a/src/location/maps/qnavigationmanagerengine_p.h b/src/location/maps/qnavigationmanagerengine_p.h
index 62d9eb87..0852b3ea 100644
--- a/src/location/maps/qnavigationmanagerengine_p.h
+++ b/src/location/maps/qnavigationmanagerengine_p.h
@@ -81,6 +81,7 @@ public:
public slots:
virtual bool start() = 0;
virtual bool stop() = 0;
+ virtual void setTrackPosition(bool trackPosition) = 0;
signals:
// These must be emitted by the engine
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
index 4614de89..ed36cd5f 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
+++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
@@ -378,7 +378,7 @@ QString QGeoMapMapboxGL::copyrightsStyleSheet() const
return QStringLiteral("* { vertical-align: middle; font-weight: normal }");
}
-void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings)
+void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings, bool useChinaEndpoint)
{
Q_D(QGeoMapMapboxGL);
@@ -386,8 +386,13 @@ void QGeoMapMapboxGL::setMapboxGLSettings(const QMapboxGLSettings& settings)
// If the access token is not set, use the development access token.
// This will only affect mapbox:// styles.
+ // Mapbox China requires a China-specific access token.
if (d->m_settings.accessToken().isEmpty()) {
- d->m_settings.setAccessToken(developmentToken);
+ if (useChinaEndpoint) {
+ qWarning("Mapbox China requires an access token: https://www.mapbox.com/contact/sales");
+ } else {
+ d->m_settings.setAccessToken(developmentToken);
+ }
}
}
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
index 0ffaf4ea..5fc2260e 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
+++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.h
@@ -54,7 +54,7 @@ public:
virtual ~QGeoMapMapboxGL();
QString copyrightsStyleSheet() const override;
- void setMapboxGLSettings(const QMapboxGLSettings &);
+ void setMapboxGLSettings(const QMapboxGLSettings &, bool useChinaEndpoint);
void setUseFBO(bool);
void setMapItemsBefore(const QString &);
Capabilities capabilities() const override;
diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp
index cc48afb2..d2463106 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp
+++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.cpp
@@ -69,30 +69,45 @@ QGeoMappingManagerEngineMapboxGL::QGeoMappingManagerEngineMapboxGL(const QVarian
int mapId = 0;
const QByteArray pluginName = "mapboxgl";
- mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/streets-v10"),
- tr("Streets"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/basic-v9"),
- tr("Basic"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/bright-v9"),
- tr("Bright"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::TerrainMap, QStringLiteral("mapbox://styles/mapbox/outdoors-v10"),
- tr("Outdoors"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, QStringLiteral("mapbox://styles/mapbox/satellite-v9"),
- tr("Satellite"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::HybridMap, QStringLiteral("mapbox://styles/mapbox/satellite-streets-v10"),
- tr("Satellite Streets"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/light-v9"),
- tr("Light"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/dark-v9"),
- tr("Dark"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-day-v2"),
- tr("Navigation Preview Day"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-night-v2"),
- tr("Navigation Preview Night"), false, true, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-day-v2"),
- tr("Navigation Guidance Day"), false, false, ++mapId, pluginName, cameraCaps);
- mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-night-v2"),
- tr("Navigation Guidance Night"), false, true, ++mapId, pluginName, cameraCaps);
+ if (parameters.contains(QStringLiteral("mapboxgl.china"))) {
+ m_useChinaEndpoint = parameters.value(QStringLiteral("mapboxgl.china")).toBool();
+ }
+
+ if (m_useChinaEndpoint) {
+ m_settings.setApiBaseUrl(QStringLiteral("https://api.mapbox.cn"));
+
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/streets-zh-v1"),
+ tr("China Streets"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/light-zh-v1"),
+ tr("China Light"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/dark-zh-v1"),
+ tr("China Dark"), false, false, ++mapId, pluginName, cameraCaps);
+ } else {
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/streets-v10"),
+ tr("Streets"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/basic-v9"),
+ tr("Basic"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox://styles/mapbox/bright-v9"),
+ tr("Bright"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::TerrainMap, QStringLiteral("mapbox://styles/mapbox/outdoors-v10"),
+ tr("Outdoors"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, QStringLiteral("mapbox://styles/mapbox/satellite-v9"),
+ tr("Satellite"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::HybridMap, QStringLiteral("mapbox://styles/mapbox/satellite-streets-v10"),
+ tr("Satellite Streets"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/light-v9"),
+ tr("Light"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::GrayStreetMap, QStringLiteral("mapbox://styles/mapbox/dark-v9"),
+ tr("Dark"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-day-v2"),
+ tr("Navigation Preview Day"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::TransitMap, QStringLiteral("mapbox://styles/mapbox/navigation-preview-night-v2"),
+ tr("Navigation Preview Night"), false, true, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-day-v2"),
+ tr("Navigation Guidance Day"), false, false, ++mapId, pluginName, cameraCaps);
+ mapTypes << QGeoMapType(QGeoMapType::CarNavigationMap, QStringLiteral("mapbox://styles/mapbox/navigation-guidance-night-v2"),
+ tr("Navigation Guidance Night"), false, true, ++mapId, pluginName, cameraCaps);
+ }
if (parameters.contains(QStringLiteral("mapboxgl.mapping.additional_style_urls"))) {
const QString ids = parameters.value(QStringLiteral("mapboxgl.mapping.additional_style_urls")).toString();
@@ -156,7 +171,7 @@ QGeoMappingManagerEngineMapboxGL::~QGeoMappingManagerEngineMapboxGL()
QGeoMap *QGeoMappingManagerEngineMapboxGL::createMap()
{
QGeoMapMapboxGL* map = new QGeoMapMapboxGL(this, 0);
- map->setMapboxGLSettings(m_settings);
+ map->setMapboxGLSettings(m_settings, m_useChinaEndpoint);
map->setUseFBO(m_useFBO);
map->setMapItemsBefore(m_mapItemsBefore);
diff --git a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h
index b3afe77b..9ceb8ccc 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h
+++ b/src/plugins/geoservices/mapboxgl/qgeomappingmanagerenginemapboxgl.h
@@ -59,6 +59,7 @@ public:
private:
QMapboxGLSettings m_settings;
bool m_useFBO = true;
+ bool m_useChinaEndpoint = false;
QString m_mapItemsBefore;
};
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/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/position.pro b/src/plugins/position/position.pro
index 4453b8a3..6800d5a3 100644
--- a/src/plugins/position/position.pro
+++ b/src/plugins/position/position.pro
@@ -2,8 +2,8 @@ TEMPLATE = subdirs
QT_FOR_CONFIG += positioning-private
-qtHaveModule(dbus):SUBDIRS += geoclue
-qtHaveModule(dbus):SUBDIRS += geoclue2
+linux:qtHaveModule(dbus):SUBDIRS += geoclue
+linux:qtHaveModule(dbus):SUBDIRS += geoclue2
qtConfig(gypsy):SUBDIRS += gypsy
qtConfig(winrt_geolocation):SUBDIRS += winrt
qtHaveModule(simulator):SUBDIRS += simulator
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/doc/src/qtpositioning-qml.qdoc b/src/positioning/doc/src/qtpositioning-qml.qdoc
index 7c9567cb..0c84484b 100644
--- a/src/positioning/doc/src/qtpositioning-qml.qdoc
+++ b/src/positioning/doc/src/qtpositioning-qml.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2018 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
@@ -26,40 +26,46 @@
****************************************************************************/
/*!
- \qmlmodule QtPositioning 5.11
+ \qmlmodule QtPositioning \QtVer
\title Qt Positioning QML Types
\ingroup qmlmodules
- \brief Provides QML types for position information
+ \brief Provides QML types for position information.
-\section1 Overview
+ \section1 Overview
-The identifying string for this module is \e QtPositioning. To use include the following import
-statement in the QML file.
+ The identifying string for this module is \e QtPositioning. To use the QML
+ from this module, include the following import statement in the QML file:
-\snippet doc_src_qtpositioning.qml import
+ \qml \QtVer
+ import QtPositioning \1
+ \endqml
-\section2 Positioning QML Concepts
+ \section2 Positioning QML Concepts
-Position information can come from a variety of sources including satellites,
-wifi, text files and so on. The position is described by the latitude,
-the longitude, and the altitude in meters. For more information see
-\l {http://en.wikipedia.org/wiki/Geographic_coordinate}{Geographic Coordinate}.
+ Position information can come from a variety of sources including
+ satellites, Wi-Fi, text files and so on. The position is described by the
+ latitude, longitude, and the altitude in meters. For more information, see
+ the Wikipedia page on
+ \l {http://en.wikipedia.org/wiki/Geographic_coordinate}
+ {Geographic Coordinates}.
-The QML position is stored in a \l {coordinate} which contains the
-latitude, longitude and altitude of the device. The \l {QtPositioning::Location}{Location} contains
-this \l {coordinate} and adds an address, it also has a bounding box which
-defines the recommended viewing region when displaying the location.
+ The QML position is stored in a \l {coordinate} which contains the
+ latitude, longitude and altitude of the device. The \l {QtPositioning::}
+ {Location} contains this \l {coordinate} and adds an address, and also has
+ a bounding box which defines the recommended viewing region when displaying
+ the location.
-Now that the device has a position, with regular updates the API can determine
-the speed and heading of the device. It can also define a box or a circle that can
-produce a notification when the device either leaves or enters that region.
+ Now that the device has a position, with regular updates the API can
+ determine the speed and heading of the device. It can also define a
+ box-shaped or circular region that triggers notifications when the device
+ either leaves or enters that region.
-More detailed information retrieving the current position can be found under
-\l {Positioning (QML)}{Location Positioning via QML}
+ More detailed information on retrieving the current position can be found
+ under \l {Positioning (QML)}{Location Positioning via QML}.
-\section1 Basic Types
+ \section1 Basic Types
-\annotatedlist qml-QtPositioning5-basictypes
+ \annotatedlist qml-QtPositioning5-basictypes
-\section1 Alphabetical Listing of All QML Types
+ \section1 Alphabetical Listing of All QML Types
*/
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);
}