From 3faac8cc62a9101902baebbda348e7da9921cce4 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Fri, 4 Dec 2015 13:03:09 +0100 Subject: Fix broken weatherinfo example openweathermap.org requires an appid these days. The free plan permits usage for commercial and non-commercial cases. Task-number: QTBUG-49772 Change-Id: I28be90709b4879df515346e03372d494d94a4f01 Reviewed-by: Maurice Kalinowski --- src/positioning/doc/src/examples/weatherinfo.qdoc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') 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 -- cgit v1.2.1 From e70502b14a6b78067c18a4645570c077453c34ea Mon Sep 17 00:00:00 2001 From: Michal Klocek Date: Wed, 18 Nov 2015 19:21:21 +0100 Subject: Add clearData() call to map qml api Add clearData call to clear texture, memory and disk cache. Update mapviewer example and add "prefetchData" and "clearData" to Tools menu. Task-number: QTBUG-47292 Change-Id: Ifc71a3652688d1403f5b011ef231b59381c17ee3 Reviewed-by: Harald Meyer Reviewed-by: Alex Blasche --- src/imports/location/qdeclarativegeomap.cpp | 12 ++++++++++++ src/imports/location/qdeclarativegeomap_p.h | 1 + src/location/maps/qabstractgeotilecache_p.h | 1 + src/location/maps/qgeofiletilecache.cpp | 13 +++++++++++++ src/location/maps/qgeofiletilecache_p.h | 1 + src/location/maps/qgeomap.cpp | 5 +++++ src/location/maps/qgeomap_p.h | 2 ++ src/location/maps/qgeotiledmap.cpp | 6 ++++++ src/location/maps/qgeotiledmap_p.h | 1 + 9 files changed, 42 insertions(+) (limited to 'src') diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp index d9981b69..80208a9b 100644 --- a/src/imports/location/qdeclarativegeomap.cpp +++ b/src/imports/location/qdeclarativegeomap.cpp @@ -907,6 +907,18 @@ void QDeclarativeGeoMap::prefetchData() m_map->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 diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h index 22450ec1..fb36104a 100644 --- a/src/imports/location/qdeclarativegeomap_p.h +++ b/src/imports/location/qdeclarativegeomap_p.h @@ -127,6 +127,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/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 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 QGeoFileTileCache::get(const QGeoTileSpec &spec) { QSharedPointer 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 get(const QGeoTileSpec &spec) Q_DECL_OVERRIDE; diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index edc64839..c035f616 100644 --- a/src/location/maps/qgeomap.cpp +++ b/src/location/maps/qgeomap.cpp @@ -132,6 +132,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; -- cgit v1.2.1 From fda281b81730d0d41af09170e732b3d70c4cfff1 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 3 Dec 2015 19:34:04 +0100 Subject: WinRT: Refactor backend - Move members into private class to clean up the public backend. - Beware of the Xaml changes and switch thread where required. - Add updateSynchronized() slot to be able to start/stop timers properly. onPositionChanged is invoked from another thread, actually one not being created by QThread. Hence other singleShot mechanisms do not work either. - Rename classnames to properly spell WinRT. - Register QGeoPositionInfo to the metatype system like on other backends. Change-Id: Ic62beddff6d8542264a44ca3927ba7b692682c63 Reviewed-by: Oliver Wolff Reviewed-by: Alex Blasche --- .../winrt/qgeopositioninfosource_winrt.cpp | 327 ++++++++++++++------- .../winrt/qgeopositioninfosource_winrt_p.h | 29 +- .../winrt/qgeopositioninfosourcefactory_winrt.cpp | 8 +- .../winrt/qgeopositioninfosourcefactory_winrt.h | 2 +- src/plugins/position/winrt/winrt.pro | 2 +- 5 files changed, 248 insertions(+), 120 deletions(-) (limited to 'src') 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 +#include +#include +#include +#include #include #include +#include #include 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 GeoLocatorPositionHandler; typedef ITypedEventHandler GeoLocatorStatusHandler; +typedef IAsyncOperationCompletedHandler PositionHandler; +#if _MSC_VER >= 1900 +typedef IAsyncOperationCompletedHandler AccessHandler; +#endif QT_BEGIN_NAMESPACE -QGeoPositionInfoSourceWinrt::QGeoPositionInfoSourceWinrt(QObject *parent) +Q_DECLARE_METATYPE(QGeoPositionInfo) + +class QGeoPositionInfoSourceWinRTPrivate { +public: + ComPtr 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(); + + 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(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(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> op; + hr = d->locator->GetGeopositionAsync(&op); + + hr = d->locator->add_PositionChanged(Callback(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 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 statics; + + if (accessStatus == GeolocationAccessStatus_Allowed) + return true; + else if (accessStatus == GeolocationAccessStatus_Denied) + return false; + + ComPtr> 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 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 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..5595a3e6 100644 --- a/src/plugins/position/winrt/winrt.pro +++ b/src/plugins/position/winrt/winrt.pro @@ -1,5 +1,5 @@ TARGET = qtposition_winrt -QT = core positioning +QT = core core-private positioning PLUGIN_TYPE = position PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryWinrt -- cgit v1.2.1 From 6976c13e327bb739f44b650ac9998e2e56c910f1 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 9 Dec 2015 14:03:23 +0100 Subject: Fix static build This has been left out for previous renaming of WinRT related classes. Change-Id: Ic193501c70c3309659d5bf09c3ecf39879d390ba Reviewed-by: Alex Blasche --- src/plugins/position/winrt/winrt.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/position/winrt/winrt.pro b/src/plugins/position/winrt/winrt.pro index 5595a3e6..c58c6c18 100644 --- a/src/plugins/position/winrt/winrt.pro +++ b/src/plugins/position/winrt/winrt.pro @@ -2,7 +2,7 @@ TARGET = qtposition_winrt QT = core core-private positioning PLUGIN_TYPE = position -PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryWinrt +PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryWinRT load(qt_plugin) SOURCES += qgeopositioninfosource_winrt.cpp \ -- cgit v1.2.1 From d75c0469c05809a4c6ff85a4c78784b397cbfcc0 Mon Sep 17 00:00:00 2001 From: Harald Meyer Date: Wed, 2 Dec 2015 09:21:05 +0100 Subject: Added methods for modifying QDeclarativePolylineMapItem. Added the methods insertCoordinate(index, coordinate), replaceCoordinate(index, coordinate), removeCoordinate(index), pathLength(), coordinateAt(index) to the QDeclarativePolylineMapItem. Change-Id: I8b1f7e01cf814fe6fdb9f2da376793891514b5f0 Reviewed-by: Alex Blasche Reviewed-by: Laszlo Agocs --- .../location/qdeclarativepolylinemapitem.cpp | 117 ++++++++++++++++++++- .../location/qdeclarativepolylinemapitem_p.h | 6 ++ 2 files changed, 118 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp index 71a205d3..0708fe2d 100644 --- a/src/imports/location/qdeclarativepolylinemapitem.cpp +++ b/src/imports/location/qdeclarativepolylinemapitem.cpp @@ -534,7 +534,6 @@ void QDeclarativePolylineMapItem::setPath(const QJSValue &value) setPathFromGeoList(pathList); } - /*! \internal */ @@ -551,13 +550,26 @@ void QDeclarativePolylineMapItem::setPathFromGeoList(const QList } /*! - \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); @@ -567,6 +579,78 @@ void QDeclarativePolylineMapItem::addCoordinate(const QGeoCoordinate &coordinate emit pathChanged(); } +/*! + \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) @@ -575,7 +659,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) { @@ -590,6 +674,29 @@ void QDeclarativePolylineMapItem::removeCoordinate(const QGeoCoordinate &coordin emit pathChanged(); } +/*! + \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 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); -- cgit v1.2.1 From 51a775b51b320dd3913f2e6f29ea9360a559e814 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 15 Dec 2015 10:35:31 +0100 Subject: Add "We mean it." comment to qpositioningglobal_p.h. Fix warning: QtPositioning: WARNING: qtlocation/src/positioning/qpositioningglobal_p.h does not have the "We mean it." warning Change-Id: I72d276587e2d1476be3ec26f1e86d0aa9865ac65 Reviewed-by: Alex Blasche --- src/positioning/qpositioningglobal_p.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/positioning/qpositioningglobal_p.h b/src/positioning/qpositioningglobal_p.h index d3a10dae..04a5b18d 100644 --- a/src/positioning/qpositioningglobal_p.h +++ b/src/positioning/qpositioningglobal_p.h @@ -33,6 +33,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 -- cgit v1.2.1 From 5927f1ac4f8728e209bd0bbb1423ffb82dd6dbf6 Mon Sep 17 00:00:00 2001 From: Harald Meyer Date: Sun, 13 Dec 2015 14:43:23 +0100 Subject: Added support for Qstarz GPS tracker Added support for Qstarz tracker (with MTK II chipset) such as BT-Q818XT for instance. Change-Id: I937358a82ebce76ac1cdaf87458234f8045d11ad Reviewed-by: Alex Blasche --- .../qgeopositioninfosourcefactory_serialnmea.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp index 2b6b3ce6..a3f8ac98 100644 --- a/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp +++ b/src/plugins/position/serialnmea/qgeopositioninfosourcefactory_serialnmea.cpp @@ -36,6 +36,7 @@ #include #include #include +#include Q_LOGGING_CATEGORY(lcSerial, "qt.positioning.serialnmea") @@ -64,16 +65,13 @@ NmeaSource::NmeaSource(QObject *parent) } // Try to find a well-known device. + QSet 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; } } -- cgit v1.2.1 From 270b1edc441564b49084d467c7318294b8823fdc Mon Sep 17 00:00:00 2001 From: Joni Poikelin Date: Wed, 16 Dec 2015 17:00:24 +0200 Subject: Emit activeMapTypeChanged in QGeoMap as well Change-Id: I98bdcfbb57d3d597e23ecaf3bb862daa5a917f00 Reviewed-by: Alex Blasche --- src/location/maps/qgeomap.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index c035f616..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(); } -- cgit v1.2.1 From 9520c488b0a496baccf8d7037f949b8a5708a490 Mon Sep 17 00:00:00 2001 From: Harald Meyer Date: Sat, 19 Dec 2015 09:26:49 +0100 Subject: MapPolyline performance improvements Instead of copying the polyline geometry container object each loop twice in the contains() method the change copies the geometry only once (implicit sharing limits the copying to the container itself). Change-Id: Iee80fa6d49b7e81dea0364b6f9f28a3d2e608d22 Task-number: QTBUG-50060 Reviewed-by: Laszlo Agocs --- src/imports/location/qdeclarativepolylinemapitem.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp index 0708fe2d..280cbdbe 100644 --- a/src/imports/location/qdeclarativepolylinemapitem.cpp +++ b/src/imports/location/qdeclarativepolylinemapitem.cpp @@ -843,9 +843,10 @@ QSGNode *QDeclarativePolylineMapItem::updateMapItemPaintNode(QSGNode *oldNode, U bool QDeclarativePolylineMapItem::contains(const QPointF &point) const { + QVector 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; -- cgit v1.2.1 From cf6bf74b900db1efd2f2c6d51313505fade267ee Mon Sep 17 00:00:00 2001 From: Harald Meyer Date: Mon, 21 Dec 2015 09:51:42 +0100 Subject: Fixed wrong MapPolyline drawing if line point lies on map center This patch fixes a bug where the transformation from the source path to the screen points of a MapPolyline fails when a source path point lies exactly on the map's center geo coordinate. Change-Id: I5d13f418d3fbb650b927422861769f3e0ab18bee Reviewed-by: Laszlo Agocs --- src/imports/location/qdeclarativepolylinemapitem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp index 280cbdbe..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) { -- cgit v1.2.1 From 9969179a06c30b56d3d057aba127686b64ccd659 Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Mon, 4 Jan 2016 11:33:33 +0100 Subject: Fix OSM based routing The server changed the status code for a successful route retrieval to 200. Task-number: QTBUG-50240 Change-Id: I98aa444b9a10a69b6a357eb92f6b45d534b4e45d Reviewed-by: Michal Klocek Reviewed-by: Harald Meyer Reviewed-by: Laszlo Agocs --- src/plugins/geoservices/osm/qgeoroutereplyosm.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp index bca345fe..f704a714 100644 --- a/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp +++ b/src/plugins/geoservices/osm/qgeoroutereplyosm.cpp @@ -344,10 +344,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; -- cgit v1.2.1 From 24e50e40caaa2f2e057180b8ed8179795e605e2a Mon Sep 17 00:00:00 2001 From: Vyacheslav Koscheev Date: Fri, 22 Jan 2016 23:09:11 +0600 Subject: Fix endless location requesting This patch fixes the problem of lost positioning listeners, which was registered in LocationManager, but does not persist in the `runningListeners` collection. We can't call LocationManager.removeUpdates() for those listeners, that are not in `runningListeners` and that's why LocationManager never ends to update location for them. Listener can be registered in LocationManager and not added to `runningListeners` collection at least in the following cases: 1. `startUpdates()` was called when location providers was disabled in system. 2. `startUpdates()` was called twice, without `stopUpdates()` Change-Id: If6777677cbb6f2ad9107fe2ac8496b7cdbb2d8d4 Reviewed-by: Alex Blasche --- .../qt5/android/positioning/QtPositioning.java | 102 +++++++++++++-------- 1 file changed, 66 insertions(+), 36 deletions(-) (limited to 'src') 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 e67ffe12..44214f53 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 @@ -173,6 +173,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) { @@ -182,8 +234,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 @@ -192,10 +242,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; @@ -205,18 +254,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; } @@ -225,7 +272,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; @@ -240,9 +286,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; @@ -260,15 +304,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; @@ -278,17 +318,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; } @@ -298,7 +335,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; @@ -318,8 +354,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 @@ -329,18 +363,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; } @@ -350,7 +381,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; -- cgit v1.2.1