summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@theqtcompany.com>2016-07-26 16:45:37 +0200
committerPaolo Angelelli <paolo.angelelli@theqtcompany.com>2016-07-29 14:13:39 +0000
commite7099f14c8faea4fb7c89877973b7cec75044cb3 (patch)
tree773b6ef8f73359c256c4cb442ae4391a4a3d02e8
parent75dd424e11964d8755abdb1b12b27a8479353b37 (diff)
downloadqtlocation-e7099f14c8faea4fb7c89877973b7cec75044cb3.tar.gz
Enable dynamic addition/removal of map types by the mapping manager
Map types are currently fixed in the constructor, regardless of whether they were available, or, now, whether they are enabled or not. This patch makes the geomappingmanager notify (e.g., emit a signal) when the available map types change at runtime. This is used in the OSM mappingmanagerengine, which can now disable map types if provider records turn out to be invalid or disabled after they have been fetched. Change-Id: I8e0e75504c882609f91c6d1ceb88424eee656f26 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp38
-rw-r--r--src/imports/location/qdeclarativegeomap_p.h1
-rw-r--r--src/location/doc/src/plugins/osm.qdoc9
-rw-r--r--src/location/maps/qgeomappingmanager.cpp6
-rw-r--r--src/location/maps/qgeomappingmanager_p.h1
-rw-r--r--src/location/maps/qgeomappingmanagerengine.cpp1
-rw-r--r--src/location/maps/qgeomappingmanagerengine_p.h1
-rw-r--r--src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp46
-rw-r--r--src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h7
-rw-r--r--src/plugins/geoservices/osm/qgeotilefetcherosm.cpp5
10 files changed, 103 insertions, 12 deletions
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index b220c899..ad2b78da 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -249,6 +249,43 @@ void QDeclarativeGeoMap::onMapChildrenChanged()
copyrights->setCopyrightsZ(maxChildZ + 1);
}
+static QDeclarativeGeoMapType *findMapType(const QList<QDeclarativeGeoMapType *> &types, const QGeoMapType &type)
+{
+ for (int i = 0; i < types.size(); ++i)
+ if (types[i]->mapType() == type)
+ return types[i];
+ return Q_NULLPTR;
+}
+
+void QDeclarativeGeoMap::onSupportedMapTypesChanged()
+{
+ QList<QDeclarativeGeoMapType *> supportedMapTypes;
+ QList<QGeoMapType> types = m_mappingManager->supportedMapTypes();
+ for (int i = 0; i < types.size(); ++i) {
+ // types that are present and get removed will be deleted at QObject destruction
+ QDeclarativeGeoMapType *type = findMapType(m_supportedMapTypes, types[i]);
+ if (!type)
+ type = new QDeclarativeGeoMapType(types[i], this);
+ supportedMapTypes.append(type);
+ }
+ m_supportedMapTypes.swap(supportedMapTypes);
+ if (m_supportedMapTypes.isEmpty()) {
+ m_map->setActiveMapType(QGeoMapType()); // no supported map types: setting an invalid one
+ } else {
+ bool hasMapType = false;
+ foreach (QDeclarativeGeoMapType *declarativeType, m_supportedMapTypes) {
+ if (declarativeType->mapType() == m_map->activeMapType())
+ hasMapType = true;
+ }
+ if (!hasMapType) {
+ QDeclarativeGeoMapType *type = m_supportedMapTypes.at(0);
+ m_activeMapType = type;
+ m_map->setActiveMapType(type->mapType());
+ }
+ }
+
+ emit supportedMapTypesChanged();
+}
void QDeclarativeGeoMap::setError(QGeoServiceProvider::Error error, const QString &errorString)
{
@@ -518,6 +555,7 @@ void QDeclarativeGeoMap::mappingManagerInitialized()
m_map->prefetchData();
m_map->update();
+ connect(m_mappingManager, SIGNAL(supportedMapTypesChanged()), this, SLOT(onSupportedMapTypesChanged()));
emit minimumZoomLevelChanged();
emit maximumZoomLevelChanged();
emit supportedMapTypesChanged();
diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h
index ca1b7a62..40693ef4 100644
--- a/src/imports/location/qdeclarativegeomap_p.h
+++ b/src/imports/location/qdeclarativegeomap_p.h
@@ -170,6 +170,7 @@ private Q_SLOTS:
void mapCenterChanged(const QGeoCoordinate &center);
void pluginReady();
void onMapChildrenChanged();
+ void onSupportedMapTypesChanged();
private:
void setupMapView(QDeclarativeGeoMapItemView *view);
diff --git a/src/location/doc/src/plugins/osm.qdoc b/src/location/doc/src/plugins/osm.qdoc
index 2fd9e7c4..75ac104d 100644
--- a/src/location/doc/src/plugins/osm.qdoc
+++ b/src/location/doc/src/plugins/osm.qdoc
@@ -37,12 +37,17 @@
This geo services plugin allows applications to access
\l {http://openstreetmap.org}{Open Street Map} location based services using the Qt Location API.
-Data, imagery and map information provided by \l {http://www.mapquest.com}{MapQuest},
+Data, imagery and map information provided by \l {http://korona.geog.uni-heidelberg.de/}{OpenMapSurfer},
\l {http://www.thunderforest.com/}{ThunderForest}, OpenStreetMap and contributors. The data is
available under the \l {http://www.opendatacommons.org/licenses/odbl}{Open Database License}.
The Open Street Map geo services plugin can be loaded by using the plugin key "osm".
+\note Since Qt 5.6.2, the available map types offered by this plugin may change without notice depending on the
+actual availability of each provider. To prevent these changes, either a different geo service plugin should be used, or the plugin
+parameter \e osm.mapping.providersrepository.address should be set to a user-specified repository, in order to take full control over
+(and accept \b responsibility for) selecting the provider that is used for each map type.
+
\section1 Parameters
\section2 Optional parameters
@@ -78,7 +83,7 @@ a prefix.
\li The OpenStreetMap plugin retrieves the provider's information from a remote repository. This is done to prevent using hardcoded
servers by default, which may become unavailable. By default this information is fetched from \l {http://maps-redirect.qt.io} {maps-redirect.qt.io}.
Setting this parameter changes the provider repository address to a user-specified one, which must contain the files
- \tt{street}, \tt{satellite}, \tt{cycle}, \tt{transit}, \tt{night-transit}, \tt{terrain} and \tt{hiking}.
+ \tt{street}, \tt{satellite}, \tt{cycle}, \tt{transit}, \tt{night-transit}, \tt{terrain} and \tt{hiking}, each of which must contain valid provider information.
\row
\li osm.mapping.providersrepository.disabled
\li By default, the OpenStreetMap plugin retrieves the provider's information from a remote repository to avoid a loss of service due to unavailability of hardcoded services.
diff --git a/src/location/maps/qgeomappingmanager.cpp b/src/location/maps/qgeomappingmanager.cpp
index 681e68a7..8c02417d 100644
--- a/src/location/maps/qgeomappingmanager.cpp
+++ b/src/location/maps/qgeomappingmanager.cpp
@@ -81,6 +81,12 @@ QGeoMappingManager::QGeoMappingManager(QGeoMappingManagerEngine *engine, QObject
this,
SIGNAL(initialized()),
Qt::QueuedConnection);
+
+ connect(d_ptr->engine,
+ SIGNAL(supportedMapTypesChanged()),
+ this,
+ SIGNAL(supportedMapTypesChanged()),
+ Qt::QueuedConnection);
}
/*!
diff --git a/src/location/maps/qgeomappingmanager_p.h b/src/location/maps/qgeomappingmanager_p.h
index 043ebd8f..2ec1e8b5 100644
--- a/src/location/maps/qgeomappingmanager_p.h
+++ b/src/location/maps/qgeomappingmanager_p.h
@@ -89,6 +89,7 @@ public:
Q_SIGNALS:
void initialized();
+ void supportedMapTypesChanged();
protected:
QGeoMappingManager(QGeoMappingManagerEngine *engine, QObject *parent = 0);
diff --git a/src/location/maps/qgeomappingmanagerengine.cpp b/src/location/maps/qgeomappingmanagerengine.cpp
index 70b1e836..d25b4749 100644
--- a/src/location/maps/qgeomappingmanagerengine.cpp
+++ b/src/location/maps/qgeomappingmanagerengine.cpp
@@ -147,6 +147,7 @@ void QGeoMappingManagerEngine::setSupportedMapTypes(const QList<QGeoMapType> &su
{
Q_D(QGeoMappingManagerEngine);
d->supportedMapTypes = supportedMapTypes;
+ emit supportedMapTypesChanged();
}
QGeoCameraCapabilities QGeoMappingManagerEngine::cameraCapabilities()
diff --git a/src/location/maps/qgeomappingmanagerengine_p.h b/src/location/maps/qgeomappingmanagerengine_p.h
index 7e866d89..4eb24eac 100644
--- a/src/location/maps/qgeomappingmanagerengine_p.h
+++ b/src/location/maps/qgeomappingmanagerengine_p.h
@@ -98,6 +98,7 @@ public:
Q_SIGNALS:
void initialized();
+ void supportedMapTypesChanged();
protected:
void setSupportedMapTypes(const QList<QGeoMapType> &supportedMapTypes);
diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
index 92982a1f..738bf9a9 100644
--- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
@@ -80,11 +80,8 @@ QGeoTiledMappingManagerEngineOsm::QGeoTiledMappingManagerEngineOsm(const QVarian
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>")
- )));
+ QGeoTileProviderOsm::TileProvider()
+ ));
m_providers.push_back(
new QGeoTileProviderOsm(domain + "cycle",
nm,
@@ -167,15 +164,17 @@ QGeoTiledMappingManagerEngineOsm::QGeoTiledMappingManagerEngineOsm(const QVarian
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();
+
+ connect(provider, &QGeoTileProviderOsm::resolutionFinished,
+ this, &QGeoTiledMappingManagerEngineOsm::onProviderResolutionFinished);
+ connect(provider, &QGeoTileProviderOsm::resolutionError,
+ this, &QGeoTiledMappingManagerEngineOsm::onProviderResolutionError);
}
- // See map type implementations in QGeoTiledMapOsm and QGeoTileFetcherOsm.
- setSupportedMapTypes(mapTypes);
+ updateMapTypes();
QGeoTileFetcherOsm *tileFetcher = new QGeoTileFetcherOsm(m_providers, nm, this);
if (parameters.contains(QStringLiteral("osm.useragent"))) {
@@ -214,4 +213,33 @@ QString QGeoTiledMappingManagerEngineOsm::customCopyright() const
return m_customCopyright;
}
+void QGeoTiledMappingManagerEngineOsm::onProviderResolutionFinished(const QGeoTileProviderOsm *provider)
+{
+ if (!provider->isResolved())
+ return;
+ updateMapTypes();
+}
+
+void QGeoTiledMappingManagerEngineOsm::onProviderResolutionError(const QGeoTileProviderOsm *provider, QNetworkReply::NetworkError error)
+{
+ Q_UNUSED(error)
+ if (!provider->isResolved())
+ return;
+ updateMapTypes();
+}
+
+void QGeoTiledMappingManagerEngineOsm::updateMapTypes()
+{
+ QList<QGeoMapType> mapTypes;
+ foreach (QGeoTileProviderOsm * provider, m_providers) {
+ // assume provider are ok until they have been resolved invalid
+ if (!provider->isResolved() || provider->isValid())
+ mapTypes << provider->mapType();
+ }
+ const QList<QGeoMapType> currentlySupportedMapTypes = supportedMapTypes();
+ if (currentlySupportedMapTypes != mapTypes)
+ // See map type implementations in QGeoTiledMapOsm and QGeoTileFetcherOsm.
+ setSupportedMapTypes(mapTypes);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h
index 9755b0c2..68a7a517 100644
--- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h
+++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h
@@ -57,6 +57,13 @@ public:
const QVector<QGeoTileProviderOsm *> &providers();
QString customCopyright() const;
+protected Q_SLOTS:
+ void onProviderResolutionFinished(const QGeoTileProviderOsm *provider);
+ void onProviderResolutionError(const QGeoTileProviderOsm *provider, QNetworkReply::NetworkError error);
+
+protected:
+ void updateMapTypes();
+
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 45da7d42..f643c66e 100644
--- a/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotilefetcherosm.cpp
@@ -109,7 +109,10 @@ 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;
+ if (m_providers.isEmpty())
+ return Q_NULLPTR;
+ else
+ id = 1;
}
id -= 1; // TODO: make OSM map ids start from 0.