diff options
author | Michal Klocek <michal.klocek@theqtcompany.com> | 2016-07-28 19:21:35 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@theqtcompany.com> | 2016-07-28 19:21:47 +0200 |
commit | 1a1d2e3fff5856dc9d1283b510a9f325c6fb8a93 (patch) | |
tree | 2c16537e3321cde9ca9730f871f47ed32668e120 /src/plugins | |
parent | 4e1008b4ac1eea776585ca41a6a3db127cf500ff (diff) | |
parent | 75dd424e11964d8755abdb1b12b27a8479353b37 (diff) | |
download | qtlocation-1a1d2e3fff5856dc9d1283b510a9f325c6fb8a93.tar.gz |
Merge remote-tracking branch 'origin/5.6' into 5.7
Change-Id: I37542960aa091ab2074914a2cebb8c5114237a26
Diffstat (limited to 'src/plugins')
15 files changed, 877 insertions, 105 deletions
diff --git a/src/plugins/geoservices/osm/osm.pro b/src/plugins/geoservices/osm/osm.pro index e73c16d7..56f4cb33 100644 --- a/src/plugins/geoservices/osm/osm.pro +++ b/src/plugins/geoservices/osm/osm.pro @@ -14,7 +14,8 @@ HEADERS += \ qplacemanagerengineosm.h \ qplacesearchreplyosm.h \ qplacecategoriesreplyosm.h \ - qgeotiledmaposm.h + qgeotiledmaposm.h \ + qgeotileproviderosm.h SOURCES += \ qgeoserviceproviderpluginosm.cpp \ @@ -28,7 +29,8 @@ SOURCES += \ qplacemanagerengineosm.cpp \ qplacesearchreplyosm.cpp \ qplacecategoriesreplyosm.cpp \ - qgeotiledmaposm.cpp + qgeotiledmaposm.cpp \ + qgeotileproviderosm.cpp OTHER_FILES += \ diff --git a/src/plugins/geoservices/osm/qgeomapreplyosm.cpp b/src/plugins/geoservices/osm/qgeomapreplyosm.cpp index a4a62e7f..052ed351 100644 --- a/src/plugins/geoservices/osm/qgeomapreplyosm.cpp +++ b/src/plugins/geoservices/osm/qgeomapreplyosm.cpp @@ -41,12 +41,16 @@ #include <QtLocation/private/qgeotilespec_p.h> -QGeoMapReplyOsm::QGeoMapReplyOsm(QNetworkReply *reply, const QGeoTileSpec &spec, QObject *parent) +QGeoMapReplyOsm::QGeoMapReplyOsm(QNetworkReply *reply, + const QGeoTileSpec &spec, + const QString &imageFormat, + QObject *parent) : QGeoTiledMapReply(spec, parent), m_reply(reply) { connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished())); connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(networkReplyError(QNetworkReply::NetworkError))); + setMapImageFormat(imageFormat); } QGeoMapReplyOsm::~QGeoMapReplyOsm() @@ -75,18 +79,15 @@ void QGeoMapReplyOsm::networkReplyFinished() if (!m_reply) return; - if (m_reply->error() != QNetworkReply::NoError) + if (m_reply->error() != QNetworkReply::NoError) { + m_reply->deleteLater(); + m_reply = 0; return; + } QByteArray a = m_reply->readAll(); setMapImageData(a); - int mapId = tileSpec().mapId(); - if (mapId == 1 || mapId == 2) - setMapImageFormat(QStringLiteral("jpg")); - else - setMapImageFormat(QStringLiteral("png")); - setFinished(true); m_reply->deleteLater(); diff --git a/src/plugins/geoservices/osm/qgeomapreplyosm.h b/src/plugins/geoservices/osm/qgeomapreplyosm.h index 994e568a..804a0a24 100644 --- a/src/plugins/geoservices/osm/qgeomapreplyosm.h +++ b/src/plugins/geoservices/osm/qgeomapreplyosm.h @@ -40,6 +40,9 @@ #ifndef QGEOMAPREPLYOSM_H #define QGEOMAPREPLYOSM_H +#include "qgeotilefetcherosm.h" +#include "qgeotileproviderosm.h" + #include <QtNetwork/QNetworkReply> #include <QtLocation/private/qgeotiledmapreply_p.h> #include <QtCore/qpointer.h> @@ -51,7 +54,7 @@ class QGeoMapReplyOsm : public QGeoTiledMapReply Q_OBJECT public: - explicit QGeoMapReplyOsm(QNetworkReply *reply, const QGeoTileSpec &spec, QObject *parent = 0); + QGeoMapReplyOsm(QNetworkReply *reply, const QGeoTileSpec &spec, const QString &imageFormat, QObject *parent = 0); ~QGeoMapReplyOsm(); void abort(); diff --git a/src/plugins/geoservices/osm/qgeotiledmaposm.cpp b/src/plugins/geoservices/osm/qgeotiledmaposm.cpp index e0ec919e..f16e602a 100644 --- a/src/plugins/geoservices/osm/qgeotiledmaposm.cpp +++ b/src/plugins/geoservices/osm/qgeotiledmaposm.cpp @@ -39,14 +39,22 @@ #include "qgeotiledmaposm.h" #include "qgeotiledmappingmanagerengineosm.h" +#include "qgeotilefetcherosm.h" #include <QtLocation/private/qgeotilespec_p.h> QT_BEGIN_NAMESPACE QGeoTiledMapOsm::QGeoTiledMapOsm(QGeoTiledMappingManagerEngineOsm *engine, QObject *parent) -: QGeoTiledMap(engine, parent), m_mapId(-1), m_customCopyright(engine->customCopyright()) +: QGeoTiledMap(engine, parent), m_mapId(-1), m_engine(engine) { + // Needed because evaluateCopyrights() is only triggered if visible tiles change in the map. + // It fails the first time it gets called if providers aren't resolved, and subsequent calls + // to it will be skipped until visible tiles change. + // This connection makes sure the copyrights are evaluated when copyright data are ready regardless + // of what tiles are visible. + connect(qobject_cast<QGeoTileFetcherOsm *>(engine->tileFetcher()), &QGeoTileFetcherOsm::providerDataUpdated, + this, &QGeoTiledMapOsm::onProviderDataUpdated); } QGeoTiledMapOsm::~QGeoTiledMapOsm() @@ -62,32 +70,43 @@ void QGeoTiledMapOsm::evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles) if (tile.mapId() == m_mapId) return; + int providerId = tile.mapId() - 1; + if (providerId < 0 || providerId >= m_engine->providers().size() || !m_engine->providers().at(providerId)->isValid()) + return; + m_mapId = tile.mapId(); + onProviderDataUpdated(m_engine->providers().at(providerId)); +} - QString copyrights; - switch (m_mapId) { - case 1: - case 2: - // set attribution to Map Quest - copyrights = tr("Tiles Courtesy of <a href='http://www.mapquest.com/'>MapQuest</a><br/>Data © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"); - break; - case 3: - case 4: - case 5: - case 6: - case 7: - // set attribution to Thunder Forest - copyrights = tr("Maps © <a href='http://www.thunderforest.com/'>Thunderforest</a><br/>Data © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"); - break; - case 8: - copyrights = m_customCopyright; - break; - default: - // set attribution to OSM - copyrights = tr("© <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors"); +void QGeoTiledMapOsm::onProviderDataUpdated(const QGeoTileProviderOsm *provider) +{ + if (!provider->isResolved() || provider->mapType().mapId() != m_mapId) + return; + QString copyRights; + const QString mapCopy = provider->mapCopyRight(); + const QString dataCopy = provider->dataCopyRight(); + const QString styleCopy = provider->styleCopyRight(); + if (!mapCopy.isEmpty()) { + copyRights += QStringLiteral("Map © "); + copyRights += mapCopy; + } + if (!dataCopy.isEmpty()) { + if (!copyRights.isEmpty()) + copyRights += QStringLiteral("<br/>"); + copyRights += QStringLiteral("Data © "); + copyRights += dataCopy; } + if (!styleCopy.isEmpty()) { + if (!copyRights.isEmpty()) + copyRights += QStringLiteral("<br/>"); + copyRights += QStringLiteral("Style © "); + copyRights += styleCopy; + } + + if (copyRights.isEmpty() && provider->mapType().style() == QGeoMapType::CustomMap) + copyRights = m_engine->customCopyright(); - emit copyrightsChanged(copyrights); + emit copyrightsChanged(copyRights); } QT_END_NAMESPACE diff --git a/src/plugins/geoservices/osm/qgeotiledmaposm.h b/src/plugins/geoservices/osm/qgeotiledmaposm.h index 40d4e79b..cfc72948 100644 --- a/src/plugins/geoservices/osm/qgeotiledmaposm.h +++ b/src/plugins/geoservices/osm/qgeotiledmaposm.h @@ -40,6 +40,8 @@ #ifndef QGEOTILEDMAPOSM_H #define QGEOTILEDMAPOSM_H +#include "qgeotileproviderosm.h" + #include <QtLocation/private/qgeotiledmap_p.h> QT_BEGIN_NAMESPACE @@ -56,9 +58,12 @@ public: protected: void evaluateCopyrights(const QSet<QGeoTileSpec> &visibleTiles) Q_DECL_OVERRIDE; +protected Q_SLOTS: + void onProviderDataUpdated(const QGeoTileProviderOsm *provider); + private: int m_mapId; - const QString m_customCopyright; + QGeoTiledMappingManagerEngineOsm *m_engine; }; QT_END_NAMESPACE diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp index d5490559..920b0148 100644 --- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp +++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp @@ -40,10 +40,14 @@ #include "qgeotiledmappingmanagerengineosm.h" #include "qgeotilefetcherosm.h" #include "qgeotiledmaposm.h" +#include "qgeotileproviderosm.h" #include <QtLocation/private/qgeocameracapabilities_p.h> #include <QtLocation/private/qgeomaptype_p.h> #include <QtLocation/private/qgeotiledmap_p.h> +#include <QtLocation/private/qgeofiletilecache_p.h> + +#include <QtNetwork/QNetworkAccessManager> QT_BEGIN_NAMESPACE @@ -57,33 +61,142 @@ QGeoTiledMappingManagerEngineOsm::QGeoTiledMappingManagerEngineOsm(const QVarian setTileSize(QSize(256, 256)); + QNetworkAccessManager *nm = new QNetworkAccessManager(); + QString domain = QStringLiteral("http://maps-redirect.qt.io/osm/5.6/"); + if (parameters.contains(QStringLiteral("osm.mapping.providersrepository.address"))) { + QString customAddress = parameters.value(QStringLiteral("osm.mapping.providersrepository.address")).toString(); + // Allowing some malformed addresses ( containing the suffix "/osm/5.6/" + if (customAddress.indexOf(QStringLiteral(":")) < 0) // defaulting to http:// if no prefix is found + customAddress = QStringLiteral("http://") + customAddress; + if (customAddress[customAddress.length()-1] != QLatin1Char('/')) + customAddress += QLatin1Char('/'); + domain = customAddress; + } + + m_providers.push_back( + new QGeoTileProviderOsm(domain + "street", + nm, + QGeoMapType(QGeoMapType::StreetMap, tr("Street Map"), tr("Street map view in daylight mode"), false, false, 1), + QGeoTileProviderOsm::TileProvider(QStringLiteral("http://c.tile.openstreetmap.org/%z/%x/%y.png"), + QStringLiteral("png"), + QStringLiteral("<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap.org</a>"), + QStringLiteral("<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors") + ))); + m_providers.push_back( + new QGeoTileProviderOsm(domain + "satellite", + nm, + QGeoMapType(QGeoMapType::SatelliteMapDay, tr("Satellite Map"), tr("Satellite map view in daylight mode"), false, false, 2), + QGeoTileProviderOsm::TileProvider(QStringLiteral("http://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer/tile/%z/%y/%x"), + QStringLiteral("jpg"), + QStringLiteral("<a href='http://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryOnly/MapServer'>USGS The National Map: Orthoimagery</a>"), + QStringLiteral("<a href='http://landsat.gsfc.nasa.gov/?page_id=2339'>USGS/NASA Landsat</a>") + ))); + m_providers.push_back( + new QGeoTileProviderOsm(domain + "cycle", + nm, + QGeoMapType(QGeoMapType::CycleMap, tr("Cycle Map"), tr("Cycle map view in daylight mode"), false, false, 3), + QGeoTileProviderOsm::TileProvider(QStringLiteral("http://c.tile.opencyclemap.org/cycle/%z/%x/%y.png"), + QStringLiteral("png"), + QStringLiteral("<a href='http://www.thunderforest.com/'>Thunderforest</a>"), + QStringLiteral("<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors") + ))); + m_providers.push_back( + new QGeoTileProviderOsm(domain + "transit", + nm, + QGeoMapType(QGeoMapType::TransitMap, tr("Transit Map"), tr("Public transit map view in daylight mode"), false, false, 4), + QGeoTileProviderOsm::TileProvider(QStringLiteral("http://c.tile2.opencyclemap.org/transport/%z/%x/%y.png"), + QStringLiteral("png"), + QStringLiteral("<a href='http://www.thunderforest.com/'>Thunderforest</a>"), + QStringLiteral("<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors") + ))); + m_providers.push_back( + new QGeoTileProviderOsm(domain + "night-transit", + nm, + QGeoMapType(QGeoMapType::TransitMap, tr("Night Transit Map"), tr("Public transit map view in night mode"), false, true, 5), + QGeoTileProviderOsm::TileProvider(QStringLiteral("http://a.tile.thunderforest.com/transport-dark/%z/%x/%y.png"), + QStringLiteral("png"), + QStringLiteral("<a href='http://www.thunderforest.com/'>Thunderforest</a>"), + QStringLiteral("<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors") + ))); + m_providers.push_back( + new QGeoTileProviderOsm(domain + "terrain", + nm, + QGeoMapType(QGeoMapType::TerrainMap, tr("Terrain Map"), tr("Terrain map view"), false, false, 6), + QGeoTileProviderOsm::TileProvider(QStringLiteral("http://a.tile.thunderforest.com/landscape/%z/%x/%y.png"), + QStringLiteral("png"), + QStringLiteral("<a href='http://www.thunderforest.com/'>Thunderforest</a>"), + QStringLiteral("<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors") + ))); + m_providers.push_back( + new QGeoTileProviderOsm(domain + "hiking", + nm, + QGeoMapType(QGeoMapType::PedestrianMap, tr("Hiking Map"), tr("Hiking map view"), false, false, 7), + QGeoTileProviderOsm::TileProvider(QStringLiteral("http://a.tile.thunderforest.com/outdoors/%z/%x/%y.png"), + QStringLiteral("png"), + QStringLiteral("<a href='http://www.thunderforest.com/'>Thunderforest</a>"), + QStringLiteral("<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors") + ))); + + if (parameters.contains(QStringLiteral("osm.mapping.custom.host")) + || parameters.contains(QStringLiteral("osm.mapping.host"))) { + // Adding a custom provider + QString tmsServer; + if (parameters.contains(QStringLiteral("osm.mapping.host"))) + tmsServer = parameters.value(QStringLiteral("osm.mapping.host")).toString(); + if (parameters.contains(QStringLiteral("osm.mapping.custom.host"))) // priority to the new one + tmsServer = parameters.value(QStringLiteral("osm.mapping.custom.host")).toString(); + + QString mapCopyright; + QString dataCopyright; + if (parameters.contains(QStringLiteral("osm.mapping.custom.mapcopyright"))) + mapCopyright = parameters.value(QStringLiteral("osm.mapping.custom.mapcopyright")).toString(); + if (parameters.contains(QStringLiteral("osm.mapping.custom.datacopyright"))) + dataCopyright = parameters.value(QStringLiteral("osm.mapping.custom.datacopyright")).toString(); + + if (parameters.contains(QStringLiteral("osm.mapping.copyright"))) + m_customCopyright = parameters.value(QStringLiteral("osm.mapping.copyright")).toString(); + + m_providers.push_back( + new QGeoTileProviderOsm("", + nm, + QGeoMapType(QGeoMapType::CustomMap, tr("Custom URL Map"), tr("Custom url map view set via urlprefix parameter"), false, false, 8), + QGeoTileProviderOsm::TileProvider(tmsServer + QStringLiteral("%z/%x/%y.png"), + QStringLiteral("png"), + mapCopyright, + dataCopyright + ))); + + m_providers.last()->disableRedirection(); + } + + bool disableRedirection = false; + if (parameters.contains(QStringLiteral("osm.mapping.providersrepository.disabled"))) + disableRedirection = parameters.value(QStringLiteral("osm.mapping.providersrepository.disabled")).toBool(); + QList<QGeoMapType> mapTypes; + foreach (QGeoTileProviderOsm * provider, m_providers) { + provider->setParent(this); + if (disableRedirection) + provider->disableRedirection(); + mapTypes << provider->mapType(); + } // See map type implementations in QGeoTiledMapOsm and QGeoTileFetcherOsm. - mapTypes << QGeoMapType(QGeoMapType::StreetMap, tr("Street Map"), tr("Street map view in daylight mode"), false, false, 1); - mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, tr("Satellite Map"), tr("Satellite map view in daylight mode"), false, false, 2); - mapTypes << QGeoMapType(QGeoMapType::CycleMap, tr("Cycle Map"), tr("Cycle map view in daylight mode"), false, false, 3); - mapTypes << QGeoMapType(QGeoMapType::TransitMap, tr("Transit Map"), tr("Public transit map view in daylight mode"), false, false, 4); - mapTypes << QGeoMapType(QGeoMapType::TransitMap, tr("Night Transit Map"), tr("Public transit map view in night mode"), false, true, 5); - mapTypes << QGeoMapType(QGeoMapType::TerrainMap, tr("Terrain Map"), tr("Terrain map view"), false, false, 6); - mapTypes << QGeoMapType(QGeoMapType::PedestrianMap, tr("Hiking Map"), tr("Hiking map view"), false, false, 7); - if (parameters.contains(QStringLiteral("osm.mapping.host"))) - mapTypes << QGeoMapType(QGeoMapType::CustomMap, tr("Custom URL Map"), tr("Custom url map view set via urlprefix parameter"), false, false, 8); setSupportedMapTypes(mapTypes); - QGeoTileFetcherOsm *tileFetcher = new QGeoTileFetcherOsm(this); + QGeoTileFetcherOsm *tileFetcher = new QGeoTileFetcherOsm(m_providers, nm, this); if (parameters.contains(QStringLiteral("osm.useragent"))) { const QByteArray ua = parameters.value(QStringLiteral("osm.useragent")).toString().toLatin1(); tileFetcher->setUserAgent(ua); } - if (parameters.contains(QStringLiteral("osm.mapping.host"))) { - const QString up = parameters.value(QStringLiteral("osm.mapping.host")).toString().toLatin1(); - tileFetcher->setUrlPrefix(up); - } - if (parameters.contains(QStringLiteral("osm.mapping.copyright"))) - m_customCopyright = parameters.value(QStringLiteral("osm.mapping.copyright")).toString().toLatin1(); + setTileFetcher(tileFetcher); + QAbstractGeoTileCache *tileCache = new QGeoFileTileCache(QAbstractGeoTileCache::baseCacheDirectory() + QStringLiteral("osm")); + // 50mb of disk cache by default to minimize n. of accesses to public OSM servers + tileCache->setMaxDiskUsage(50 * 1024 * 1024); + setTileCache(tileCache); + *error = QGeoServiceProvider::NoError; errorString->clear(); } @@ -97,6 +210,11 @@ QGeoMap *QGeoTiledMappingManagerEngineOsm::createMap() return new QGeoTiledMapOsm(this); } +const QVector<QGeoTileProviderOsm *> &QGeoTiledMappingManagerEngineOsm::providers() +{ + return m_providers; +} + QString QGeoTiledMappingManagerEngineOsm::customCopyright() const { return m_customCopyright; diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h index e0f7d873..2ceebc74 100644 --- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h +++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h @@ -40,25 +40,31 @@ #ifndef QGEOTILEDMAPPINGMANAGERENGINEOSM_H #define QGEOTILEDMAPPINGMANAGERENGINEOSM_H -#include <QtLocation/QGeoServiceProvider> +#include "qgeotileproviderosm.h" +#include <QtLocation/QGeoServiceProvider> #include <QtLocation/private/qgeotiledmappingmanagerengine_p.h> +#include <QVector> + QT_BEGIN_NAMESPACE class QGeoTiledMappingManagerEngineOsm : public QGeoTiledMappingManagerEngine { Q_OBJECT + friend class QGeoTiledMapOsm; public: QGeoTiledMappingManagerEngineOsm(const QVariantMap ¶meters, QGeoServiceProvider::Error *error, QString *errorString); ~QGeoTiledMappingManagerEngineOsm(); QGeoMap *createMap(); + const QVector<QGeoTileProviderOsm *> &providers(); QString customCopyright() const; private: + QVector<QGeoTileProviderOsm *> m_providers; QString m_customCopyright; }; diff --git a/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp b/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp index 021c2882..730b5379 100644 --- a/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp +++ b/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp @@ -44,12 +44,36 @@ #include <QtNetwork/QNetworkRequest> #include <QtLocation/private/qgeotilespec_p.h> + QT_BEGIN_NAMESPACE -QGeoTileFetcherOsm::QGeoTileFetcherOsm(QObject *parent) -: QGeoTileFetcher(parent), m_networkManager(new QNetworkAccessManager(this)), - m_userAgent("Qt Location based application") +static bool providersResolved(const QVector<QGeoTileProviderOsm *> &providers) { + foreach (const QGeoTileProviderOsm *provider, providers) + if (!provider->isResolved()) + return false; + return true; +} + +QGeoTileFetcherOsm::QGeoTileFetcherOsm(const QVector<QGeoTileProviderOsm *> &providers, + QNetworkAccessManager *nm, + QObject *parent) +: QGeoTileFetcher(parent), m_userAgent("Qt Location based application"), + m_providers(providers), m_nm(nm), m_ready(true) +{ + m_nm->setParent(this); + foreach (QGeoTileProviderOsm *provider, m_providers) { + if (!provider->isResolved()) { + m_ready = false; + connect(provider, &QGeoTileProviderOsm::resolutionFinished, + this, &QGeoTileFetcherOsm::onProviderResolutionFinished); + connect(provider, &QGeoTileProviderOsm::resolutionError, + this, &QGeoTileFetcherOsm::onProviderResolutionError); + provider->resolveProvider(); + } + } + if (m_ready) + readyUpdated(); } void QGeoTileFetcherOsm::setUserAgent(const QByteArray &userAgent) @@ -57,57 +81,55 @@ void QGeoTileFetcherOsm::setUserAgent(const QByteArray &userAgent) m_userAgent = userAgent; } -void QGeoTileFetcherOsm::setUrlPrefix(const QString &urlPrefix) +bool QGeoTileFetcherOsm::initialized() const { - m_urlPrefix = urlPrefix; + if (!m_ready) { + foreach (QGeoTileProviderOsm *provider, m_providers) + if (!provider->isResolved()) + provider->resolveProvider(); + } + return m_ready; } -QGeoTiledMapReply *QGeoTileFetcherOsm::getTileImage(const QGeoTileSpec &spec) +void QGeoTileFetcherOsm::onProviderResolutionFinished(const QGeoTileProviderOsm *provider) { - QNetworkRequest request; - request.setRawHeader("User-Agent", m_userAgent); + if ((m_ready = providersResolved(m_providers))) { + qWarning("QGeoTileFetcherOsm: all providers resolved"); + readyUpdated(); + } + emit providerDataUpdated(provider); +} - QString urlPrefix; - QString suffix = QStringLiteral(".png"); +void QGeoTileFetcherOsm::onProviderResolutionError(const QGeoTileProviderOsm *provider, QNetworkReply::NetworkError error) +{ + Q_UNUSED(error) + if ((m_ready = providersResolved(m_providers))) { + qWarning("QGeoTileFetcherOsm: all providers resolved"); + readyUpdated(); + } + emit providerDataUpdated(provider); +} - switch (spec.mapId()) { - case 1: - urlPrefix = QStringLiteral("http://otile1.mqcdn.com/tiles/1.0.0/map/"); - suffix = QStringLiteral(".jpg"); - break; - case 2: - urlPrefix = QStringLiteral("http://otile1.mqcdn.com/tiles/1.0.0/sat/"); - suffix = QStringLiteral(".jpg"); - break; - case 3: - urlPrefix = QStringLiteral("http://a.tile.thunderforest.com/cycle/"); - break; - case 4: - urlPrefix = QStringLiteral("http://a.tile.thunderforest.com/transport/"); - break; - case 5: - urlPrefix = QStringLiteral("http://a.tile.thunderforest.com/transport-dark/"); - break; - case 6: - urlPrefix = QStringLiteral("http://a.tile.thunderforest.com/landscape/"); - break; - case 7: - urlPrefix = QStringLiteral("http://a.tile.thunderforest.com/outdoors/"); - break; - case 8: - urlPrefix = m_urlPrefix; - break; - default: +QGeoTiledMapReply *QGeoTileFetcherOsm::getTileImage(const QGeoTileSpec &spec) +{ + int id = spec.mapId(); + if (id < 1 || id > m_providers.size()) { qWarning("Unknown map id %d\n", spec.mapId()); + id = 0; } + id -= 1; // TODO: make OSM map ids start from 0. - request.setUrl(QUrl(urlPrefix + QString::number(spec.zoom()) + QLatin1Char('/') + - QString::number(spec.x()) + QLatin1Char('/') + - QString::number(spec.y()) + suffix)); - - QNetworkReply *reply = m_networkManager->get(request); + const QUrl url = m_providers[id]->tileAddress(spec.x(), spec.y(), spec.zoom()); + QNetworkRequest request; + request.setHeader(QNetworkRequest::UserAgentHeader, m_userAgent); + request.setUrl(url); + QNetworkReply *reply = m_nm->get(request); + return new QGeoMapReplyOsm(reply, spec, m_providers[id]->format()); +} - return new QGeoMapReplyOsm(reply, spec); +void QGeoTileFetcherOsm::readyUpdated() +{ + updateTileRequests(QSet<QGeoTileSpec>(), QSet<QGeoTileSpec>()); } QT_END_NAMESPACE diff --git a/src/plugins/geoservices/osm/qgeotilefetcherosm.h b/src/plugins/geoservices/osm/qgeotilefetcherosm.h index 184f20a6..8d69cc56 100644 --- a/src/plugins/geoservices/osm/qgeotilefetcherosm.h +++ b/src/plugins/geoservices/osm/qgeotilefetcherosm.h @@ -40,31 +40,48 @@ #ifndef QGEOTILEFETCHEROSM_H #define QGEOTILEFETCHEROSM_H +#include "qgeotileproviderosm.h" #include <QtLocation/private/qgeotilefetcher_p.h> +#include <QVector> QT_BEGIN_NAMESPACE -class QGeoTiledMappingManagerEngine; class QNetworkAccessManager; class QGeoTileFetcherOsm : public QGeoTileFetcher { Q_OBJECT + friend class QGeoMapReplyOsm; + friend class QGeoTiledMappingManagerEngineOsm; public: - QGeoTileFetcherOsm(QObject *parent = 0); + QGeoTileFetcherOsm(const QVector<QGeoTileProviderOsm *> &providers, + QNetworkAccessManager *nm, + QObject *parent = 0); void setUserAgent(const QByteArray &userAgent); - void setUrlPrefix(const QString &urlPrefix); + +Q_SIGNALS: + void providerDataUpdated(const QGeoTileProviderOsm *provider); + +protected: + bool initialized() const Q_DECL_OVERRIDE; + +protected Q_SLOTS: + void onProviderResolutionFinished(const QGeoTileProviderOsm *provider); + void onProviderResolutionError(const QGeoTileProviderOsm *provider, QNetworkReply::NetworkError error); private: QGeoTiledMapReply *getTileImage(const QGeoTileSpec &spec); + void readyUpdated(); - QNetworkAccessManager *m_networkManager; QByteArray m_userAgent; - QString m_urlPrefix; + QVector<QGeoTileProviderOsm *> m_providers; + QNetworkAccessManager *m_nm; + bool m_ready; }; QT_END_NAMESPACE #endif // QGEOTILEFETCHEROSM_H + diff --git a/src/plugins/geoservices/osm/qgeotileproviderosm.cpp b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp new file mode 100644 index 00000000..3d46a425 --- /dev/null +++ b/src/plugins/geoservices/osm/qgeotileproviderosm.cpp @@ -0,0 +1,318 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgeotileproviderosm.h" + +#include <QtCore/QJsonDocument> +#include <QtCore/QJsonObject> +#include <QDebug> + +QT_BEGIN_NAMESPACE + +static const int maxValidZoom = 30; + +QGeoTileProviderOsm::QGeoTileProviderOsm(const QString &urlRedir, + QNetworkAccessManager *nm, + const QGeoMapType &mapType, + const QGeoTileProviderOsm::TileProvider &providerFallback) + : m_nm(nm), m_urlRedirector(urlRedir), + m_providerFallback(providerFallback), + m_mapType(mapType), m_status(Idle) +{ + if (!m_urlRedirector.isValid()) + disableRedirection(); +} + +QGeoTileProviderOsm::~QGeoTileProviderOsm() +{ + +} + +void QGeoTileProviderOsm::resolveProvider() +{ + switch (m_status) { + case Resolving: + case Invalid: + case Valid: + return; + case Idle: + m_status = Resolving; + break; + } + + QNetworkRequest request; + request.setHeader(QNetworkRequest::UserAgentHeader, QByteArrayLiteral("QGeoTileFetcherOsm")); + request.setUrl(m_urlRedirector); + QNetworkReply *reply = m_nm->get(request); + connect(reply, SIGNAL(finished()), this, SLOT(onNetworkReplyFinished())); + connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), + this, SLOT(onNetworkReplyError(QNetworkReply::NetworkError))); +} + +void QGeoTileProviderOsm::disableRedirection() +{ + m_status = Invalid; + m_provider.m_valid = false; +} + +void QGeoTileProviderOsm::handleError(QNetworkReply::NetworkError error) +{ + switch (error) { + case QNetworkReply::ConnectionRefusedError: + case QNetworkReply::TooManyRedirectsError: + case QNetworkReply::InsecureRedirectError: + case QNetworkReply::ContentAccessDenied: + case QNetworkReply::ContentOperationNotPermittedError: + case QNetworkReply::ContentNotFoundError: + case QNetworkReply::AuthenticationRequiredError: + case QNetworkReply::ContentGoneError: + case QNetworkReply::OperationNotImplementedError: + case QNetworkReply::ServiceUnavailableError: + // Errors we don't expect to recover from in the near future, which + // prevent accessing the redirection info but not the actual providers. + m_status = Invalid; + default: + break; + } +} + +QUrl QGeoTileProviderOsm::tileAddress(int x, int y, int z) const +{ + if (m_provider.isValid()) + return m_provider.tileAddress(x,y,z); + if (m_providerFallback.isValid()) + return m_providerFallback.tileAddress(x,y,z); + return QUrl(); +} + +QString QGeoTileProviderOsm::mapCopyRight() const +{ + if (m_provider.isValid()) + return m_provider.mapCopyRight(); + if (m_providerFallback.isValid()) + return m_providerFallback.mapCopyRight(); + return QString(); +} + +QString QGeoTileProviderOsm::dataCopyRight() const +{ + if (m_provider.isValid()) + return m_provider.dataCopyRight(); + if (m_providerFallback.isValid()) + return m_providerFallback.dataCopyRight(); + return QString(); +} + +QString QGeoTileProviderOsm::styleCopyRight() const +{ + if (m_provider.isValid()) + return m_provider.styleCopyRight(); + if (m_providerFallback.isValid()) + return m_providerFallback.styleCopyRight(); + return QString(); +} + +QString QGeoTileProviderOsm::format() const +{ + if (m_provider.isValid()) + return m_provider.format(); + if (m_providerFallback.isValid()) + return m_providerFallback.format(); + return QString(); +} + +const QGeoMapType &QGeoTileProviderOsm::mapType() const +{ + return m_mapType; +} + +bool QGeoTileProviderOsm::isValid() const +{ + return (m_provider.isValid() || m_providerFallback.isValid()); +} + +bool QGeoTileProviderOsm::isResolved() const +{ + return (m_status == Valid || m_status == Invalid); +} + +void QGeoTileProviderOsm::onNetworkReplyFinished() +{ + QNetworkReply *reply = static_cast<QNetworkReply *>(sender()); + reply->deleteLater(); + + switch (m_status) { + case Resolving: + m_status = Idle; + case Idle: // should not happen + case Invalid: // should not happen + break; + case Valid: // should not happen + return; + } + + if (reply->error() != QNetworkReply::NoError) { + handleError(reply->error()); + if (m_status == Invalid) + emit resolutionError(this, reply->error()); + return; + } + m_status = Invalid; + + /* + * The content of a provider information file must be in JSON format, containing + * (as of Qt 5.6.2) the following fields: + * + * { + * "Enabled" : bool, (optional) + * "UrlTemplate" : "<url template>", (mandatory) + * "ImageFormat" : "<image format>", (mandatory) + * "MapCopyRight" : "<copyright>", (mandatory) + * "DataCopyRight" : "<copyright>", (mandatory) + * "StyleCopyRight" : "<copyright>", (optional) + * "MinimumZoomLevel" : <minimumZoomLevel>, (optional) + * "MaximumZoomLevel" : <maximumZoomLevel>, (optional) + * } + * + * Enabled is optional, and allows to temporarily disable a tile provider if it becomes + * unavailable, without making the osm plugin fire requests to it. Default is true. + * + * MinimumZoomLevel and MaximumZoomLevel are also optional, and allow to prevent invalid tile + * requests to the providers, if they do not support the specific ZL. Default is 0 and 19, + * respectively. + * + * <server address template> is required, and is the tile url template, with %x, %y and %z as + * placeholders for the actual parameters. + * Example: + * http://localhost:8080/maps/%z/%x/%y.png + * + * <image format> is required, and is the format of the tile. + * Examples: + * "png", "jpg" + * + * <MapCopyRight> is required and is the string that will be displayed in the "Map (c)" part + * of the on-screen copyright notice. Can be an empty string. + * Example: + * "<a href='http://www.mapquest.com/'>MapQuest</a>" + * + * <DataCopyRight> is required and is the string that will be displayed in the "Data (c)" part + * of the on-screen copyright notice. Can be an empty string. + * Example: + * "<a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors" + * + * <StyleCopyRight> is optional and is the string that will be displayed in the optional "Style (c)" part + * of the on-screen copyright notice. + */ + + QJsonParseError error; + QJsonDocument d = QJsonDocument::fromJson(reply->readAll(), &error); + if (error.error != QJsonParseError::NoError) { + qWarning() << "QGeoTileProviderOsm: Error parsing redirection data: "<<error.errorString() << "at "<<m_urlRedirector; + emit resolutionFinished(this); + return; + } + if (!d.isObject()) { + qWarning() << "QGeoTileProviderOsm: Invalid redirection data" << "at "<<m_urlRedirector; + emit resolutionFinished(this); + return; + } + const QJsonObject json = d.object(); + const QJsonValue urlTemplate = json.value(QLatin1String("UrlTemplate")); + const QJsonValue imageFormat = json.value(QLatin1String("ImageFormat")); + const QJsonValue copyRightMap = json.value(QLatin1String("MapCopyRight")); + const QJsonValue copyRightData = json.value(QLatin1String("DataCopyRight")); + if ( urlTemplate == QJsonValue::Undefined + || imageFormat == QJsonValue::Undefined + || copyRightMap == QJsonValue::Undefined + || copyRightData == QJsonValue::Undefined + || !urlTemplate.isString() + || !imageFormat.isString() + || !copyRightMap.isString() + || !copyRightData.isString()) { + qWarning() << "QGeoTileProviderOsm: Incomplete redirection data" << "at "<<m_urlRedirector; + emit resolutionFinished(this); + return; + } + + const QJsonValue enabled = json.value(QLatin1String("Enabled")); + if (enabled.isBool() && ! enabled.toBool()) { + qWarning() << "QGeoTileProviderOsm: Tileserver disabled" << "at "<<m_urlRedirector; + emit resolutionFinished(this); + return; + } + + QString styleCopyRight; + const QJsonValue copyRightStyle = json.value(QLatin1String("StyleCopyRight")); + if (copyRightStyle != QJsonValue::Undefined && copyRightStyle.isString()) + styleCopyRight = copyRightStyle.toString(); + + int minZL = 0; + int maxZL = 19; + const QJsonValue minZoom = json.value(QLatin1String("MinimumZoomLevel")); + if (minZoom.isDouble()) + minZL = qBound(0, int(minZoom.toDouble()), maxValidZoom); + const QJsonValue maxZoom = json.value(QLatin1String("MaximumZoomLevel")); + if (maxZoom.isDouble()) + maxZL = qBound(0, int(maxZoom.toDouble()), maxValidZoom); + + m_provider = TileProvider(urlTemplate.toString(), + imageFormat.toString(), + copyRightMap.toString(), + copyRightData.toString(), + minZL, + maxZL); + m_provider.setStyleCopyRight(styleCopyRight); + + if (m_provider.isValid()) + m_status = Valid; + + emit resolutionFinished(this); +} + +void QGeoTileProviderOsm::onNetworkReplyError(QNetworkReply::NetworkError error) +{ + if (m_status == Resolving) + m_status = Idle; + + qWarning() << "QGeoTileProviderOsm::onNetworkReplyError " << error; + handleError(error); + + static_cast<QNetworkReply *>(sender())->deleteLater(); + if (m_status == Invalid) + emit resolutionError(this, error); +} + +QT_END_NAMESPACE diff --git a/src/plugins/geoservices/osm/qgeotileproviderosm.h b/src/plugins/geoservices/osm/qgeotileproviderosm.h new file mode 100644 index 00000000..cdff7997 --- /dev/null +++ b/src/plugins/geoservices/osm/qgeotileproviderosm.h @@ -0,0 +1,256 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTILEPROVIDEROSM_H +#define QTILEPROVIDEROSM_H + +#include <QtLocation/private/qgeomaptype_p.h> + +#include <QtCore/QUrl> +#include <QtNetwork/QNetworkAccessManager> +#include <QtNetwork/QNetworkReply> +#include <QtCore/QPointer> +#include <QTimer> +#include <algorithm> + +QT_BEGIN_NAMESPACE + +class QGeoTileProviderOsm: public QObject +{ + Q_OBJECT + + friend class QGeoTileFetcherOsm; + friend class QGeoMapReplyOsm; + friend class QGeoTiledMappingManagerEngineOsm; +public: + struct TileProvider { + + static inline void sort2(int &a, int &b) + { + if (a > b) { + int temp=a; + a=b; + b=temp; + } + } + + TileProvider() : m_valid(false) + { + + } + + TileProvider(const QString &urlTemplate, + const QString &format, + const QString ©RightMap, + const QString ©RightData, + int minimumZoomLevel = 0, + int maximumZoomLevel = 19) : m_valid(false) + { + if (urlTemplate.isEmpty()) + return; + m_urlTemplate = urlTemplate; + + if (format.isEmpty()) + return; + m_format = format; + + m_copyRightMap = copyRightMap; + m_copyRightData = copyRightData; + + if (minimumZoomLevel < 0 || minimumZoomLevel > 30) + return; + m_minimumZoomLevel = minimumZoomLevel; + + if (maximumZoomLevel < 0 || maximumZoomLevel > 30 || maximumZoomLevel < minimumZoomLevel) + return; + m_maximumZoomLevel = maximumZoomLevel; + + // Currently supporting only %x, %y and &z + int offset[3]; + offset[0] = m_urlTemplate.indexOf(QLatin1String("%x")); + if (offset[0] < 0) + return; + + offset[1] = m_urlTemplate.indexOf(QLatin1String("%y")); + if (offset[1] < 0) + return; + + offset[2] = m_urlTemplate.indexOf(QLatin1String("%z")); + if (offset[2] < 0) + return; + + int sortedOffsets[3]; + std::copy(offset, offset + 4, sortedOffsets); + sort2(sortedOffsets[0] ,sortedOffsets[1]); + sort2(sortedOffsets[1] ,sortedOffsets[2]); + sort2(sortedOffsets[0] ,sortedOffsets[1]); + + int min = sortedOffsets[0]; + int max = sortedOffsets[2]; + int mid = sortedOffsets[1]; + + // Initing LUT + for (int i=0; i<3; i++) { + if (offset[0] == sortedOffsets[i]) + paramsLUT[i] = 0; + else if (offset[1] == sortedOffsets[i]) + paramsLUT[i] = 1; + else + paramsLUT[i] = 2; + } + + m_urlPrefix = m_urlTemplate.mid(0 , min); + m_urlSuffix = m_urlTemplate.mid(max + 2, m_urlTemplate.size() - max - 2); + + paramsSep[0] = m_urlTemplate.mid(min + 2, mid - min - 2); + paramsSep[1] = m_urlTemplate.mid(mid + 2, max - mid - 2); + m_valid = true; + } + + ~TileProvider() + { + } + + inline bool isValid() const + { + return m_valid; + } + + inline QString mapCopyRight() const + { + return m_copyRightMap; + } + + inline QString dataCopyRight() const + { + return m_copyRightData; + } + + inline QString styleCopyRight() const + { + return m_copyRightStyle; + } + + inline QString format() const + { + return m_format; + } + + // Optional properties, not needed to construct a provider + void setStyleCopyRight(const QString ©right) + { + m_copyRightStyle = copyright; + } + + QUrl tileAddress(int x, int y, int z) const + { + if (z < m_minimumZoomLevel || z > m_maximumZoomLevel) + return QUrl(); + int params[3] = { x, y, z}; + QString url; + url += m_urlPrefix; + url += QString::number(params[paramsLUT[0]]); + url += paramsSep[0]; + url += QString::number(params[paramsLUT[1]]); + url += paramsSep[1]; + url += QString::number(params[paramsLUT[2]]); + url += m_urlSuffix; + return QUrl(url); + } + + bool m_valid; + QString m_urlTemplate; + QString m_format; + QString m_copyRightMap; + QString m_copyRightData; + QString m_copyRightStyle; + QString m_urlPrefix; + QString m_urlSuffix; + int m_minimumZoomLevel; + int m_maximumZoomLevel; + + int paramsLUT[3]; //Lookup table to handle possibly shuffled x,y,z + QString paramsSep[2]; // what goes in between %x, %y and %z + }; + + enum Status {Idle, + Resolving, + Valid, + Invalid }; + + QGeoTileProviderOsm(const QString &urlRedir, + QNetworkAccessManager *nm, + const QGeoMapType &mapType, + const TileProvider &providerFallback); + + ~QGeoTileProviderOsm(); + + + + QUrl tileAddress(int x, int y, int z) const; + QString mapCopyRight() const; + QString dataCopyRight() const; + QString styleCopyRight() const; + QString format() const; + const QGeoMapType &mapType() const; + bool isValid() const; + bool isResolved() const; + +Q_SIGNALS: + void resolutionFinished(const QGeoTileProviderOsm *provider); + void resolutionError(const QGeoTileProviderOsm *provider, QNetworkReply::NetworkError error); + +public Q_SLOTS: + void onNetworkReplyFinished(); + void onNetworkReplyError(QNetworkReply::NetworkError error); + void resolveProvider(); + +protected: + void disableRedirection(); + void handleError(QNetworkReply::NetworkError error); + + QNetworkAccessManager *m_nm; + QUrl m_urlRedirector; // The URL from where to fetch the URL template + TileProvider m_provider; + TileProvider m_providerFallback; + QGeoMapType m_mapType; + Status m_status; + QTimer m_retryTimer; +}; + +QT_END_NAMESPACE + +#endif // QTILEPROVIDEROSM_H 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 ac718199..b55a90d4 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 @@ -241,7 +241,7 @@ public class QtPositioning implements LocationListener positioningListener.isSatelliteUpdate = false; if (updateInterval == 0) - updateInterval = 1000; //don't update more often than once per second + updateInterval = 50; //don't update more often than once per 50ms positioningListener.updateIntervalTime = updateInterval; if ((locationProvider & QT_GPS_PROVIDER) > 0) { @@ -361,7 +361,7 @@ public class QtPositioning implements LocationListener positioningListener.isSingleUpdate = isSingleRequest; if (updateInterval == 0) - updateInterval = 1000; //don't update more often than once per second + updateInterval = 50; //don't update more often than once per 50ms if (isSingleRequest) Log.d(TAG, "Single update for Satellites " + updateInterval); diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp index 3ec772cd..e0124eb6 100644 --- a/src/plugins/position/android/src/jnipositioning.cpp +++ b/src/plugins/position/android/src/jnipositioning.cpp @@ -546,6 +546,11 @@ static bool registerNatives(JNIEnv *env) Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/) { + static bool initialized = false; + if (initialized) + return JNI_VERSION_1_6; + initialized = true; + typedef union { JNIEnv *nativeEnvironment; void *venv; diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp index b24a6c96..488c1a70 100644 --- a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp +++ b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp @@ -111,7 +111,7 @@ void QGeoPositionInfoSourceAndroid::setPreferredPositioningMethods(QGeoPositionI int QGeoPositionInfoSourceAndroid::minimumUpdateInterval() const { - return 1000; + return 50; } QGeoPositionInfoSource::Error QGeoPositionInfoSourceAndroid::error() const diff --git a/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp b/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp index e7cd2e7d..f89f6663 100644 --- a/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp +++ b/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp @@ -90,7 +90,7 @@ void QGeoSatelliteInfoSourceAndroid::setUpdateInterval(int msec) int QGeoSatelliteInfoSourceAndroid::minimumUpdateInterval() const { - return 1000; + return 50; } QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSourceAndroid::error() const |