summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-01-26 14:25:06 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-01-26 14:25:06 +0100
commitc6a28570a7300788127117378eb7cd36dcd0953f (patch)
treeb8e56b1bd18fb4438de171004d588d12dbf7abec
parente9ead74ec4169d483de0b711986b5b560bbb730a (diff)
parent24e50e40caaa2f2e057180b8ed8179795e605e2a (diff)
downloadqtlocation-c6a28570a7300788127117378eb7cd36dcd0953f.tar.gz
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: I23c874c5dcd0452142c3cf8abff65415ad31a1e7
-rw-r--r--examples/location/mapviewer/mapviewer.qml6
-rw-r--r--examples/location/mapviewer/menus/MainMenu.qml2
-rw-r--r--examples/positioning/weatherinfo/appmodel.cpp5
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp12
-rw-r--r--src/imports/location/qdeclarativegeomap_p.h1
-rw-r--r--src/imports/location/qdeclarativepolylinemapitem.cpp126
-rw-r--r--src/imports/location/qdeclarativepolylinemapitem_p.h6
-rw-r--r--src/location/maps/qabstractgeotilecache_p.h1
-rw-r--r--src/location/maps/qgeofiletilecache.cpp13
-rw-r--r--src/location/maps/qgeofiletilecache_p.h1
-rw-r--r--src/location/maps/qgeomap.cpp6
-rw-r--r--src/location/maps/qgeomap_p.h2
-rw-r--r--src/location/maps/qgeotiledmap.cpp6
-rw-r--r--src/location/maps/qgeotiledmap_p.h1
-rw-r--r--src/plugins/geoservices/osm/qgeoroutereplyosm.cpp4
-rw-r--r--src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java102
-rw-r--r--src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp16
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp327
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h29
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp8
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h2
-rw-r--r--src/plugins/position/winrt/winrt.pro4
-rw-r--r--src/positioning/doc/src/examples/weatherinfo.qdoc2
-rw-r--r--src/positioning/qpositioningglobal_p.h11
-rw-r--r--tests/auto/declarative_geoshape/tst_locationsingleton.qml59
25 files changed, 576 insertions, 176 deletions
diff --git a/examples/location/mapviewer/mapviewer.qml b/examples/location/mapviewer/mapviewer.qml
index 2cb4e0d0..929ea4ba 100644
--- a/examples/location/mapviewer/mapviewer.qml
+++ b/examples/location/mapviewer/mapviewer.qml
@@ -231,6 +231,12 @@ ApplicationWindow {
stackView.currentItem.selectLanguage.connect(setLanguage)
stackView.currentItem.closeForm.connect(stackView.closeForm)
break
+ case "Clear":
+ map.clearData()
+ break
+ case "Prefetch":
+ map.prefetchData()
+ break
default:
console.log("Unsupported operation")
}
diff --git a/examples/location/mapviewer/menus/MainMenu.qml b/examples/location/mapviewer/menus/MainMenu.qml
index 3dc3e9fb..7054c40d 100644
--- a/examples/location/mapviewer/menus/MainMenu.qml
+++ b/examples/location/mapviewer/menus/MainMenu.qml
@@ -125,6 +125,8 @@ MenuBar {
item.triggered.connect(function() {toggleMapState("FollowMe")})
addItem(qsTr("Language")).triggered.connect(function(){selectTool("Language")})
+ addItem(qsTr("Prefetch Map Data")).triggered.connect(function(){selectTool("Prefetch")})
+ addItem(qsTr("Clear Map Data")).triggered.connect(function(){selectTool("Clear")})
}
}
}
diff --git a/examples/positioning/weatherinfo/appmodel.cpp b/examples/positioning/weatherinfo/appmodel.cpp
index a773cfca..4d8806b8 100644
--- a/examples/positioning/weatherinfo/appmodel.cpp
+++ b/examples/positioning/weatherinfo/appmodel.cpp
@@ -154,6 +154,7 @@ public:
int minMsBeforeNewRequest;
QTimer delayedCityRequestTimer;
QTimer requestNewWeatherTimer;
+ QString app_ident;
AppModelPrivate() :
src(NULL),
@@ -170,6 +171,7 @@ public:
requestNewWeatherTimer.setSingleShot(false);
requestNewWeatherTimer.setInterval(20*60*1000); // 20 min
throttle.invalidate();
+ app_ident = QStringLiteral("36496bad1955bf3365448965a42b9eac");
}
};
@@ -304,6 +306,7 @@ void AppModel::queryCity()
query.addQueryItem("lat", latitude);
query.addQueryItem("lon", longitude);
query.addQueryItem("mode", "json");
+ query.addQueryItem("APPID", d->app_ident);
url.setQuery(query);
qCDebug(requestsLog) << "submitting request";
@@ -385,6 +388,7 @@ void AppModel::refreshWeather()
query.addQueryItem("q", d->city);
query.addQueryItem("mode", "json");
+ query.addQueryItem("APPID", d->app_ident);
url.setQuery(query);
QNetworkReply *rep = d->nam->get(QNetworkRequest(url));
@@ -443,6 +447,7 @@ void AppModel::handleWeatherNetworkData(QObject *replyObj)
query.addQueryItem("q", d->city);
query.addQueryItem("mode", "json");
query.addQueryItem("cnt", "5");
+ query.addQueryItem("APPID", d->app_ident);
url.setQuery(query);
QNetworkReply *rep = d->nam->get(QNetworkRequest(url));
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index 67f723b9..8fbe6e32 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -944,6 +944,18 @@ void QDeclarativeGeoMap::prefetchData()
}
/*!
+ \qmlmethod void QtLocation::Map::clearData()
+
+ Clears map data collected by the currently selected plugin.
+ \note This method will delete cached files.
+ \sa plugin
+*/
+void QDeclarativeGeoMap::clearData()
+{
+ m_map->clearData();
+}
+
+/*!
\qmlproperty string QtLocation::Map::errorString
This read-only property holds the textual presentation of the latest mapping provider error.
diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h
index 69d4687d..06c39640 100644
--- a/src/imports/location/qdeclarativegeomap_p.h
+++ b/src/imports/location/qdeclarativegeomap_p.h
@@ -131,6 +131,7 @@ public:
Q_INVOKABLE void fitViewportToMapItems();
Q_INVOKABLE void pan(int dx, int dy);
Q_INVOKABLE void prefetchData(); // optional hint for prefetch
+ Q_INVOKABLE void clearData();
QString errorString() const;
QGeoServiceProvider::Error error() const;
diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp
index 71a205d3..f2373abf 100644
--- a/src/imports/location/qdeclarativepolylinemapitem.cpp
+++ b/src/imports/location/qdeclarativepolylinemapitem.cpp
@@ -199,6 +199,7 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map,
QDoubleVector2D origin, lastPoint, lastAddedPoint;
+ const double mapWidthHalf = map.width()/2.0;
double unwrapBelowX = 0;
if (preserveGeometry_)
unwrapBelowX = map.coordinateToItemPosition(geoLeftBound_, false).x();
@@ -219,7 +220,8 @@ void QGeoMapPolylineGeometry::updateSourcePoints(const QGeoMap &map,
// unwrap x to preserve geometry if moved to border of map
if (preserveGeometry_ && point.x() < unwrapBelowX
&& !qFuzzyCompare(geoLeftBound_.longitude(), coord.longitude())
- && !qFuzzyCompare(point.x(), unwrapBelowX))
+ && !qFuzzyCompare(point.x(), unwrapBelowX)
+ && !qFuzzyCompare(mapWidthHalf, point.x()))
point.setX(unwrapBelowX + geoDistanceToScreenWidth(map, geoLeftBound_, coord));
if (!foundValid) {
@@ -534,7 +536,6 @@ void QDeclarativePolylineMapItem::setPath(const QJSValue &value)
setPathFromGeoList(pathList);
}
-
/*!
\internal
*/
@@ -551,13 +552,26 @@ void QDeclarativePolylineMapItem::setPathFromGeoList(const QList<QGeoCoordinate>
}
/*!
- \qmlmethod void MapPolyline::addCoordinate(coordinate)
+ \qmlmethod int MapPolyline::pathLength()
+
+ Returns the number of coordinates of the polyline.
- Adds a coordinate to the path.
+ \since Qt Location 5.6
- \sa removeCoordinate, path
+ \sa path
*/
+int QDeclarativePolylineMapItem::pathLength() const
+{
+ return path_.size();
+}
+
+/*!
+ \qmlmethod void MapPolyline::addCoordinate(coordinate)
+
+ Adds a coordinate to the end of the path.
+ \sa insertCoordinate, removeCoordinate, path
+*/
void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate)
{
path_.append(coordinate);
@@ -568,6 +582,78 @@ void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate
}
/*!
+ \qmlmethod void MapPolyline::insertCoordinate(index, coordinate)
+
+ Inserts a \a coordinate to the path at the given \a index.
+
+ \since Qt Location 5.6
+
+ \sa addCoordinate, removeCoordinate, path
+*/
+void QDeclarativePolylineMapItem::insertCoordinate(int index, const QGeoCoordinate &coordinate)
+{
+ if (index < 0 || index > path_.size())
+ return;
+
+ path_.insert(index, coordinate);
+
+ geometry_.markSourceDirty();
+ polishAndUpdate();
+ emit pathChanged();
+}
+
+/*!
+ \qmlmethod void MapPolyline::replaceCoordinate(index, coordinate)
+
+ Replaces the coordinate in the current path at the given \a index
+ with the new \a coordinate.
+
+ \since Qt Location 5.6
+
+ \sa addCoordinate, insertCoordinate, removeCoordinate, path
+*/
+void QDeclarativePolylineMapItem::replaceCoordinate(int index, const QGeoCoordinate &coordinate)
+{
+ if (index < 0 || index >= path_.size())
+ return;
+
+ path_[index] = coordinate;
+
+ geometry_.markSourceDirty();
+ polishAndUpdate();
+ emit pathChanged();
+}
+
+/*!
+ \qmlmethod coordinate MapPolyline::coordinateAt(index)
+
+ Gets the coordinate of the polyline at the given \a index.
+ If the index is outside the path's bounds then an invalid
+ coordinate is returned.
+
+ \since Qt Location 5.6
+*/
+QGeoCoordinate QDeclarativePolylineMapItem::coordinateAt(int index) const
+{
+ if (index < 0 || index >= path_.size())
+ return QGeoCoordinate();
+
+ return path_.at(index);
+}
+
+/*!
+ \qmlmethod coordinate MapPolyline::containsCoordinate(coordinate)
+
+ Returns true if the given \a coordinate is part of the path.
+
+ \since Qt Location 5.6
+*/
+bool QDeclarativePolylineMapItem::containsCoordinate(const QGeoCoordinate &coordinate)
+{
+ return path_.indexOf(coordinate) > -1;
+}
+
+/*!
\qmlmethod void MapPolyline::removeCoordinate(coordinate)
Removes \a coordinate from the path. If there are multiple instances of the
@@ -575,7 +661,7 @@ void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate
If \a coordinate is not in the path this method does nothing.
- \sa addCoordinate, path
+ \sa addCoordinate, insertCoordinate, path
*/
void QDeclarativePolylineMapItem::removeCoordinate(const QGeoCoordinate &coordinate)
{
@@ -591,6 +677,29 @@ void QDeclarativePolylineMapItem::removeCoordinate(const QGeoCoordinate &coordin
}
/*!
+ \qmlmethod void MapPolyline::removeCoordinate(index)
+
+ Removes a coordinate from the path at the given \a index.
+
+ If \a index is invalid then this method does nothing.
+
+ \since Qt Location 5.6
+
+ \sa addCoordinate, insertCoordinate, path
+*/
+void QDeclarativePolylineMapItem::removeCoordinate(int index)
+{
+ if (index < 0 || index >= path_.size())
+ return;
+
+ path_.removeAt(index);
+
+ geometry_.markSourceDirty();
+ polishAndUpdate();
+ emit pathChanged();
+}
+
+/*!
\qmlpropertygroup Location::MapPolyline::line
\qmlproperty int MapPolyline::line.width
\qmlproperty color MapPolyline::line.color
@@ -736,9 +845,10 @@ QSGNode *QDeclarativePolylineMapItem::updateMapItemPaintNode(QSGNode *oldNode, U
bool QDeclarativePolylineMapItem::contains(const QPointF &point) const
{
+ QVector<QPointF> vertices = geometry_.vertices();
QPolygonF tri;
- for (int i = 0; i < geometry_.vertices().size(); ++i) {
- tri << geometry_.vertices()[i];
+ for (int i = 0; i < vertices.size(); ++i) {
+ tri << vertices[i];
if (tri.size() == 3) {
if (tri.containsPoint(point,Qt::OddEvenFill))
return true;
diff --git a/src/imports/location/qdeclarativepolylinemapitem_p.h b/src/imports/location/qdeclarativepolylinemapitem_p.h
index a7b7f167..298dc3bc 100644
--- a/src/imports/location/qdeclarativepolylinemapitem_p.h
+++ b/src/imports/location/qdeclarativepolylinemapitem_p.h
@@ -116,8 +116,14 @@ public:
//from QuickItem
virtual QSGNode *updateMapItemPaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
+ Q_INVOKABLE int pathLength() const;
Q_INVOKABLE void addCoordinate(const QGeoCoordinate &coordinate);
+ Q_INVOKABLE void insertCoordinate(int index, const QGeoCoordinate &coordinate);
+ Q_INVOKABLE void replaceCoordinate(int index, const QGeoCoordinate &coordinate);
+ Q_INVOKABLE QGeoCoordinate coordinateAt(int index) const;
+ Q_INVOKABLE bool containsCoordinate(const QGeoCoordinate &coordinate);
Q_INVOKABLE void removeCoordinate(const QGeoCoordinate &coordinate);
+ Q_INVOKABLE void removeCoordinate(int index);
QJSValue path() const;
virtual void setPath(const QJSValue &value);
diff --git a/src/location/maps/qabstractgeotilecache_p.h b/src/location/maps/qabstractgeotilecache_p.h
index e368066f..141aa9b4 100644
--- a/src/location/maps/qabstractgeotilecache_p.h
+++ b/src/location/maps/qabstractgeotilecache_p.h
@@ -102,6 +102,7 @@ public:
virtual int maxTextureUsage() const = 0;
virtual int minTextureUsage() const = 0;
virtual int textureUsage() const = 0;
+ virtual void clearAll() = 0;
virtual QSharedPointer<QGeoTileTexture> get(const QGeoTileSpec &spec) = 0;
diff --git a/src/location/maps/qgeofiletilecache.cpp b/src/location/maps/qgeofiletilecache.cpp
index 6202f7fb..3d381dc2 100644
--- a/src/location/maps/qgeofiletilecache.cpp
+++ b/src/location/maps/qgeofiletilecache.cpp
@@ -261,6 +261,19 @@ int QGeoFileTileCache::textureUsage() const
return textureCache_.totalCost();
}
+void QGeoFileTileCache::clearAll()
+{
+ textureCache_.clear();
+ memoryCache_.clear();
+ diskCache_.clear();
+ QDir dir(directory_);
+ dir.setNameFilters(QStringList() << QLatin1String("*-*-*-*.*"));
+ dir.setFilter(QDir::Files);
+ foreach (QString dirFile, dir.entryList()) {
+ dir.remove(dirFile);
+ }
+}
+
QSharedPointer<QGeoTileTexture> QGeoFileTileCache::get(const QGeoTileSpec &spec)
{
QSharedPointer<QGeoTileTexture> tt = textureCache_.object(spec);
diff --git a/src/location/maps/qgeofiletilecache_p.h b/src/location/maps/qgeofiletilecache_p.h
index 8afb4c8d..bd3e684b 100644
--- a/src/location/maps/qgeofiletilecache_p.h
+++ b/src/location/maps/qgeofiletilecache_p.h
@@ -115,6 +115,7 @@ public:
int maxTextureUsage() const Q_DECL_OVERRIDE;
int minTextureUsage() const Q_DECL_OVERRIDE;
int textureUsage() const Q_DECL_OVERRIDE;
+ void clearAll() Q_DECL_OVERRIDE;
QSharedPointer<QGeoTileTexture> get(const QGeoTileSpec &spec) Q_DECL_OVERRIDE;
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index edc64839..37bf139a 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -109,6 +109,7 @@ void QGeoMap::setActiveMapType(const QGeoMapType type)
d->m_activeMapType = type;
d->changeActiveMapType(type);
d->setCameraData(d->m_cameraData);
+ emit activeMapTypeChanged();
update();
}
@@ -132,6 +133,11 @@ void QGeoMap::prefetchData()
}
+void QGeoMap::clearData()
+{
+
+}
+
QGeoMapPrivate::QGeoMapPrivate(QGeoMappingManagerEngine *engine)
: QObjectPrivate(),
m_width(0),
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index 58a020dc..acc928ea 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -84,9 +84,11 @@ public:
virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const = 0;
virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const = 0;
virtual void prefetchData();
+ virtual void clearData();
QGeoCameraCapabilities cameraCapabilities();
+
protected:
QGeoMap(QGeoMapPrivate &dd, QObject *parent = 0);
void setCameraData(const QGeoCameraData &cameraData);
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index d561c011..97747049 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -103,6 +103,12 @@ void QGeoTiledMap::prefetchData()
d->prefetchTiles();
}
+void QGeoTiledMap::clearData()
+{
+ Q_D(QGeoTiledMap);
+ d->m_cache->clearAll();
+}
+
void QGeoTiledMap::handleTileVersionChanged()
{
Q_D(QGeoTiledMap);
diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h
index 111056d2..87dac5d1 100644
--- a/src/location/maps/qgeotiledmap_p.h
+++ b/src/location/maps/qgeotiledmap_p.h
@@ -86,6 +86,7 @@ public:
QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const Q_DECL_OVERRIDE;
QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const Q_DECL_OVERRIDE;
void prefetchData() Q_DECL_OVERRIDE;
+ void clearData() Q_DECL_OVERRIDE;
protected:
QSGNode *updateSceneGraph(QSGNode *, QQuickWindow *window) Q_DECL_OVERRIDE;
diff --git a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
index cbc64f41..a104df54 100644
--- a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
+++ b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp
@@ -350,10 +350,10 @@ void QGeoRouteReplyOsm::networkReplyFinished()
int status = object.value(QStringLiteral("status")).toDouble();
QString statusMessage = object.value(QStringLiteral("status_message")).toString();
- // status code is 0 in case of success
+ // status code 0 or 200 are case of success
// status code is 207 if no route was found
// an error occurred when trying to find a route
- if (0 != status) {
+ if (0 != status && 200 != status) {
setError(QGeoRouteReply::UnknownError, statusMessage);
m_reply->deleteLater();
m_reply = 0;
diff --git a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java
index 4723a805..43767f0e 100644
--- a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java
+++ b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java
@@ -179,6 +179,58 @@ public class QtPositioning implements LocationListener
return false;
}
+
+ static private void addActiveListener(QtPositioning listener, String provider)
+ {
+ int androidClassKey = listener.nativeClassReference;
+ //start update thread
+ listener.setActiveLooper(true);
+
+ if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) {
+ removeActiveListener(androidClassKey);
+ }
+
+ locationManager.requestSingleUpdate(provider,
+ listener,
+ listener.looper());
+
+ runningListeners.put(androidClassKey, listener);
+ }
+
+
+ static private void addActiveListener(QtPositioning listener, String provider, long minTime, float minDistance)
+ {
+ int androidClassKey = listener.nativeClassReference;
+ //start update thread
+ listener.setActiveLooper(true);
+
+ if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) {
+ removeActiveListener(androidClassKey);
+ }
+
+ locationManager.requestLocationUpdates(provider,
+ minTime, minDistance,
+ listener,
+ listener.looper());
+
+ runningListeners.put(androidClassKey, listener);
+ }
+
+
+ static private void removeActiveListener(QtPositioning listener)
+ {
+ removeActiveListener(listener.nativeClassReference);
+ }
+
+
+ static private void removeActiveListener(int androidClassKey)
+ {
+ QtPositioning listener = runningListeners.remove(androidClassKey);
+ locationManager.removeUpdates(listener);
+ listener.setActiveLooper(false);
+ }
+
+
static public int startUpdates(int androidClassKey, int locationProvider, int updateInterval)
{
synchronized (m_syncObject) {
@@ -188,8 +240,6 @@ public class QtPositioning implements LocationListener
positioningListener.nativeClassReference = androidClassKey;
positioningListener.expectedProviders = locationProvider;
positioningListener.isSatelliteUpdate = false;
- //start update thread
- positioningListener.setActiveLooper(true);
if (updateInterval == 0)
updateInterval = 1000; //don't update more often than once per second
@@ -198,10 +248,9 @@ public class QtPositioning implements LocationListener
if ((locationProvider & QT_GPS_PROVIDER) > 0) {
Log.d(TAG, "Regular updates using GPS " + updateInterval);
try {
- locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
- updateInterval, 0,
- positioningListener,
- positioningListener.looper());
+ addActiveListener(positioningListener,
+ LocationManager.GPS_PROVIDER,
+ updateInterval, 0);
} catch (SecurityException se) {
se.printStackTrace();
exceptionOccurred = true;
@@ -211,18 +260,16 @@ public class QtPositioning implements LocationListener
if ((locationProvider & QT_NETWORK_PROVIDER) > 0) {
Log.d(TAG, "Regular updates using network " + updateInterval);
try {
- locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
- updateInterval, 0,
- positioningListener,
- positioningListener.looper());
+ addActiveListener(positioningListener,
+ LocationManager.NETWORK_PROVIDER,
+ updateInterval, 0);
} catch (SecurityException se) {
se.printStackTrace();
exceptionOccurred = true;
}
}
if (exceptionOccurred) {
- positioningListener.setActiveLooper(false);
- locationManager.removeUpdates(positioningListener);
+ removeActiveListener(positioningListener);
return QT_ACCESS_ERROR;
}
@@ -231,7 +278,6 @@ public class QtPositioning implements LocationListener
return QT_CLOSED_ERROR;
}
- runningListeners.put(androidClassKey, positioningListener);
} catch(Exception e) {
e.printStackTrace();
return QT_POSITION_UNKNOWN_SOURCE_ERROR;
@@ -246,9 +292,7 @@ public class QtPositioning implements LocationListener
synchronized (m_syncObject) {
try {
Log.d(TAG, "Stopping updates");
- QtPositioning listener = runningListeners.remove(androidClassKey);
- locationManager.removeUpdates(listener);
- listener.setActiveLooper(false);
+ removeActiveListener(androidClassKey);
} catch(Exception e) {
e.printStackTrace();
return;
@@ -266,15 +310,11 @@ public class QtPositioning implements LocationListener
positioningListener.isSingleUpdate = true;
positioningListener.expectedProviders = locationProvider;
positioningListener.isSatelliteUpdate = false;
- //start update thread
- positioningListener.setActiveLooper(true);
if ((locationProvider & QT_GPS_PROVIDER) > 0) {
Log.d(TAG, "Single update using GPS");
try {
- locationManager.requestSingleUpdate(LocationManager.GPS_PROVIDER,
- positioningListener,
- positioningListener.looper());
+ addActiveListener(positioningListener, LocationManager.GPS_PROVIDER);
} catch (SecurityException se) {
se.printStackTrace();
exceptionOccurred = true;
@@ -284,17 +324,14 @@ public class QtPositioning implements LocationListener
if ((locationProvider & QT_NETWORK_PROVIDER) > 0) {
Log.d(TAG, "Single update using network");
try {
- locationManager.requestSingleUpdate(LocationManager.NETWORK_PROVIDER,
- positioningListener,
- positioningListener.looper());
+ addActiveListener(positioningListener, LocationManager.NETWORK_PROVIDER);
} catch (SecurityException se) {
se.printStackTrace();
exceptionOccurred = true;
}
}
if (exceptionOccurred) {
- positioningListener.setActiveLooper(false);
- locationManager.removeUpdates(positioningListener);
+ removeActiveListener(positioningListener);
return QT_ACCESS_ERROR;
}
@@ -304,7 +341,6 @@ public class QtPositioning implements LocationListener
return QT_CLOSED_ERROR;
}
- runningListeners.put(androidClassKey, positioningListener);
} catch(Exception e) {
e.printStackTrace();
return QT_POSITION_UNKNOWN_SOURCE_ERROR;
@@ -324,8 +360,6 @@ public class QtPositioning implements LocationListener
positioningListener.nativeClassReference = androidClassKey;
positioningListener.expectedProviders = 1; //always satellite provider
positioningListener.isSingleUpdate = isSingleRequest;
- //start update thread
- positioningListener.setActiveLooper(true);
if (updateInterval == 0)
updateInterval = 1000; //don't update more often than once per second
@@ -335,18 +369,15 @@ public class QtPositioning implements LocationListener
else
Log.d(TAG, "Regular updates for Satellites " + updateInterval);
try {
- locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
- updateInterval, 0,
- positioningListener,
- positioningListener.looper());
+ addActiveListener(positioningListener, LocationManager.GPS_PROVIDER,
+ updateInterval, 0);
} catch (SecurityException se) {
se.printStackTrace();
exceptionOccurred = true;
}
if (exceptionOccurred) {
- positioningListener.setActiveLooper(false);
- locationManager.removeUpdates(positioningListener);
+ removeActiveListener(positioningListener);
return QT_ACCESS_ERROR;
}
@@ -356,7 +387,6 @@ public class QtPositioning implements LocationListener
return QT_CLOSED_ERROR;
}
- runningListeners.put(androidClassKey, positioningListener);
} catch(Exception e) {
e.printStackTrace();
return QT_SATELLITE_UNKNOWN_SOURCE_ERROR;
diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp
index c9b209e8..1d1a6f4f 100644
--- a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp
+++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp
@@ -42,6 +42,7 @@
#include <QtSerialPort/qserialport.h>
#include <QtSerialPort/qserialportinfo.h>
#include <QtCore/qloggingcategory.h>
+#include <QSet>
Q_LOGGING_CATEGORY(lcSerial, "qt.positioning.serialnmea")
@@ -70,16 +71,13 @@ NmeaSource::NmeaSource(QObject *parent)
}
// Try to find a well-known device.
+ QSet<int> supportedDevices;
+ supportedDevices << 0x67b; // GlobalSat (BU-353S4 and probably others)
+ supportedDevices << 0xe8d; // Qstarz MTK II
QString portName;
- for (int i = 0; i < ports.count(); ++i) {
- const QString candidatePortName = ports[i].portName();
- bool acceptThis = false;
-
- // GlobalSat (BU-353S4 and probably others)
- acceptThis |= ports[i].hasVendorIdentifier() && ports[i].vendorIdentifier() == 0x67b;
-
- if (acceptThis) {
- portName = candidatePortName;
+ foreach (const QSerialPortInfo& port, ports) {
+ if (port.hasVendorIdentifier() && supportedDevices.contains(port.vendorIdentifier())) {
+ portName = port.portName();
break;
}
}
diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
index 4e70cc07..5dbbacb5 100644
--- a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
+++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
@@ -37,75 +37,119 @@
#include "qgeopositioninfosource_winrt_p.h"
#include <QCoreApplication>
+#include <QMutex>
+#include <qfunctions_winrt.h>
+#include <private/qeventdispatcher_winrt_p.h>
+#include <functional>
#include <windows.system.h>
#include <windows.devices.geolocation.h>
+#include <windows.foundation.h>
#include <windows.foundation.collections.h>
using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Devices::Geolocation;
using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::System;
+using namespace ABI::Windows::Foundation::Collections;
typedef ITypedEventHandler<Geolocator *, PositionChangedEventArgs *> GeoLocatorPositionHandler;
typedef ITypedEventHandler<Geolocator *, StatusChangedEventArgs *> GeoLocatorStatusHandler;
+typedef IAsyncOperationCompletedHandler<Geoposition*> PositionHandler;
+#if _MSC_VER >= 1900
+typedef IAsyncOperationCompletedHandler<GeolocationAccessStatus> AccessHandler;
+#endif
QT_BEGIN_NAMESPACE
-QGeoPositionInfoSourceWinrt::QGeoPositionInfoSourceWinrt(QObject *parent)
+Q_DECLARE_METATYPE(QGeoPositionInfo)
+
+class QGeoPositionInfoSourceWinRTPrivate {
+public:
+ ComPtr<IGeolocator> locator;
+ QTimer periodicTimer;
+ QTimer singleUpdateTimer;
+ QGeoPositionInfo lastPosition;
+ QGeoPositionInfoSource::Error positionError;
+ EventRegistrationToken statusToken;
+ EventRegistrationToken positionToken;
+ QMutex mutex;
+ bool updatesOngoing;
+};
+
+
+QGeoPositionInfoSourceWinRT::QGeoPositionInfoSourceWinRT(QObject *parent)
: QGeoPositionInfoSource(parent)
- , m_positionError(QGeoPositionInfoSource::NoError)
- , m_updatesOngoing(false)
+ , d_ptr(new QGeoPositionInfoSourceWinRTPrivate)
{
- HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(),
- &m_locator);
+ Q_D(QGeoPositionInfoSourceWinRT);
+ d->positionError = QGeoPositionInfoSource::NoError;
+ d->updatesOngoing = false;
+
+ qRegisterMetaType<QGeoPositionInfo>();
+
+ requestAccess();
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(),
+ &d->locator);
+ RETURN_HR_IF_FAILED("Could not initialize native location services.");
+
+ // StatusChanged throws an exception on Windows 8.1
+#if _MSC_VER >= 1900
+ hr = d->locator->add_StatusChanged(Callback<GeoLocatorStatusHandler>(this,
+ &QGeoPositionInfoSourceWinRT::onStatusChanged).Get(),
+ &d->statusToken);
+ RETURN_HR_IF_FAILED("Could not add status callback.");
+#endif
- if (FAILED(hr)) {
- setError(QGeoPositionInfoSource::UnknownSourceError);
- qErrnoWarning(hr, "Could not initialize native location services");
- return;
- }
+ hr = d->locator->put_ReportInterval(1000);
+ RETURN_HR_IF_FAILED("Could not initialize report interval.");
- hr = m_locator->put_ReportInterval(minimumUpdateInterval());
- if (FAILED(hr)) {
- setError(QGeoPositionInfoSource::UnknownSourceError);
- qErrnoWarning(hr, "Could not initialize report interval");
- return;
- }
- hr = m_locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_High);
+ return hr;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+
+ hr = d->locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_Default);
if (FAILED(hr)) {
setError(QGeoPositionInfoSource::UnknownSourceError);
- qErrnoWarning(hr, "Could not initialize desired accuracy");
+ qErrnoWarning(hr, "Could not initialize desired accuracy.");
return;
}
- m_positionToken.value = 0;
+ d->positionToken.value = 0;
- m_periodicTimer.setSingleShot(true);
- m_periodicTimer.setInterval(minimumUpdateInterval());
- connect(&m_periodicTimer, SIGNAL(timeout()), this, SLOT(virtualPositionUpdate()));
+ d->periodicTimer.setSingleShot(true);
+ d->periodicTimer.setInterval(minimumUpdateInterval());
+ connect(&d->periodicTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::virtualPositionUpdate);
- m_singleUpdateTimer.setSingleShot(true);
- connect(&m_singleUpdateTimer, SIGNAL(timeout()), this, SLOT(singleUpdateTimeOut()));
+ d->singleUpdateTimer.setSingleShot(true);
+ connect(&d->singleUpdateTimer, &QTimer::timeout, this, &QGeoPositionInfoSourceWinRT::singleUpdateTimeOut);
setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods);
+
+ connect(this, &QGeoPositionInfoSourceWinRT::nativePositionUpdate, this, &QGeoPositionInfoSourceWinRT::updateSynchronized);
}
-QGeoPositionInfoSourceWinrt::~QGeoPositionInfoSourceWinrt()
+QGeoPositionInfoSourceWinRT::~QGeoPositionInfoSourceWinRT()
{
}
-QGeoPositionInfo QGeoPositionInfoSourceWinrt::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
+QGeoPositionInfo QGeoPositionInfoSourceWinRT::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
{
+ Q_D(const QGeoPositionInfoSourceWinRT);
Q_UNUSED(fromSatellitePositioningMethodsOnly)
- return m_lastPosition;
+ return d->lastPosition;
}
-QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinrt::supportedPositioningMethods() const
+QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinRT::supportedPositioningMethods() const
{
+ Q_D(const QGeoPositionInfoSourceWinRT);
+
PositionStatus status;
- HRESULT hr = m_locator->get_LocationStatus(&status);
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, &status]() {
+ HRESULT hr = d->locator->get_LocationStatus(&status);
+ return hr;
+ });
if (FAILED(hr))
return QGeoPositionInfoSource::NoPositioningMethods;
@@ -119,88 +163,94 @@ QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceWinrt::supporte
return QGeoPositionInfoSource::AllPositioningMethods;
}
-void QGeoPositionInfoSourceWinrt::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods)
+void QGeoPositionInfoSourceWinRT::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods)
{
+ Q_D(QGeoPositionInfoSourceWinRT);
+
PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods();
QGeoPositionInfoSource::setPreferredPositioningMethods(methods);
if (previousPreferredPositioningMethods == preferredPositioningMethods())
return;
- bool needsRestart = m_positionToken.value != 0;
+ bool needsRestart = d->positionToken.value != 0;
if (needsRestart)
stopHandler();
- HRESULT hr;
- if (methods & PositioningMethod::SatellitePositioningMethods)
- hr = m_locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_High);
- else
- hr = m_locator->put_DesiredAccuracy(PositionAccuracy::PositionAccuracy_Default);
-
- if (FAILED(hr)) {
- qErrnoWarning(hr, "Could not set positioning accuracy");
- return;
- }
+ PositionAccuracy acc = methods & PositioningMethod::SatellitePositioningMethods ?
+ PositionAccuracy::PositionAccuracy_High :
+ PositionAccuracy::PositionAccuracy_Default;
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([d, acc]() {
+ HRESULT hr = d->locator->put_DesiredAccuracy(acc);
+ return hr;
+ });
+ RETURN_VOID_IF_FAILED("Could not set positioning accuracy.");
if (needsRestart)
startHandler();
}
-void QGeoPositionInfoSourceWinrt::setUpdateInterval(int msec)
+void QGeoPositionInfoSourceWinRT::setUpdateInterval(int msec)
{
- // Windows Phone does not support 0 interval
-#ifdef Q_OS_WINPHONE
+ 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.
if (msec != 0 && msec < minimumUpdateInterval())
msec = minimumUpdateInterval();
- HRESULT hr = m_locator->put_ReportInterval(msec);
+ HRESULT hr = d->locator->put_ReportInterval(msec);
if (FAILED(hr)) {
setError(QGeoPositionInfoSource::UnknownSourceError);
qErrnoWarning(hr, "Failed to set update interval");
return;
}
- if (msec != 0)
- m_periodicTimer.setInterval(msec);
- else
- m_periodicTimer.setInterval(minimumUpdateInterval());
+
+ d->periodicTimer.setInterval(qMax(msec, minimumUpdateInterval()));
QGeoPositionInfoSource::setUpdateInterval(msec);
}
-int QGeoPositionInfoSourceWinrt::minimumUpdateInterval() const
+int QGeoPositionInfoSourceWinRT::minimumUpdateInterval() const
{
// We use one second to reduce potential timer events
// in case the platform itself stops reporting
return 1000;
}
-void QGeoPositionInfoSourceWinrt::startUpdates()
+void QGeoPositionInfoSourceWinRT::startUpdates()
{
- if (m_updatesOngoing)
+ Q_D(QGeoPositionInfoSourceWinRT);
+
+ if (d->updatesOngoing)
return;
if (!startHandler())
return;
- m_updatesOngoing = true;
- m_periodicTimer.start();
+ d->updatesOngoing = true;
+ d->periodicTimer.start();
}
-void QGeoPositionInfoSourceWinrt::stopUpdates()
+void QGeoPositionInfoSourceWinRT::stopUpdates()
{
+ Q_D(QGeoPositionInfoSourceWinRT);
+
stopHandler();
- m_updatesOngoing = false;
- m_periodicTimer.stop();
+ d->updatesOngoing = false;
+ d->periodicTimer.stop();
}
-bool QGeoPositionInfoSourceWinrt::startHandler()
+bool QGeoPositionInfoSourceWinRT::startHandler()
{
+ Q_D(QGeoPositionInfoSourceWinRT);
+
// Check if already attached
- if (m_positionToken.value != 0)
+ if (d->positionToken.value != 0)
return true;
if (preferredPositioningMethods() == QGeoPositionInfoSource::NoPositioningMethods) {
@@ -208,31 +258,49 @@ bool QGeoPositionInfoSourceWinrt::startHandler()
return false;
}
- if (!checkNativeState())
+ if (!requestAccess() || !checkNativeState())
return false;
- HRESULT hr = m_locator->add_PositionChanged(Callback<GeoLocatorPositionHandler>(this,
- &QGeoPositionInfoSourceWinrt::onPositionChanged).Get(),
- &m_positionToken);
+ HRESULT hr = QEventDispatcherWinRT::runOnXamlThread([this, d]() {
+ HRESULT hr;
+ // We need to call this at least once on Windows 10 Mobile.
+ // Unfortunately this operation does not have a completion handler
+ // registered. That could have helped in the single update case
+ ComPtr<IAsyncOperation<Geoposition*>> op;
+ hr = d->locator->GetGeopositionAsync(&op);
+
+ hr = d->locator->add_PositionChanged(Callback<GeoLocatorPositionHandler>(this,
+ &QGeoPositionInfoSourceWinRT::onPositionChanged).Get(),
+ &d->positionToken);
+ return hr;
+ });
if (FAILED(hr)) {
setError(QGeoPositionInfoSource::UnknownSourceError);
qErrnoWarning(hr, "Could not add position handler");
return false;
}
+
return true;
}
-void QGeoPositionInfoSourceWinrt::stopHandler()
+void QGeoPositionInfoSourceWinRT::stopHandler()
{
- if (!m_positionToken.value)
+ Q_D(QGeoPositionInfoSourceWinRT);
+
+ if (!d->positionToken.value)
return;
- m_locator->remove_PositionChanged(m_positionToken);
- m_positionToken.value = 0;
+ QEventDispatcherWinRT::runOnXamlThread([d]() {
+ d->locator->remove_PositionChanged(d->positionToken);
+ return S_OK;
+ });
+ d->positionToken.value = 0;
}
-void QGeoPositionInfoSourceWinrt::requestUpdate(int timeout)
+void QGeoPositionInfoSourceWinRT::requestUpdate(int timeout)
{
+ Q_D(QGeoPositionInfoSourceWinRT);
+
if (timeout != 0 && timeout < minimumUpdateInterval()) {
emit updateTimeout();
return;
@@ -242,11 +310,14 @@ void QGeoPositionInfoSourceWinrt::requestUpdate(int timeout)
timeout = 2*60*1000; // Maximum time for cold start (see Android)
startHandler();
- m_singleUpdateTimer.start(timeout);
+ d->singleUpdateTimer.start(timeout);
}
-void QGeoPositionInfoSourceWinrt::virtualPositionUpdate()
+void QGeoPositionInfoSourceWinRT::virtualPositionUpdate()
{
+ Q_D(QGeoPositionInfoSourceWinRT);
+ QMutexLocker locker(&d->mutex);
+
// Need to check if services are still running and ok
if (!checkNativeState()) {
stopUpdates();
@@ -258,39 +329,69 @@ void QGeoPositionInfoSourceWinrt::virtualPositionUpdate()
// between backends.
// This only applies to the periodic timer, not for single requests
// We can only do this if we received a valid position before
- if (m_lastPosition.isValid()) {
- QGeoPositionInfo sent = m_lastPosition;
+ if (d->lastPosition.isValid()) {
+ QGeoPositionInfo sent = d->lastPosition;
sent.setTimestamp(QDateTime::currentDateTime());
- m_lastPosition = sent;
+ d->lastPosition = sent;
emit positionUpdated(sent);
}
- m_periodicTimer.start();
+ d->periodicTimer.start();
}
-void QGeoPositionInfoSourceWinrt::singleUpdateTimeOut()
+void QGeoPositionInfoSourceWinRT::singleUpdateTimeOut()
{
- emit updateTimeout();
- if (!m_updatesOngoing)
+ Q_D(QGeoPositionInfoSourceWinRT);
+ QMutexLocker locker(&d->mutex);
+
+ if (d->singleUpdateTimer.isActive()) {
+ emit updateTimeout();
+ if (!d->updatesOngoing)
+ stopHandler();
+ }
+}
+
+void QGeoPositionInfoSourceWinRT::updateSynchronized(QGeoPositionInfo currentInfo)
+{
+ Q_D(QGeoPositionInfoSourceWinRT);
+ QMutexLocker locker(&d->mutex);
+
+ d->periodicTimer.stop();
+ d->lastPosition = currentInfo;
+
+ if (d->updatesOngoing)
+ d->periodicTimer.start();
+
+ if (d->singleUpdateTimer.isActive()) {
+ d->singleUpdateTimer.stop();
+ if (!d->updatesOngoing)
stopHandler();
+ }
+
+ emit positionUpdated(currentInfo);
}
-QGeoPositionInfoSource::Error QGeoPositionInfoSourceWinrt::error() const
+QGeoPositionInfoSource::Error QGeoPositionInfoSourceWinRT::error() const
{
- return m_positionError;
+ Q_D(const QGeoPositionInfoSourceWinRT);
+ return d->positionError;
}
-void QGeoPositionInfoSourceWinrt::setError(QGeoPositionInfoSource::Error positionError)
+void QGeoPositionInfoSourceWinRT::setError(QGeoPositionInfoSource::Error positionError)
{
- if (positionError == m_positionError)
+ Q_D(QGeoPositionInfoSourceWinRT);
+
+ if (positionError == d->positionError)
return;
- m_positionError = positionError;
+ d->positionError = positionError;
emit QGeoPositionInfoSource::error(positionError);
}
-bool QGeoPositionInfoSourceWinrt::checkNativeState()
+bool QGeoPositionInfoSourceWinRT::checkNativeState()
{
+ Q_D(QGeoPositionInfoSourceWinRT);
+
PositionStatus status;
- HRESULT hr = m_locator->get_LocationStatus(&status);
+ HRESULT hr = d->locator->get_LocationStatus(&status);
if (FAILED(hr)) {
setError(QGeoPositionInfoSource::UnknownSourceError);
qErrnoWarning(hr, "Could not query status");
@@ -314,17 +415,14 @@ bool QGeoPositionInfoSourceWinrt::checkNativeState()
return result;
}
-HRESULT QGeoPositionInfoSourceWinrt::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args)
+HRESULT QGeoPositionInfoSourceWinRT::onPositionChanged(IGeolocator *locator, IPositionChangedEventArgs *args)
{
Q_UNUSED(locator);
- m_periodicTimer.stop();
-
HRESULT hr;
ComPtr<IGeoposition> pos;
hr = args->get_Position(&pos);
- if (FAILED(hr))
- qErrnoWarning(hr, "Could not access position object");
+ RETURN_HR_IF_FAILED("Could not access position object.");
QGeoPositionInfo currentInfo;
@@ -378,19 +476,48 @@ HRESULT QGeoPositionInfoSourceWinrt::onPositionChanged(IGeolocator *locator, IPo
currentInfo.setTimestamp(QDateTime::currentDateTime());
- m_lastPosition = currentInfo;
+ emit nativePositionUpdate(currentInfo);
- if (m_updatesOngoing)
- m_periodicTimer.start();
-
- if (m_singleUpdateTimer.isActive()) {
- m_singleUpdateTimer.stop();
- if (!m_updatesOngoing)
- stopHandler();
- }
+ return S_OK;
+}
- emit positionUpdated(currentInfo);
+HRESULT QGeoPositionInfoSourceWinRT::onStatusChanged(IGeolocator*, IStatusChangedEventArgs *args)
+{
+ PositionStatus st;
+ args->get_Status(&st);
return S_OK;
}
+bool QGeoPositionInfoSourceWinRT::requestAccess() const
+{
+#if _MSC_VER >= 1900
+ static GeolocationAccessStatus accessStatus = GeolocationAccessStatus_Unspecified;
+ static ComPtr<IGeolocatorStatics> statics;
+
+ if (accessStatus == GeolocationAccessStatus_Allowed)
+ return true;
+ else if (accessStatus == GeolocationAccessStatus_Denied)
+ return false;
+
+ ComPtr<IAsyncOperation<GeolocationAccessStatus>> op;
+ HRESULT hr;
+ hr = QEventDispatcherWinRT::runOnXamlThread([&op]() {
+ HRESULT hr;
+ hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Geolocation_Geolocator).Get(),
+ IID_PPV_ARGS(&statics));
+ RETURN_HR_IF_FAILED("Could not access Geolocation Statics.");
+
+ hr = statics->RequestAccessAsync(&op);
+ return hr;
+ });
+ Q_ASSERT_SUCCEEDED(hr);
+
+ // We cannot wait inside the XamlThread as that would deadlock
+ QWinRTFunctions::await(op, &accessStatus);
+ return accessStatus == GeolocationAccessStatus_Allowed;
+#else // _MSC_VER < 1900
+ return true;
+#endif // _MSC_VER < 1900
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h
index 45c22847..b8820dd2 100644
--- a/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h
+++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt_p.h
@@ -70,12 +70,14 @@ namespace ABI {
QT_BEGIN_NAMESPACE
-class QGeoPositionInfoSourceWinrt : public QGeoPositionInfoSource
+class QGeoPositionInfoSourceWinRTPrivate;
+
+class QGeoPositionInfoSourceWinRT : public QGeoPositionInfoSource
{
Q_OBJECT
public:
- QGeoPositionInfoSourceWinrt(QObject *parent = 0);
- ~QGeoPositionInfoSourceWinrt();
+ QGeoPositionInfoSourceWinRT(QObject *parent = 0);
+ ~QGeoPositionInfoSourceWinRT();
QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const;
PositioningMethods supportedPositioningMethods() const;
@@ -89,6 +91,12 @@ 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);
public slots:
void startUpdates();
void stopUpdates();
@@ -99,23 +107,16 @@ private slots:
void stopHandler();
void virtualPositionUpdate();
void singleUpdateTimeOut();
+ void updateSynchronized(const QGeoPositionInfo info);
private:
bool startHandler();
- Q_DISABLE_COPY(QGeoPositionInfoSourceWinrt)
+ Q_DISABLE_COPY(QGeoPositionInfoSourceWinRT)
void setError(QGeoPositionInfoSource::Error positionError);
bool checkNativeState();
- Microsoft::WRL::ComPtr<ABI::Windows::Devices::Geolocation::IGeolocator> m_locator;
- EventRegistrationToken m_positionToken;
-
- QGeoPositionInfo m_lastPosition;
- QGeoPositionInfoSource::Error m_positionError;
-
- //EventRegistrationToken m_StatusToken;
- QTimer m_periodicTimer;
- QTimer m_singleUpdateTimer;
- bool m_updatesOngoing;
+ QScopedPointer<QGeoPositionInfoSourceWinRTPrivate> d_ptr;
+ Q_DECLARE_PRIVATE(QGeoPositionInfoSourceWinRT)
};
QT_END_NAMESPACE
diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp
index 0f9a21f2..81656c21 100644
--- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp
+++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.cpp
@@ -37,18 +37,18 @@
#include "qgeopositioninfosourcefactory_winrt.h"
#include "qgeopositioninfosource_winrt_p.h"
-QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinrt::positionInfoSource(QObject *parent)
+QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryWinRT::positionInfoSource(QObject *parent)
{
- return new QGeoPositionInfoSourceWinrt(parent);
+ return new QGeoPositionInfoSourceWinRT(parent);
}
-QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryWinrt::satelliteInfoSource(QObject *parent)
+QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryWinRT::satelliteInfoSource(QObject *parent)
{
Q_UNUSED(parent);
return 0;
}
-QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryWinrt::areaMonitor(QObject *parent)
+QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryWinRT::areaMonitor(QObject *parent)
{
Q_UNUSED(parent);
return 0;
diff --git a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h
index 0627abc4..46cd3853 100644
--- a/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h
+++ b/src/plugins/position/winrt/qgeopositioninfosourcefactory_winrt.h
@@ -42,7 +42,7 @@
QT_BEGIN_NAMESPACE
-class QGeoPositionInfoSourceFactoryWinrt : public QObject, public QGeoPositionInfoSourceFactory
+class QGeoPositionInfoSourceFactoryWinRT : public QObject, public QGeoPositionInfoSourceFactory
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0"
diff --git a/src/plugins/position/winrt/winrt.pro b/src/plugins/position/winrt/winrt.pro
index 228a9e78..c58c6c18 100644
--- a/src/plugins/position/winrt/winrt.pro
+++ b/src/plugins/position/winrt/winrt.pro
@@ -1,8 +1,8 @@
TARGET = qtposition_winrt
-QT = core positioning
+QT = core core-private positioning
PLUGIN_TYPE = position
-PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryWinrt
+PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryWinRT
load(qt_plugin)
SOURCES += qgeopositioninfosource_winrt.cpp \
diff --git a/src/positioning/doc/src/examples/weatherinfo.qdoc b/src/positioning/doc/src/examples/weatherinfo.qdoc
index e32127d4..3db6fcbf 100644
--- a/src/positioning/doc/src/examples/weatherinfo.qdoc
+++ b/src/positioning/doc/src/examples/weatherinfo.qdoc
@@ -45,6 +45,8 @@
\include examples-run.qdocinc
+ The example uses weather data provided by \l http://www.openweathermap.org.
+
The key part of this example is the application's data model, contained
in the WeatherData and AppModel classes. WeatherData represents the weather
information taken from the HTTP service. It is a simple data class, but we
diff --git a/src/positioning/qpositioningglobal_p.h b/src/positioning/qpositioningglobal_p.h
index 653fcf77..747e450e 100644
--- a/src/positioning/qpositioningglobal_p.h
+++ b/src/positioning/qpositioningglobal_p.h
@@ -39,6 +39,17 @@
#ifndef QPOSITIONINGGLOBAL_P_H
#define QPOSITIONINGGLOBAL_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 "qpositioningglobal.h"
QT_BEGIN_NAMESPACE
diff --git a/tests/auto/declarative_geoshape/tst_locationsingleton.qml b/tests/auto/declarative_geoshape/tst_locationsingleton.qml
index ce5b7c4b..4b0a55ae 100644
--- a/tests/auto/declarative_geoshape/tst_locationsingleton.qml
+++ b/tests/auto/declarative_geoshape/tst_locationsingleton.qml
@@ -29,6 +29,7 @@
import QtQuick 2.0
import QtTest 1.0
import QtPositioning 5.2
+import QtLocation 5.5
Item {
id: testCase
@@ -186,4 +187,62 @@ Item {
verify(rectangle.isValid)
}
}
+
+
+ MapPolyline {
+ id: mapPolyline
+ path: [
+ { latitude: -27, longitude: 153.0 },
+ { latitude: -27, longitude: 154.1 },
+ { latitude: -28, longitude: 153.5 },
+ { latitude: -29, longitude: 153.5 }
+ ]
+ }
+
+ TestCase {
+ name: "MapPolyline path"
+ function test_path_operations() {
+ compare(mapPolyline.path[1].latitude, -27)
+ compare(mapPolyline.path[1].longitude, 154.1)
+ compare(mapPolyline.coordinateAt(1), QtPositioning.coordinate(27, 154.1))
+ compare(mapPolyline.path.length, mapPolyline.pathLength())
+
+ mapPolyline.removeCoordinate(1);
+ compare(mapPolyline.path[1].latitude, -28)
+ compare(mapPolyline.path[1].longitude, 153.5)
+ compare(mapPolyline.coordinateAt(1), QtPositioning.coordinate(-28, 153.5))
+ compare(mapPolyline.path.length, mapPolyline.pathLength())
+
+ mapPolyline.addCoordinate(QtPositioning.coordinate(30, 153.1))
+ compare(mapPolyline.path[mapPolyline.path.length-1].latitude, 30)
+ compare(mapPolyline.path[mapPolyline.path.length-1].longitude, 153.1)
+ compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(30, 153.1)), true)
+ compare(mapPolyline.path.length, mapPolyline.pathLength())
+
+ mapPolyline.removeCoordinate(QtPositioning.coordinate(30, 153.1))
+ compare(mapPolyline.path[mapPolyline.path.length-1].latitude, -29)
+ compare(mapPolyline.path[mapPolyline.path.length-1].longitude, 153.5)
+ compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(30, 153.1)), false)
+ compare(mapPolyline.path.length, mapPolyline.pathLength())
+
+ mapPolyline.insertCoordinate(2, QtPositioning.coordinate(35, 153.1))
+ compare(mapPolyline.path[2].latitude, 35)
+ compare(mapPolyline.path[2].longitude, 153.1)
+ compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), true)
+ compare(mapPolyline.path.length, mapPolyline.pathLength())
+
+ mapPolyline.replaceCoordinate(2, QtPositioning.coordinate(45, 150.1))
+ compare(mapPolyline.path[2].latitude, 45)
+ compare(mapPolyline.path[2].longitude, 150.1)
+ compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), false)
+ compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(45, 150.1)), true)
+ compare(mapPolyline.path.length, mapPolyline.pathLength())
+
+ mapPolyline.insertCoordinate(2, QtPositioning.coordinate(35, 153.1))
+ compare(mapPolyline.coordinateAt(2).latitude, 35)
+ compare(mapPolyline.coordinateAt(2).longitude, 153.1)
+ compare(mapPolyline.containsCoordinate(QtPositioning.coordinate(35, 153.1)), true)
+ compare(mapPolyline.path.length, mapPolyline.pathLength())
+ }
+ }
}