summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/location/qdeclarativegeomap.cpp29
-rw-r--r--src/imports/location/qdeclarativegeomap_p.h2
-rw-r--r--src/imports/location/qdeclarativepolygonmapitem.cpp2
-rw-r--r--src/imports/location/qdeclarativepolylinemapitem.cpp2
-rw-r--r--src/imports/location/qgeomapitemgeometry.cpp4
-rw-r--r--src/location/doc/src/plugins/mapbox.qdoc34
-rw-r--r--src/location/doc/src/plugins/nokia.qdoc3
-rw-r--r--src/location/doc/src/plugins/osm.qdoc23
-rw-r--r--src/location/maps/qabstractgeotilecache_p.h4
-rw-r--r--src/location/maps/qgeofiletilecache.cpp94
-rw-r--r--src/location/maps/qgeofiletilecache_p.h9
-rw-r--r--src/location/maps/qgeomap_p.h5
-rw-r--r--src/location/maps/qgeotiledmap.cpp4
-rw-r--r--src/location/maps/qgeotiledmap_p.h4
-rw-r--r--src/location/maps/qgeotiledmappingmanagerengine.cpp2
-rw-r--r--src/location/maps/qgeotiledmapscene.cpp73
-rw-r--r--src/plugins/geoservices/mapbox/mapbox.pro10
-rw-r--r--src/plugins/geoservices/mapbox/mapbox_plugin.json3
-rw-r--r--src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.cpp131
-rw-r--r--src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.h63
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp231
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h71
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp122
-rw-r--r--src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h76
-rw-r--r--src/plugins/geoservices/mapbox/qgeoserviceproviderpluginmapbox.cpp19
-rw-r--r--src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.cpp100
-rw-r--r--src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.h3
-rw-r--r--src/plugins/geoservices/mapbox/qgeotilefetchermapbox.cpp13
-rw-r--r--src/plugins/geoservices/mapbox/qgeotilefetchermapbox.h8
-rw-r--r--src/plugins/geoservices/nokia/nokia.pro6
-rw-r--r--src/plugins/geoservices/nokia/qgeofiletilecachenokia.cpp124
-rw-r--r--src/plugins/geoservices/nokia/qgeofiletilecachenokia.h60
-rw-r--r--src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp6
-rw-r--r--src/plugins/geoservices/nokia/qgeotiledmappingmanagerengine_nokia.cpp13
-rw-r--r--src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp28
-rw-r--r--src/plugins/geoservices/nokia/qgeotilefetcher_nokia.h7
-rw-r--r--src/plugins/geoservices/osm/osm.pro4
-rw-r--r--src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp131
-rw-r--r--src/plugins/geoservices/osm/qgeofiletilecacheosm.h71
-rw-r--r--src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp35
-rw-r--r--src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h2
-rw-r--r--src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h18
-rw-r--r--src/plugins/position/position.pro2
-rw-r--r--src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp4
44 files changed, 1476 insertions, 179 deletions
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp
index 9b5c658f..9bb8a17a 100644
--- a/src/imports/location/qdeclarativegeomap.cpp
+++ b/src/imports/location/qdeclarativegeomap.cpp
@@ -45,7 +45,7 @@
#include <QtPositioning/QGeoCircle>
#include <QtPositioning/QGeoRectangle>
#include <QtQuick/QQuickWindow>
-#include <QtQuick/QSGSimpleRectNode>
+#include <QtQuick/QSGRectangleNode>
#include <QtQuick/private/qquickwindow_p.h>
#include <QtQml/qqmlinfo.h>
#include <cmath>
@@ -306,10 +306,10 @@ void QDeclarativeGeoMap::initialize()
// try to keep center change signal in the end
bool centerHasChanged = false;
- setMinimumZoomLevel(m_map->minimumZoomForMapSize(width(), height()));
+ setMinimumZoomLevel(m_map->minimumZoomAtMapSize(width(), height()));
// set latitude bundary check
- m_maximumViewportLatitude = m_map->maximumLatitudeForZoom(m_cameraData.zoomLevel());
+ m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(m_cameraData.zoomLevel());
QGeoCoordinate center = m_cameraData.center();
center.setLatitude(qBound(-m_maximumViewportLatitude, center.latitude(), m_maximumViewportLatitude));
@@ -476,13 +476,12 @@ QSGNode *QDeclarativeGeoMap::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDa
return 0;
}
- QSGSimpleRectNode *root = static_cast<QSGSimpleRectNode *>(oldNode);
+ QSGRectangleNode *root = static_cast<QSGRectangleNode *>(oldNode);
if (!root)
- root = new QSGSimpleRectNode(boundingRect(), m_color);
- else {
- root->setRect(boundingRect());
- root->setColor(m_color);
- }
+ root = window()->createRectangleNode();
+
+ root->setRect(boundingRect());
+ root->setColor(m_color);
QSGNode *content = root->childCount() ? root->firstChild() : 0;
content = m_map->updateSceneGraph(content, window());
@@ -616,7 +615,7 @@ void QDeclarativeGeoMap::setMinimumZoomLevel(qreal minimumZoomLevel)
if (m_map) {
minimumZoomLevel = qBound(qreal(m_map->cameraCapabilities().minimumZoomLevel()), minimumZoomLevel, maximumZoomLevel());
- double minimumViewportZoomLevel = m_map->minimumZoomForMapSize(width(),height());
+ double minimumViewportZoomLevel = m_map->minimumZoomAtMapSize(width(),height());
if (minimumZoomLevel < minimumViewportZoomLevel)
minimumZoomLevel = minimumViewportZoomLevel;
}
@@ -715,7 +714,7 @@ void QDeclarativeGeoMap::setZoomLevel(qreal zoomLevel)
if (m_initialized) {
m_cameraData.setZoomLevel(qBound(minimumZoomLevel(), zoomLevel, maximumZoomLevel()));
- m_maximumViewportLatitude = m_map->maximumLatitudeForZoom(m_cameraData.zoomLevel());
+ m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(m_cameraData.zoomLevel());
QGeoCoordinate coord = m_cameraData.center();
coord.setLatitude(qBound(-m_maximumViewportLatitude, coord.latitude(), m_maximumViewportLatitude));
if (coord != m_cameraData.center()) {
@@ -1205,13 +1204,11 @@ void QDeclarativeGeoMap::addMapItem(QDeclarativeGeoMapItemBase *item)
{
if (!item || item->quickMap())
return;
- m_updateMutex.lock();
item->setParentItem(this);
if (m_map)
item->setMap(this, m_map);
m_mapItems.append(item);
emit mapItemsChanged();
- m_updateMutex.unlock();
}
/*!
@@ -1251,13 +1248,11 @@ void QDeclarativeGeoMap::removeMapItem(QDeclarativeGeoMapItemBase *ptr)
QPointer<QDeclarativeGeoMapItemBase> item(ptr);
if (!m_mapItems.contains(item))
return;
- m_updateMutex.lock();
item.data()->setParentItem(0);
item.data()->setMap(0, 0);
// these can be optimized for perf, as we already check the 'contains' above
m_mapItems.removeOne(item);
emit mapItemsChanged();
- m_updateMutex.unlock();
}
/*!
@@ -1271,7 +1266,6 @@ void QDeclarativeGeoMap::clearMapItems()
{
if (m_mapItems.isEmpty())
return;
- m_updateMutex.lock();
for (int i = 0; i < m_mapItems.count(); ++i) {
if (m_mapItems.at(i)) {
m_mapItems.at(i).data()->setParentItem(0);
@@ -1280,7 +1274,6 @@ void QDeclarativeGeoMap::clearMapItems()
}
m_mapItems.clear();
emit mapItemsChanged();
- m_updateMutex.unlock();
}
/*!
@@ -1324,7 +1317,7 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF
if (!m_initialized)
initialize();
else
- setMinimumZoomLevel(m_map->minimumZoomForMapSize(newGeometry.width(), newGeometry.height()));
+ setMinimumZoomLevel(m_map->minimumZoomAtMapSize(newGeometry.width(), newGeometry.height()));
/*!
The fitViewportTo*() functions depend on a valid map geometry.
diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h
index d1d69656..262314ed 100644
--- a/src/imports/location/qdeclarativegeomap_p.h
+++ b/src/imports/location/qdeclarativegeomap_p.h
@@ -54,7 +54,6 @@
#include "qgeocameradata_p.h"
#include <QtQuick/QQuickItem>
#include <QtCore/QPointer>
-#include <QtCore/QMutex>
#include <QtGui/QColor>
#include <QtPositioning/qgeoshape.h>
@@ -193,7 +192,6 @@ private:
QGeoMap *m_map;
QPointer<QDeclarativeGeoMapCopyrightNotice> m_copyrights;
QList<QPointer<QDeclarativeGeoMapItemBase> > m_mapItems;
- QMutex m_updateMutex;
QString m_errorString;
QGeoServiceProvider::Error m_error;
QGeoShape m_region;
diff --git a/src/imports/location/qdeclarativepolygonmapitem.cpp b/src/imports/location/qdeclarativepolygonmapitem.cpp
index 361c554d..d997f590 100644
--- a/src/imports/location/qdeclarativepolygonmapitem.cpp
+++ b/src/imports/location/qdeclarativepolygonmapitem.cpp
@@ -661,7 +661,7 @@ MapPolygonNode::MapPolygonNode() :
geometry_(QSGGeometry::defaultAttributes_Point2D(), 0),
blocked_(true)
{
- geometry_.setDrawingMode(GL_TRIANGLES);
+ geometry_.setDrawingMode(QSGGeometry::DrawTriangles);
QSGGeometryNode::setMaterial(&fill_material_);
QSGGeometryNode::setGeometry(&geometry_);
diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp
index 2899d839..a85bbc76 100644
--- a/src/imports/location/qdeclarativepolylinemapitem.cpp
+++ b/src/imports/location/qdeclarativepolylinemapitem.cpp
@@ -958,7 +958,7 @@ MapPolylineNode::MapPolylineNode() :
geometry_(QSGGeometry::defaultAttributes_Point2D(),0),
blocked_(true)
{
- geometry_.setDrawingMode(GL_TRIANGLE_STRIP);
+ geometry_.setDrawingMode(QSGGeometry::DrawTriangleStrip);
QSGGeometryNode::setMaterial(&fill_material_);
QSGGeometryNode::setGeometry(&geometry_);
}
diff --git a/src/imports/location/qgeomapitemgeometry.cpp b/src/imports/location/qgeomapitemgeometry.cpp
index e9c490d5..513feb2a 100644
--- a/src/imports/location/qgeomapitemgeometry.cpp
+++ b/src/imports/location/qgeomapitemgeometry.cpp
@@ -70,11 +70,11 @@ void QGeoMapItemGeometry::allocateAndFill(QSGGeometry *geom) const
if (isIndexed()) {
geom->allocate(vx.size(), ix.size());
- if (geom->indexType() == GL_UNSIGNED_SHORT) {
+ if (geom->indexType() == QSGGeometry::TypeUnsignedShort) {
quint16 *its = geom->indexDataAsUShort();
for (int i = 0; i < ix.size(); ++i)
its[i] = ix[i];
- } else if (geom->indexType() == GL_UNSIGNED_INT) {
+ } else if (geom->indexType() == QSGGeometry::TypeUnsignedInt) {
quint32 *its = geom->indexDataAsUInt();
for (int i = 0; i < ix.size(); ++i)
its[i] = ix[i];
diff --git a/src/location/doc/src/plugins/mapbox.qdoc b/src/location/doc/src/plugins/mapbox.qdoc
index 6cd326ba..449df330 100644
--- a/src/location/doc/src/plugins/mapbox.qdoc
+++ b/src/location/doc/src/plugins/mapbox.qdoc
@@ -53,9 +53,6 @@ The following table lists mandatory parameters that \e must be passed to the Map
\row
\li mapbox.access_token
\li \l{https://www.mapbox.com/help/define-access-token/}{Access token} provided by Mapbox.
-\row
- \li mapbox.map_id
- \li \l{https://www.mapbox.com/help/define-map-id/}{ID} of the Mapbox map to show. An example ID is "examples.map-zr0njcqy".
\endtable
The Mapbox geo services plugin requires an access token and map ID to use the
@@ -69,13 +66,44 @@ The following table lists optional parameters that can be passed to the Mapbox p
\li Parameter
\li Description
\row
+ \li mapbox.map_id
+ \li \l{https://www.mapbox.com/help/define-map-id/}{ID} of the Mapbox map to show. An example ID is "examples.map-zr0njcqy".
+ If this parameter is present, the specified map type will be used by default, unless another is selected.
+ If not present, the default Mapbox map ID is "mapbox.streets".
+\row
+ \li mapbox.additional_map_ids
+ \li Additional, comma separated, Mapbox map IDs to be added to the available map types.
+\row
\li mapbox.format
\li Data format to download tiles in, available values are "png", "png32",
"png64", "png128", "png256", (PNG with full, 32, 64, 128 and 256 color palette)
"jpg70", "jpg80", "jpg90" (JPEG with 70%, 80% and 90% compression).
Defaults to "png".
\row
+ \li mapbox.highdpi_tiles
+ \li Whether or not to request high dpi tiles. Valid values are \b true and \b false. The default value is \b true.
+\row
\li useragent
\li User agent string set when making network requests.
+\row
+ \li mapbox.cache.directory
+ \li Absolute path to map tile cache directory used as network disk cache.
+
+ The default place for the cache is \c{QtLocation/mapbox} directory in \l {QStandardPaths::writableLocation()} {QStandardPaths::writableLocation}(\l{QStandardPaths::GenericCacheLocation}).
+ On systems that have no concept of a shared cache, the application-specific \l{QStandardPaths::CacheLocation} is used instead.
+\row
+ \li mapbox.cache.disk.size
+ \li Map tile disk cache size in bytes. Default size of the cache is 300MB.
+ Note that this is the maximum amount of data that the Mapbox free plan allows to cache.
+ Make sure to comply with Mapbox Terms of Service before increasing this value.
+\row
+ \li mapbox.cache.memory.size
+ \li Map tile memory cache size in bytes. Default size of the cache is 3MB.
+\row
+ \li mapbox.cache.texture.size
+ \li Map tile texture cache size in bytes. Default size of the cache is 6MB.
+ Note that the texture cache has a hard minimum size which depends on the size of the map viewport
+ (it must contain enough data to display the tiles currently visible on the display).
+ This value is the amount of cache to be used in addition to the bare minimum.
\endtable
*/
diff --git a/src/location/doc/src/plugins/nokia.qdoc b/src/location/doc/src/plugins/nokia.qdoc
index 1ed5e6e1..c13cec36 100644
--- a/src/location/doc/src/plugins/nokia.qdoc
+++ b/src/location/doc/src/plugins/nokia.qdoc
@@ -105,6 +105,9 @@ a prefix.
\li here.mapping.cache.texture.size
\li Map tile texture cache size in bytes. Default size of the cache is 6MB. Note that the texture cache has a hard minimum size which depends on the size of the map viewport (it must contain enough data to display the tiles currently visible on the display). This value is the amount of cache to be used in addition to the bare minimum.
\row
+ \li here.mapping.highdpi_tiles
+ \li Whether or not to request high dpi tiles. Valid values are \b true and \b false. The default value is \b true.
+\row
\li here.geocoding.host
\li Geocoding service URL used by geocoding manager.
\row
diff --git a/src/location/doc/src/plugins/osm.qdoc b/src/location/doc/src/plugins/osm.qdoc
index 75ac104d..fa75a197 100644
--- a/src/location/doc/src/plugins/osm.qdoc
+++ b/src/location/doc/src/plugins/osm.qdoc
@@ -106,6 +106,29 @@ a prefix.
If not specified the default \l {http://nominatim.openstreetmap.org/search}{url}
will be used.
\note The API documentation is available at \l {https://wiki.openstreetmap.org/wiki/Nominatim}{Project OSM Nominatim}.
+\row
+ \li osm.mapping.cache.directory
+ \li Absolute path to map tile cache directory used as network disk cache.
+
+ The default place for the cache is \c{QtLocation/osm} directory in \l {QStandardPaths::writableLocation()} {QStandardPaths::writableLocation}(\l{QStandardPaths::GenericCacheLocation}).
+ On systems that have no concept of a shared cache, the application-specific \l{QStandardPaths::CacheLocation} is used instead.
+\row
+ \li osm.mapping.offline.directory
+ \li Absolute path to a directory containing map tiles used as an offline storage. If specified, it will work together with the network disk cache, but tiles won't get automatically
+ inserted, removed or updated. The format of the tiles is the same used by the network disk cache.
+
+ There is no default value, and if this property is not set, no directory will be indexed and only the network disk cache will be used
+ to reduce network usage or to act as an offline storage for the currently cached tiles.
+\row
+ \li osm.mapping.cache.disk.size
+ \li Map tile disk cache size in bytes. Default size of the cache is 100MB.
+\row
+ \li osm.mapping.cache.memory.size
+ \li Map tile memory cache size in bytes. Default size of the cache is 3MB.
+\row
+ \li osm.mapping.cache.texture.size
+ \li Map tile texture cache size in bytes. Default size of the cache is 6MB. Note that the texture cache has a hard minimum size which depends on the size of the map viewport (it must contain enough data to display the tiles currently visible on the display). This value is the amount of cache to be used in addition to the bare minimum.
+
\endtable
\section1 Parameter Usage Example
diff --git a/src/location/maps/qabstractgeotilecache_p.h b/src/location/maps/qabstractgeotilecache_p.h
index 141aa9b4..bf1e56b9 100644
--- a/src/location/maps/qabstractgeotilecache_p.h
+++ b/src/location/maps/qabstractgeotilecache_p.h
@@ -116,8 +116,10 @@ public:
protected:
QAbstractGeoTileCache(QObject *parent = 0);
-
+ virtual void init() = 0;
virtual void printStats() = 0;
+
+ friend class QGeoTiledMappingManagerEngine;
};
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeofiletilecache.cpp b/src/location/maps/qgeofiletilecache.cpp
index 3d381dc2..fd6bbc38 100644
--- a/src/location/maps/qgeofiletilecache.cpp
+++ b/src/location/maps/qgeofiletilecache.cpp
@@ -86,8 +86,12 @@ QGeoCachedTileDisk::~QGeoCachedTileDisk()
}
QGeoFileTileCache::QGeoFileTileCache(const QString &directory, QObject *parent)
- : QAbstractGeoTileCache(parent), directory_(directory),
- minTextureUsage_(0), extraTextureUsage_(0)
+ : QAbstractGeoTileCache(parent), directory_(directory), minTextureUsage_(0), extraTextureUsage_(0)
+{
+
+}
+
+void QGeoFileTileCache::init()
{
const QString basePath = baseCacheDirectory();
@@ -276,43 +280,10 @@ void QGeoFileTileCache::clearAll()
QSharedPointer<QGeoTileTexture> QGeoFileTileCache::get(const QGeoTileSpec &spec)
{
- QSharedPointer<QGeoTileTexture> tt = textureCache_.object(spec);
+ QSharedPointer<QGeoTileTexture> tt = getFromMemory(spec);
if (tt)
return tt;
-
- QSharedPointer<QGeoCachedTileMemory> tm = memoryCache_.object(spec);
- if (tm) {
- QImage image;
- if (!image.loadFromData(tm->bytes)) {
- handleError(spec, QLatin1String("Problem with tile image"));
- return QSharedPointer<QGeoTileTexture>(0);
- }
- QSharedPointer<QGeoTileTexture> tt = addToTextureCache(spec, image);
- if (tt)
- return tt;
- }
-
- QSharedPointer<QGeoCachedTileDisk> td = diskCache_.object(spec);
- if (td) {
- const QString format = QFileInfo(td->filename).suffix();
- QFile file(td->filename);
- file.open(QIODevice::ReadOnly);
- QByteArray bytes = file.readAll();
- file.close();
-
- QImage image;
- if (!image.loadFromData(bytes)) {
- handleError(spec, QLatin1String("Problem with tile image"));
- return QSharedPointer<QGeoTileTexture>(0);
- }
-
- addToMemoryCache(spec, bytes, format);
- QSharedPointer<QGeoTileTexture> tt = addToTextureCache(td->spec, image);
- if (tt)
- return tt;
- }
-
- return QSharedPointer<QGeoTileTexture>();
+ return getFromDisk(spec);
}
void QGeoFileTileCache::insert(const QGeoTileSpec &spec,
@@ -390,7 +361,52 @@ QSharedPointer<QGeoTileTexture> QGeoFileTileCache::addToTextureCache(const QGeoT
return tt;
}
-QString QGeoFileTileCache::tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory)
+QSharedPointer<QGeoTileTexture> QGeoFileTileCache::getFromMemory(const QGeoTileSpec &spec)
+{
+ QSharedPointer<QGeoTileTexture> tt = textureCache_.object(spec);
+ if (tt)
+ return tt;
+
+ QSharedPointer<QGeoCachedTileMemory> tm = memoryCache_.object(spec);
+ if (tm) {
+ QImage image;
+ if (!image.loadFromData(tm->bytes)) {
+ handleError(spec, QLatin1String("Problem with tile image"));
+ return QSharedPointer<QGeoTileTexture>(0);
+ }
+ QSharedPointer<QGeoTileTexture> tt = addToTextureCache(spec, image);
+ if (tt)
+ return tt;
+ }
+ return QSharedPointer<QGeoTileTexture>();
+}
+
+QSharedPointer<QGeoTileTexture> QGeoFileTileCache::getFromDisk(const QGeoTileSpec &spec)
+{
+ QSharedPointer<QGeoCachedTileDisk> td = diskCache_.object(spec);
+ if (td) {
+ const QString format = QFileInfo(td->filename).suffix();
+ QFile file(td->filename);
+ file.open(QIODevice::ReadOnly);
+ QByteArray bytes = file.readAll();
+ file.close();
+
+ QImage image;
+ if (!image.loadFromData(bytes)) {
+ handleError(spec, QLatin1String("Problem with tile image"));
+ return QSharedPointer<QGeoTileTexture>(0);
+ }
+
+ addToMemoryCache(spec, bytes, format);
+ QSharedPointer<QGeoTileTexture> tt = addToTextureCache(td->spec, image);
+ if (tt)
+ return tt;
+ }
+
+ return QSharedPointer<QGeoTileTexture>();
+}
+
+QString QGeoFileTileCache::tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const
{
QString filename = spec.plugin();
filename += QLatin1String("-");
@@ -416,7 +432,7 @@ QString QGeoFileTileCache::tileSpecToFilename(const QGeoTileSpec &spec, const QS
return dir.filePath(filename);
}
-QGeoTileSpec QGeoFileTileCache::filenameToTileSpec(const QString &filename)
+QGeoTileSpec QGeoFileTileCache::filenameToTileSpec(const QString &filename) const
{
QGeoTileSpec emptySpec;
diff --git a/src/location/maps/qgeofiletilecache_p.h b/src/location/maps/qgeofiletilecache_p.h
index bd3e684b..b6d4919f 100644
--- a/src/location/maps/qgeofiletilecache_p.h
+++ b/src/location/maps/qgeofiletilecache_p.h
@@ -128,7 +128,8 @@ public:
const QString &format,
QGeoTiledMappingManagerEngine::CacheAreas areas = QGeoTiledMappingManagerEngine::AllCaches) Q_DECL_OVERRIDE;
-private:
+protected:
+ void init() Q_DECL_OVERRIDE;
void printStats() Q_DECL_OVERRIDE;
void loadTiles();
@@ -137,9 +138,11 @@ private:
QSharedPointer<QGeoCachedTileDisk> addToDiskCache(const QGeoTileSpec &spec, const QString &filename);
QSharedPointer<QGeoCachedTileMemory> addToMemoryCache(const QGeoTileSpec &spec, const QByteArray &bytes, const QString &format);
QSharedPointer<QGeoTileTexture> addToTextureCache(const QGeoTileSpec &spec, const QImage &image);
+ QSharedPointer<QGeoTileTexture> getFromMemory(const QGeoTileSpec &spec);
+ QSharedPointer<QGeoTileTexture> getFromDisk(const QGeoTileSpec &spec);
- static QString tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory);
- static QGeoTileSpec filenameToTileSpec(const QString &filename);
+ virtual QString tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const;
+ virtual QGeoTileSpec filenameToTileSpec(const QString &filename) const;
QCache3Q<QGeoTileSpec, QGeoCachedTileDisk, QCache3QTileEvictionPolicy > diskCache_;
QCache3Q<QGeoTileSpec, QGeoCachedTileMemory > memoryCache_;
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index 021c440b..339d6dfb 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -84,9 +84,8 @@ public:
virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const = 0;
virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const = 0;
-
- virtual double minimumZoomForMapSize(int width, int height) const = 0;
- virtual double maximumLatitudeForZoom(double zoomLevel) const = 0;
+ virtual double minimumZoomAtMapSize(int width, int height) const = 0;
+ virtual double maximumCenterLatitudeAtZoom(double zoomLevel) const = 0;
virtual QDoubleVector2D referenceCoordinateToItemPosition(const QGeoCoordinate &coordinate) const = 0;
virtual QGeoCoordinate referenceItemPositionToCoordinate(const QDoubleVector2D &pos) const = 0;
diff --git a/src/location/maps/qgeotiledmap.cpp b/src/location/maps/qgeotiledmap.cpp
index a6cbb294..f59417f7 100644
--- a/src/location/maps/qgeotiledmap.cpp
+++ b/src/location/maps/qgeotiledmap.cpp
@@ -164,7 +164,7 @@ QDoubleVector2D QGeoTiledMap::coordinateToItemPosition(const QGeoCoordinate &coo
// This method returns the minimum zoom level that this specific qgeomap type allows
// at a given canvas size (width,height) and for a given tile size (usually 256).
-double QGeoTiledMap::minimumZoomForMapSize(int width, int height) const
+double QGeoTiledMap::minimumZoomAtMapSize(int width, int height) const
{
Q_D(const QGeoTiledMap);
double maxSize = qMax(width,height);
@@ -178,7 +178,7 @@ double QGeoTiledMap::minimumZoomForMapSize(int width, int height) const
// the amount of pixels between the center and the borders changes
// 2) when the zoom level changes, because the amount of pixels between the center
// and the borders stays the same, but the meters per pixel change
-double QGeoTiledMap::maximumLatitudeForZoom(double zoomLevel) const
+double QGeoTiledMap::maximumCenterLatitudeAtZoom(double zoomLevel) const
{
Q_D(const QGeoTiledMap);
double mapEdgeSize = std::pow(2.0,zoomLevel);
diff --git a/src/location/maps/qgeotiledmap_p.h b/src/location/maps/qgeotiledmap_p.h
index 813e342d..220d422f 100644
--- a/src/location/maps/qgeotiledmap_p.h
+++ b/src/location/maps/qgeotiledmap_p.h
@@ -86,9 +86,9 @@ 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;
+ double minimumZoomAtMapSize(int width, int height) const Q_DECL_OVERRIDE;
+ double maximumCenterLatitudeAtZoom(double zoomLevel) const Q_DECL_OVERRIDE;
- double minimumZoomForMapSize(int width, int height) const Q_DECL_OVERRIDE;
- double maximumLatitudeForZoom(double zoomLevel) const Q_DECL_OVERRIDE;
QDoubleVector2D referenceCoordinateToItemPosition(const QGeoCoordinate &coordinate) const Q_DECL_OVERRIDE;
QGeoCoordinate referenceItemPositionToCoordinate(const QDoubleVector2D &pos) const Q_DECL_OVERRIDE;
diff --git a/src/location/maps/qgeotiledmappingmanagerengine.cpp b/src/location/maps/qgeotiledmappingmanagerengine.cpp
index dc5f1889..1aaae4c6 100644
--- a/src/location/maps/qgeotiledmappingmanagerengine.cpp
+++ b/src/location/maps/qgeotiledmappingmanagerengine.cpp
@@ -289,6 +289,7 @@ void QGeoTiledMappingManagerEngine::setTileCache(QAbstractGeoTileCache *cache)
Q_ASSERT_X(!d->tileCache_, Q_FUNC_INFO, "This should be called only once");
cache->setParent(this);
d->tileCache_ = cache;
+ d->tileCache_->init();
}
QAbstractGeoTileCache *QGeoTiledMappingManagerEngine::tileCache()
@@ -299,6 +300,7 @@ QAbstractGeoTileCache *QGeoTiledMappingManagerEngine::tileCache()
if (!managerName().isEmpty())
cacheDirectory = QAbstractGeoTileCache::baseCacheDirectory() + managerName();
d->tileCache_ = new QGeoFileTileCache(cacheDirectory);
+ d->tileCache_->init();
}
return d->tileCache_;
}
diff --git a/src/location/maps/qgeotiledmapscene.cpp b/src/location/maps/qgeotiledmapscene.cpp
index 57750f4d..33c0bb8c 100644
--- a/src/location/maps/qgeotiledmapscene.cpp
+++ b/src/location/maps/qgeotiledmapscene.cpp
@@ -40,7 +40,7 @@
#include "qgeotilespec_p.h"
#include <QtPositioning/private/qdoublevector3d_p.h>
#include <QtCore/private/qobject_p.h>
-#include <QtQuick/QSGSimpleTextureNode>
+#include <QtQuick/QSGImageNode>
#include <QtQuick/QQuickWindow>
#include <cmath>
@@ -108,7 +108,7 @@ public:
void setVisibleTiles(const QSet<QGeoTileSpec> &tiles);
void removeTiles(const QSet<QGeoTileSpec> &oldTiles);
- bool buildGeometry(const QGeoTileSpec &spec, QSGGeometry::TexturedPoint2D *vertices);
+ bool buildGeometry(const QGeoTileSpec &spec, QSGImageNode *imageNode);
void setTileBounds(const QSet<QGeoTileSpec> &tiles);
void setupCamera();
};
@@ -292,7 +292,7 @@ QDoubleVector2D QGeoTiledMapScenePrivate::mercatorToItemPosition(const QDoubleVe
return QDoubleVector2D(x + m_screenOffsetX, y + m_screenOffsetY);
}
-bool QGeoTiledMapScenePrivate::buildGeometry(const QGeoTileSpec &spec, QSGGeometry::TexturedPoint2D *vertices)
+bool QGeoTiledMapScenePrivate::buildGeometry(const QGeoTileSpec &spec, QSGImageNode *imageNode)
{
int x = spec.x();
@@ -320,11 +320,9 @@ bool QGeoTiledMapScenePrivate::buildGeometry(const QGeoTileSpec &spec, QSGGeomet
y1 *= edge;
y2 *= edge;
- //Texture coordinate order for veritcal flip of texture
- vertices[0].set(x1, y1, 0, 0);
- vertices[1].set(x1, y2, 0, 1);
- vertices[2].set(x2, y1, 1, 0);
- vertices[3].set(x2, y2, 1, 1);
+ imageNode->setRect(QRectF(QPointF(x1, y2), QPointF(x2, y1)));
+ imageNode->setTextureCoordinatesTransform(QSGImageNode::MirrorVertically);
+ imageNode->setSourceRect(QRectF(QPointF(0,0), imageNode->texture()->textureSize()));
return true;
}
@@ -559,12 +557,12 @@ void QGeoTiledMapScenePrivate::setupCamera()
class QGeoTiledMapTileContainerNode : public QSGTransformNode
{
public:
- void addChild(const QGeoTileSpec &spec, QSGSimpleTextureNode *node)
+ void addChild(const QGeoTileSpec &spec, QSGImageNode *node)
{
tiles.insert(spec, node);
appendChildNode(node);
}
- QHash<QGeoTileSpec, QSGSimpleTextureNode *> tiles;
+ QHash<QGeoTileSpec, QSGImageNode *> tiles;
};
class QGeoTiledMapRootNode : public QSGClipNode
@@ -601,7 +599,10 @@ public:
}
}
- void updateTiles(QGeoTiledMapTileContainerNode *root, QGeoTiledMapScenePrivate *d, double camAdjust);
+ void updateTiles(QGeoTiledMapTileContainerNode *root,
+ QGeoTiledMapScenePrivate *d,
+ double camAdjust,
+ QQuickWindow *window);
bool isTextureLinear;
@@ -617,11 +618,9 @@ public:
QHash<QGeoTileSpec, QSGTexture *> textures;
};
-static bool qgeotiledmapscene_isTileInViewport(const QSGGeometry::TexturedPoint2D *tp, const QMatrix4x4 &matrix) {
- QPolygonF polygon; polygon.reserve(4);
- for (int i=0; i<4; ++i)
- polygon << matrix * QPointF(tp[i].x, tp[i].y);
- return QRectF(-1, -1, 2, 2).intersects(polygon.boundingRect());
+static bool qgeotiledmapscene_isTileInViewport(const QRectF &tileRect, const QMatrix4x4 &matrix) {
+ const QRectF boundingRect = QRectF(matrix * tileRect.topLeft(), matrix * tileRect.bottomRight());
+ return QRectF(-1, -1, 2, 2).intersects(boundingRect);
}
static QVector3D toVector3D(const QDoubleVector3D& in)
@@ -630,8 +629,9 @@ static QVector3D toVector3D(const QDoubleVector3D& in)
}
void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
- QGeoTiledMapScenePrivate *d,
- double camAdjust)
+ QGeoTiledMapScenePrivate *d,
+ double camAdjust,
+ QQuickWindow *window)
{
// Set up the matrix...
QDoubleVector3D eye = d->m_cameraEye;
@@ -649,23 +649,12 @@ void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
foreach (const QGeoTileSpec &s, toRemove)
delete root->tiles.take(s);
- for (QHash<QGeoTileSpec, QSGSimpleTextureNode *>::iterator it = root->tiles.begin();
+ for (QHash<QGeoTileSpec, QSGImageNode *>::iterator it = root->tiles.begin();
it != root->tiles.end(); ) {
- QSGGeometry visualGeometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4);
- QSGGeometry::TexturedPoint2D *v = visualGeometry.vertexDataAsTexturedPoint2D();
- bool ok = d->buildGeometry(it.key(), v) && qgeotiledmapscene_isTileInViewport(v, root->matrix());
- QSGSimpleTextureNode *node = it.value();
- QSGNode::DirtyState dirtyBits = 0;
+ QSGImageNode *node = it.value();
+ bool ok = d->buildGeometry(it.key(), node) && qgeotiledmapscene_isTileInViewport(node->rect(), root->matrix());
- // Check and handle changes to vertex data.
- if (ok && memcmp(node->geometry()->vertexData(), v, 4 * sizeof(QSGGeometry::TexturedPoint2D)) != 0) {
- if (v[0].x == v[3].x || v[0].y == v[3].y) { // top-left == bottom-right => invalid => remove
- ok = false;
- } else {
- memcpy(node->geometry()->vertexData(), v, 4 * sizeof(QSGGeometry::TexturedPoint2D));
- dirtyBits |= QSGNode::DirtyGeometry;
- }
- }
+ QSGNode::DirtyState dirtyBits = 0;
if (!ok) {
it = root->tiles.erase(it);
@@ -673,6 +662,8 @@ void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
} else {
if (isTextureLinear != d->m_linearScaling) {
node->setFiltering(d->m_linearScaling ? QSGTexture::Linear : QSGTexture::Nearest);
+ if (node->texture()->textureSize().width() > d->m_tileSize)
+ node->setMipmapFiltering(QSGTexture::Linear);
dirtyBits |= QSGNode::DirtyMaterial;
}
if (dirtyBits != 0)
@@ -685,15 +676,13 @@ void QGeoTiledMapRootNode::updateTiles(QGeoTiledMapTileContainerNode *root,
QGeoTileTexture *tileTexture = d->m_textures.value(s).data();
if (!tileTexture || tileTexture->image.isNull())
continue;
- QSGSimpleTextureNode *tileNode = new QSGSimpleTextureNode();
+ QSGImageNode *tileNode = window->createImageNode();
// note: setTexture will update coordinates so do it here, before we buildGeometry
tileNode->setTexture(textures.value(s));
- Q_ASSERT(tileNode->geometry());
- Q_ASSERT(tileNode->geometry()->attributes() == QSGGeometry::defaultAttributes_TexturedPoint2D().attributes);
- Q_ASSERT(tileNode->geometry()->vertexCount() == 4);
- if (d->buildGeometry(s, tileNode->geometry()->vertexDataAsTexturedPoint2D())
- && qgeotiledmapscene_isTileInViewport(tileNode->geometry()->vertexDataAsTexturedPoint2D(), root->matrix())) {
+ if (d->buildGeometry(s, tileNode) && qgeotiledmapscene_isTileInViewport(tileNode->rect(), root->matrix())) {
tileNode->setFiltering(d->m_linearScaling ? QSGTexture::Linear : QSGTexture::Nearest);
+ if (tileNode->texture()->textureSize().width() > d->m_tileSize)
+ tileNode->setMipmapFiltering(QSGTexture::Linear);
root->addChild(s, tileNode);
} else {
delete tileNode;
@@ -737,9 +726,9 @@ QSGNode *QGeoTiledMapScene::updateSceneGraph(QSGNode *oldNode, QQuickWindow *win
}
double sideLength = d->m_scaleFactor * d->m_tileSize * d->m_sideLength;
- mapRoot->updateTiles(mapRoot->tiles, d, 0);
- mapRoot->updateTiles(mapRoot->wrapLeft, d, +sideLength);
- mapRoot->updateTiles(mapRoot->wrapRight, d, -sideLength);
+ mapRoot->updateTiles(mapRoot->tiles, d, 0, window);
+ mapRoot->updateTiles(mapRoot->wrapLeft, d, +sideLength, window);
+ mapRoot->updateTiles(mapRoot->wrapRight, d, -sideLength, window);
mapRoot->isTextureLinear = d->m_linearScaling;
diff --git a/src/plugins/geoservices/mapbox/mapbox.pro b/src/plugins/geoservices/mapbox/mapbox.pro
index d4797e37..ea011131 100644
--- a/src/plugins/geoservices/mapbox/mapbox.pro
+++ b/src/plugins/geoservices/mapbox/mapbox.pro
@@ -6,13 +6,19 @@ HEADERS += \
qgeoserviceproviderpluginmapbox.h \
qgeotiledmappingmanagerenginemapbox.h \
qgeotilefetchermapbox.h \
- qgeomapreplymapbox.h
+ qgeomapreplymapbox.h \
+ qgeofiletilecachemapbox.h \
+ qgeoroutingmanagerenginemapbox.h \
+ qgeoroutereplymapbox.h
SOURCES += \
qgeoserviceproviderpluginmapbox.cpp \
qgeotiledmappingmanagerenginemapbox.cpp \
qgeotilefetchermapbox.cpp \
- qgeomapreplymapbox.cpp
+ qgeomapreplymapbox.cpp \
+ qgeofiletilecachemapbox.cpp \
+ qgeoroutingmanagerenginemapbox.cpp \
+ qgeoroutereplymapbox.cpp
OTHER_FILES += \
mapbox_plugin.json
diff --git a/src/plugins/geoservices/mapbox/mapbox_plugin.json b/src/plugins/geoservices/mapbox/mapbox_plugin.json
index 0b8d08af..f886458f 100644
--- a/src/plugins/geoservices/mapbox/mapbox_plugin.json
+++ b/src/plugins/geoservices/mapbox/mapbox_plugin.json
@@ -4,6 +4,7 @@
"Version": 100,
"Experimental": false,
"Features": [
- "OnlineMappingFeature"
+ "OnlineMappingFeature",
+ "OnlineRoutingFeature"
]
}
diff --git a/src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.cpp b/src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.cpp
new file mode 100644
index 00000000..6ce41a2b
--- /dev/null
+++ b/src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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 "qgeofiletilecachemapbox.h"
+#include <QtLocation/private/qgeotilespec_p.h>
+#include <QDir>
+
+QT_BEGIN_NAMESPACE
+
+QGeoFileTileCacheMapbox::QGeoFileTileCacheMapbox(const QList<QGeoMapType> &mapTypes, int scaleFactor, const QString &directory, QObject *parent)
+ :QGeoFileTileCache(directory, parent), m_mapTypes(mapTypes)
+{
+ m_scaleFactor = qBound(1, scaleFactor, 2);
+ for (int i=0; i < mapTypes.size(); i++)
+ m_mapNameToId.insert(mapTypes[i].name(), i);
+}
+
+QGeoFileTileCacheMapbox::~QGeoFileTileCacheMapbox()
+{
+
+}
+
+QString QGeoFileTileCacheMapbox::tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const
+{
+ QString filename = spec.plugin();
+ filename += QLatin1String("-");
+ filename += m_mapTypes[spec.mapId()].name();
+ filename += QLatin1String("-");
+ filename += QString::number(spec.zoom());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.x());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.y());
+
+ //Append version if real version number to ensure backwards compatibility and eviction of old tiles
+ if (spec.version() != -1) {
+ filename += QLatin1String("-");
+ filename += QString::number(spec.version());
+ }
+
+ filename += QLatin1String("-@");
+ filename += QString::number(m_scaleFactor);
+ filename += QLatin1Char('x');
+
+ filename += QLatin1String(".");
+ filename += format;
+
+ QDir dir = QDir(directory);
+
+ return dir.filePath(filename);
+}
+
+QGeoTileSpec QGeoFileTileCacheMapbox::filenameToTileSpec(const QString &filename) const
+{
+ QStringList parts = filename.split('.');
+
+ if (parts.length() != 2)
+ return QGeoTileSpec();
+
+ QString name = parts.at(0);
+ QStringList fields = name.split('-');
+
+ int length = fields.length();
+ if (length != 6 && length != 7) {
+ return QGeoTileSpec();
+ } else {
+ int scaleIdx = fields.last().indexOf("@");
+ if (scaleIdx < 0 || fields.last().size() <= (scaleIdx + 2))
+ return QGeoTileSpec();
+ int scaleFactor = fields.last()[scaleIdx + 1].digitValue();
+ if (scaleFactor != m_scaleFactor)
+ return QGeoTileSpec();
+ }
+
+ QList<int> numbers;
+
+ bool ok = false;
+ for (int i = 2; i < length-1; ++i) { // skipping -@_X
+ ok = false;
+ int value = fields.at(i).toInt(&ok);
+ if (!ok)
+ return QGeoTileSpec();
+ numbers.append(value);
+ }
+
+ //File name without version, append default
+ if (numbers.length() < 4)
+ numbers.append(-1);
+
+ return QGeoTileSpec(fields.at(0),
+ m_mapNameToId[fields.at(1)],
+ numbers.at(0),
+ numbers.at(1),
+ numbers.at(2),
+ numbers.at(3));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.h b/src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.h
new file mode 100644
index 00000000..faf9b2bf
--- /dev/null
+++ b/src/plugins/geoservices/mapbox/qgeofiletilecachemapbox.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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 QGEOFILETILECACHEMAPBOX_H
+#define QGEOFILETILECACHEMAPBOX_H
+
+#include <QtLocation/private/qgeofiletilecache_p.h>
+#include <QMap>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoFileTileCacheMapbox : public QGeoFileTileCache
+{
+ Q_OBJECT
+public:
+ QGeoFileTileCacheMapbox(const QList<QGeoMapType> &mapTypes, int scaleFactor, const QString &directory = QString(), QObject *parent = 0);
+ ~QGeoFileTileCacheMapbox();
+
+protected:
+ QString tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const Q_DECL_OVERRIDE;
+ QGeoTileSpec filenameToTileSpec(const QString &filename) const Q_DECL_OVERRIDE;
+
+ QList<QGeoMapType> m_mapTypes;
+ QMap<QString, int> m_mapNameToId;
+ int m_scaleFactor;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOFILETILECACHEMAPBOX_H
diff --git a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
new file mode 100644
index 00000000..4c98412b
--- /dev/null
+++ b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Vlad Seryakov <vseryakov@gmail.com>
+** Copyright (C) 2016 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgeoroutereplymapbox.h"
+
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonArray>
+#include <QtLocation/QGeoRouteSegment>
+#include <QtLocation/QGeoManeuver>
+
+QT_BEGIN_NAMESPACE
+
+static QList<QGeoCoordinate> parsePolyline(const QString &line)
+{
+ QList<QGeoCoordinate> path;
+ QByteArray data(line.toLocal8Bit());
+
+ int mode = 0, shift = 0, value = 0, coord[2] = {0, 0};
+ for (int i = 0; i < data.length(); ++i) {
+ int c = data.at(i) - 63;
+ value |= (c & 0x1f) << shift;
+ shift += 5;
+ if (c & 0x20) continue;
+ coord[mode] += (value & 1) ? ~(value >> 1) : (value >> 1);
+ if (mode) path.append(QGeoCoordinate((double)coord[0]/1e5, (double)coord[1]/1e5));
+ mode = 1 - mode;
+ value = shift = 0;
+ }
+ return path;
+}
+
+static QList<QGeoCoordinate> parseGeometry(const QJsonValue &geometry)
+{
+ QList<QGeoCoordinate> path;
+ if (geometry.isString()) path = parsePolyline(geometry.toString());
+ if (geometry.isObject()) {
+ QJsonArray coords = geometry.toObject().value(QStringLiteral("coordinates")).toArray();
+ for (int i = 0; i < coords.count(); i++) {
+ QJsonArray coord = coords.at(i).toArray();
+ if (coord.count() != 2) continue;
+ path.append(QGeoCoordinate(coord.at(1).toDouble(), coord.at(0).toDouble()));
+ }
+ }
+ return path;
+}
+
+QGeoRouteReplyMapbox::QGeoRouteReplyMapbox(QNetworkReply *reply, const QGeoRouteRequest &request,
+ QObject *parent)
+: QGeoRouteReply(request, parent), m_reply(reply)
+{
+ connect(m_reply, SIGNAL(finished()), this, SLOT(networkReplyFinished()));
+ connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(networkReplyError(QNetworkReply::NetworkError)));
+}
+
+QGeoRouteReplyMapbox::~QGeoRouteReplyMapbox()
+{
+ if (m_reply)
+ m_reply->deleteLater();
+}
+
+void QGeoRouteReplyMapbox::abort()
+{
+ if (!m_reply)
+ return;
+
+ m_reply->abort();
+
+ m_reply->deleteLater();
+ m_reply = 0;
+}
+
+static QGeoRoute constructRoute(const QJsonObject &obj)
+{
+ QGeoRoute route;
+ route.setDistance(obj.value(QStringLiteral("distance")).toDouble());
+ route.setTravelTime(obj.value(QStringLiteral("duration")).toDouble());
+
+ QList<QGeoCoordinate> path = parseGeometry(obj.value(QStringLiteral("geometry")));
+ route.setPath(path);
+
+ QGeoRouteSegment firstSegment, lastSegment;
+ QJsonArray legs = obj.value(QStringLiteral("legs")).toArray();
+
+ for (int i = 0; i < legs.count(); i++) {
+ QJsonObject leg = legs.at(i).toObject();
+ QJsonArray steps = leg.value("steps").toArray();
+
+ for (int j = 0; j < steps.count(); j++) {
+ QJsonObject step = steps.at(j).toObject();
+ QJsonObject stepManeuver = step.value("maneuver").toObject();
+
+ QGeoRouteSegment segment;
+ segment.setDistance(step.value("distance").toDouble());
+ segment.setTravelTime(step.value(QStringLiteral("duration")).toDouble());
+
+ QGeoManeuver maneuver;
+ maneuver.setDistanceToNextInstruction(step.value("distance").toDouble());
+ maneuver.setInstructionText(stepManeuver.value("instruction").toString());
+ maneuver.setTimeToNextInstruction(step.value(QStringLiteral("duration")).toDouble());
+ QJsonArray location = stepManeuver.value(QStringLiteral("location")).toArray();
+ if (location.count() > 1)
+ maneuver.setPosition(QGeoCoordinate(location.at(0).toDouble(), location.at(1).toDouble()));
+
+ QString modifier = stepManeuver.value("modifier").toString();
+ int bearing1 = stepManeuver.value("bearing_before").toInt();
+ int bearing2 = stepManeuver.value("bearing_after").toInt();
+
+ if (modifier == "straight")
+ maneuver.setDirection(QGeoManeuver::DirectionForward);
+ else if (modifier == "slight right")
+ maneuver.setDirection(QGeoManeuver::DirectionLightRight);
+ else if (modifier == "right")
+ maneuver.setDirection(QGeoManeuver::DirectionRight);
+ else if (modifier == "sharp right")
+ maneuver.setDirection(QGeoManeuver::DirectionHardRight);
+ else if (modifier == "uturn")
+ maneuver.setDirection(bearing2 - bearing1 > 180 ? QGeoManeuver::DirectionUTurnLeft : QGeoManeuver::DirectionUTurnRight);
+ else if (modifier == "sharp left")
+ maneuver.setDirection(QGeoManeuver::DirectionHardLeft);
+ else if (modifier == "left")
+ maneuver.setDirection(QGeoManeuver::DirectionLeft);
+ else if (modifier == "slight left")
+ maneuver.setDirection(QGeoManeuver::DirectionLightLeft);
+ else
+ maneuver.setDirection(QGeoManeuver::NoDirection);
+
+ segment.setManeuver(maneuver);
+ segment.setPath(parseGeometry(step.value(QStringLiteral("geometry"))));
+
+ if (!firstSegment.isValid()) firstSegment = segment;
+ if (lastSegment.isValid()) lastSegment.setNextRouteSegment(segment);
+ lastSegment = segment;
+ }
+ }
+ route.setFirstRouteSegment(firstSegment);
+ return route;
+}
+
+void QGeoRouteReplyMapbox::networkReplyFinished()
+{
+ if (!m_reply)
+ return;
+
+ if (m_reply->error() != QNetworkReply::NoError) {
+ setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
+ m_reply->deleteLater();
+ m_reply = 0;
+ return;
+ }
+
+ QJsonDocument document = QJsonDocument::fromJson(m_reply->readAll());
+ if (document.isObject()) {
+ QJsonObject object = document.object();
+
+ QString status = object.value(QStringLiteral("code")).toString();
+ if (status != QStringLiteral("Ok")) {
+ setError(QGeoRouteReply::UnknownError, object.value(QStringLiteral("message")).toString());
+ m_reply->deleteLater();
+ m_reply = 0;
+ return;
+ }
+
+ QList<QGeoRoute> list;
+ QJsonArray routes = object.value(QStringLiteral("routes")).toArray();
+ for (int i = 0; i < routes.count(); i++) {
+ QGeoRoute route = constructRoute(routes.at(i).toObject());
+ list.append(route);
+ }
+ setRoutes(list);
+ setFinished(true);
+ } else {
+ setError(QGeoRouteReply::ParseError, QStringLiteral("Couldn't parse json."));
+ }
+
+ m_reply->deleteLater();
+ m_reply = 0;
+}
+
+void QGeoRouteReplyMapbox::networkReplyError(QNetworkReply::NetworkError error)
+{
+ Q_UNUSED(error)
+
+ if (!m_reply)
+ return;
+
+ setError(QGeoRouteReply::CommunicationError, m_reply->errorString());
+
+ m_reply->deleteLater();
+ m_reply = 0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h
new file mode 100644
index 00000000..9df45ac4
--- /dev/null
+++ b/src/plugins/geoservices/mapbox/qgeoroutereplymapbox.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Vlad Seryakov <vseryakov@gmail.com>
+** Copyright (C) 2016 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGEOROUTEREPLYMAPBOX_H
+#define QGEOROUTEREPLYMAPBOX_H
+
+#include <QtNetwork/QNetworkReply>
+#include <QtLocation/QGeoRouteReply>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoRouteReplyMapbox : public QGeoRouteReply
+{
+ Q_OBJECT
+
+public:
+ explicit QGeoRouteReplyMapbox(QObject *parent = 0);
+ QGeoRouteReplyMapbox(QNetworkReply *reply, const QGeoRouteRequest &request, QObject *parent = 0);
+ ~QGeoRouteReplyMapbox();
+
+ void abort() Q_DECL_OVERRIDE;
+
+private Q_SLOTS:
+ void networkReplyFinished();
+ void networkReplyError(QNetworkReply::NetworkError error);
+
+private:
+ QNetworkReply *m_reply;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOROUTEREPLYMAPBOX_H
+
diff --git a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
new file mode 100644
index 00000000..d6ef8f0a
--- /dev/null
+++ b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.cpp
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Vlad Seryakov <vseryakov@gmail.com>
+** Copyright (C) 2016 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgeoroutingmanagerenginemapbox.h"
+#include "qgeoroutereplymapbox.h"
+
+#include <QtCore/QUrlQuery>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+QGeoRoutingManagerEngineMapbox::QGeoRoutingManagerEngineMapbox(const QVariantMap &parameters,
+ QGeoServiceProvider::Error *error,
+ QString *errorString)
+ : QGeoRoutingManagerEngine(parameters),
+ m_networkManager(new QNetworkAccessManager(this)),
+ m_userAgent("Qt Location based application")
+{
+ if (parameters.contains(QStringLiteral("mapbox.useragent"))) {
+ m_userAgent = parameters.value(QStringLiteral("mapbox.useragent")).toString().toLatin1();
+ }
+
+ if (parameters.contains(QStringLiteral("mapbox.access_token"))) {
+ m_accessToken = parameters.value(QStringLiteral("mapbox.access_token")).toString();
+ }
+
+ *error = QGeoServiceProvider::NoError;
+ errorString->clear();
+}
+
+QGeoRoutingManagerEngineMapbox::~QGeoRoutingManagerEngineMapbox()
+{
+}
+
+QGeoRouteReply* QGeoRoutingManagerEngineMapbox::calculateRoute(const QGeoRouteRequest &request)
+{
+ QNetworkRequest networkRequest;
+ networkRequest.setRawHeader("User-Agent", m_userAgent);
+
+ QString url("https://api.mapbox.com/directions/v5/mapbox/");
+
+ QGeoRouteRequest::TravelModes travelModes = request.travelModes();
+ if (travelModes.testFlag(QGeoRouteRequest::PedestrianTravel))
+ url += "walking/";
+ else
+ if (travelModes.testFlag(QGeoRouteRequest::BicycleTravel))
+ url += "cycling/";
+ else
+ if (travelModes.testFlag(QGeoRouteRequest::CarTravel))
+ url += "driving/";
+
+ foreach (const QGeoCoordinate &c, request.waypoints()) {
+ url += QString("%1,%2;").arg(c.longitude()).arg(c.latitude());
+ }
+ if (url.right(1) == ";") url.chop(1);
+ url += QString("?steps=true&overview=full&geometries=geojson&access_token=%1").arg(m_accessToken);
+
+ networkRequest.setUrl(QUrl(url));
+
+ QNetworkReply *reply = m_networkManager->get(networkRequest);
+ QGeoRouteReplyMapbox *routeReply = new QGeoRouteReplyMapbox(reply, request, this);
+
+ connect(routeReply, SIGNAL(finished()), this, SLOT(replyFinished()));
+ connect(routeReply, SIGNAL(error(QGeoRouteReply::Error,QString)),
+ this, SLOT(replyError(QGeoRouteReply::Error,QString)));
+
+ return routeReply;
+}
+
+void QGeoRoutingManagerEngineMapbox::replyFinished()
+{
+ QGeoRouteReply *reply = qobject_cast<QGeoRouteReply *>(sender());
+ if (reply)
+ emit finished(reply);
+}
+
+void QGeoRoutingManagerEngineMapbox::replyError(QGeoRouteReply::Error errorCode,
+ const QString &errorString)
+{
+ QGeoRouteReply *reply = qobject_cast<QGeoRouteReply *>(sender());
+ if (reply)
+ emit error(reply, errorCode, errorString);
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h
new file mode 100644
index 00000000..5b440147
--- /dev/null
+++ b/src/plugins/geoservices/mapbox/qgeoroutingmanagerenginemapbox.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Vlad Seryakov <vseryakov@gmail.com>
+** Copyright (C) 2016 Aaron McCarthy <mccarthy.aaron@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGEOROUTINGMANAGERENGINEMAPBOX_H
+#define QGEOROUTINGMANAGERENGINEMAPBOX_H
+
+#include <QtLocation/QGeoServiceProvider>
+#include <QtLocation/QGeoRoutingManagerEngine>
+
+QT_BEGIN_NAMESPACE
+
+class QNetworkAccessManager;
+
+class QGeoRoutingManagerEngineMapbox : public QGeoRoutingManagerEngine
+{
+ Q_OBJECT
+
+public:
+ QGeoRoutingManagerEngineMapbox(const QVariantMap &parameters,
+ QGeoServiceProvider::Error *error,
+ QString *errorString);
+ ~QGeoRoutingManagerEngineMapbox();
+
+ QGeoRouteReply *calculateRoute(const QGeoRouteRequest &request);
+
+private Q_SLOTS:
+ void replyFinished();
+ void replyError(QGeoRouteReply::Error errorCode, const QString &errorString);
+
+private:
+ QNetworkAccessManager *m_networkManager;
+ QByteArray m_userAgent;
+ QString m_accessToken;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOROUTINGMANAGERENGINEOSM_H
+
diff --git a/src/plugins/geoservices/mapbox/qgeoserviceproviderpluginmapbox.cpp b/src/plugins/geoservices/mapbox/qgeoserviceproviderpluginmapbox.cpp
index ec40716b..4bc8d7b9 100644
--- a/src/plugins/geoservices/mapbox/qgeoserviceproviderpluginmapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeoserviceproviderpluginmapbox.cpp
@@ -36,6 +36,7 @@
#include "qgeoserviceproviderpluginmapbox.h"
#include "qgeotiledmappingmanagerenginemapbox.h"
+#include "qgeoroutingmanagerenginemapbox.h"
#include <QtLocation/private/qgeotiledmappingmanagerengine_p.h>
@@ -54,14 +55,13 @@ QGeoCodingManagerEngine *QGeoServiceProviderFactoryMapbox::createGeocodingManage
QGeoMappingManagerEngine *QGeoServiceProviderFactoryMapbox::createMappingManagerEngine(
const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString) const
{
- const QString mapId = parameters.value(QStringLiteral("mapbox.map_id")).toString();
const QString accessToken = parameters.value(QStringLiteral("mapbox.access_token")).toString();
- if (!mapId.isEmpty() && !accessToken.isEmpty()) {
+ if (!accessToken.isEmpty()) {
return new QGeoTiledMappingManagerEngineMapbox(parameters, error, errorString);
} else {
*error = QGeoServiceProvider::MissingRequiredParameterError;
- *errorString = tr("Mapbox plugin requires 'mapbox.map_id' and 'mapbox.access_token' parameters.\n"
+ *errorString = tr("Mapbox plugin requires a 'mapbox.access_token' parameter.\n"
"Please visit https://www.mapbox.com");
return 0;
}
@@ -70,11 +70,16 @@ QGeoMappingManagerEngine *QGeoServiceProviderFactoryMapbox::createMappingManager
QGeoRoutingManagerEngine *QGeoServiceProviderFactoryMapbox::createRoutingManagerEngine(
const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString) const
{
- Q_UNUSED(parameters)
- Q_UNUSED(error)
- Q_UNUSED(errorString)
+ const QString accessToken = parameters.value(QStringLiteral("mapbox.access_token")).toString();
- return 0;
+ if (!accessToken.isEmpty()) {
+ return new QGeoRoutingManagerEngineMapbox(parameters, error, errorString);
+ } else {
+ *error = QGeoServiceProvider::MissingRequiredParameterError;
+ *errorString = tr("Mapbox plugin requires 'mapbox.access_token' parameters.\n"
+ "Please visit https://www.mapbox.com");
+ return 0;
+ }
}
QPlaceManagerEngine *QGeoServiceProviderFactoryMapbox::createPlaceManagerEngine(
diff --git a/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.cpp b/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.cpp
index 4be5ac24..2bf756fc 100644
--- a/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.cpp
@@ -40,6 +40,7 @@
#include <QtLocation/private/qgeocameracapabilities_p.h>
#include <QtLocation/private/qgeomaptype_p.h>
#include <QtLocation/private/qgeotiledmap_p.h>
+#include "qgeofiletilecachemapbox.h"
QT_BEGIN_NAMESPACE
@@ -54,18 +55,59 @@ QGeoTiledMappingManagerEngineMapbox::QGeoTiledMappingManagerEngineMapbox(const Q
setTileSize(QSize(256, 256));
QList<QGeoMapType> mapTypes;
- mapTypes << QGeoMapType(QGeoMapType::CustomMap, tr("Custom"), tr("Mapbox custom map"), false, false, 0);
+ // as index 0 to retain compatibility with the current API, that expects the passed map_id to be on by default.
+ if (parameters.contains(QStringLiteral("mapbox.map_id"))) {
+ const QString name = parameters.value(QStringLiteral("mapbox.map_id")).toString();
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, name, name, false, false, mapTypes.size());
+ }
+
+ // As of 2016.06.15, valid mapbox map_ids are documented at https://www.mapbox.com/api-documentation/#maps
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.streets"), tr("Street"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.light"), tr("Light"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.dark"), tr("Dark"), false, true, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, QStringLiteral("mapbox.satellite"), tr("Satellite"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::HybridMap, QStringLiteral("mapbox.streets-satellite"), tr("Streets Satellite"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.wheatpaste"), tr("Wheatpaste"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.streets-basic"), tr("Streets Basic"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.comic"), tr("Comic"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::PedestrianMap, QStringLiteral("mapbox.outdoors"), tr("Outdoors"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::CycleMap, QStringLiteral("mapbox.run-bike-hike"), tr("Run Bike Hike"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.pencil"), tr("Pencil"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.pirates"), tr("Pirates"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.emerald"), tr("Emerald"), false, false, mapTypes.size());
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.high-contrast"), tr("High Contrast"), false, false, mapTypes.size());
+
+ // New way to specify multiple customized map_ids via additional_map_ids
+ if (parameters.contains(QStringLiteral("mapbox.additional_map_ids"))) {
+ const QString ids = parameters.value(QStringLiteral("mapbox.additional_map_ids")).toString();
+ const QStringList idList = ids.split(',', QString::SkipEmptyParts);
+
+ for (const QString &name: idList) {
+ if (!name.isEmpty())
+ mapTypes << QGeoMapType(QGeoMapType::CustomMap, name, name, false, false, mapTypes.size());
+ }
+ }
+
+ QVector<QString> mapIds;
+ for (int i=0; i < mapTypes.size(); ++i)
+ mapIds.push_back(mapTypes[i].name());
+
setSupportedMapTypes(mapTypes);
- QGeoTileFetcherMapbox *tileFetcher = new QGeoTileFetcherMapbox(this);
+ int scaleFactor = 2;
+ if (parameters.contains(QStringLiteral("mapbox.highdpi_tiles"))) {
+ const QString param = parameters.value(QStringLiteral("mapbox.highdpi_tiles")).toString().toLower();
+ if (param == "false")
+ scaleFactor = 1;
+ }
+
+ QGeoTileFetcherMapbox *tileFetcher = new QGeoTileFetcherMapbox(scaleFactor, this);
+ tileFetcher->setMapIds(mapIds);
+
if (parameters.contains(QStringLiteral("useragent"))) {
const QByteArray ua = parameters.value(QStringLiteral("useragent")).toString().toLatin1();
tileFetcher->setUserAgent(ua);
}
- if (parameters.contains(QStringLiteral("mapbox.map_id"))) {
- const QString id = parameters.value(QStringLiteral("mapbox.map_id")).toString();
- tileFetcher->setMapId(id);
- }
if (parameters.contains(QStringLiteral("mapbox.format"))) {
const QString format = parameters.value(QStringLiteral("mapbox.format")).toString();
tileFetcher->setFormat(format);
@@ -77,6 +119,52 @@ QGeoTiledMappingManagerEngineMapbox::QGeoTiledMappingManagerEngineMapbox(const Q
setTileFetcher(tileFetcher);
+ // TODO: do this in a plugin-neutral way so that other tiled map plugins
+ // don't need this boilerplate or hardcode plugin name
+
+ if (parameters.contains(QStringLiteral("mapbox.cache.directory"))) {
+ m_cacheDirectory = parameters.value(QStringLiteral("mapbox.cache.directory")).toString();
+ } else {
+ // managerName() is not yet set, we have to hardcode the plugin name below
+ m_cacheDirectory = QAbstractGeoTileCache::baseCacheDirectory() + QLatin1String("mapbox");
+ }
+
+ // The Mapbox free plan allows for 6000 tiles to be stored for offline uses
+ // As of 2016.06.15, according to https://www.mapbox.com/help/mobile-offline/ ,
+ // this translates into 45-315 MiB, depending on the map and the area.
+ // Setting a default limit of 300MiB, which can be overridden via parameters, if
+ // the plan allows for more data to be stored offline.
+ // NOTE:
+ // It is illegal to violate Mapbox Terms of Service, setting a limit that exceeds
+ // what the plan the token belongs to allows.
+
+ QGeoFileTileCache *tileCache = new QGeoFileTileCacheMapbox(mapTypes, scaleFactor, m_cacheDirectory);
+
+ if (parameters.contains(QStringLiteral("mapbox.cache.disk.size"))) {
+ bool ok = false;
+ int cacheSize = parameters.value(QStringLiteral("mapbox.cache.disk.size")).toString().toInt(&ok);
+ if (ok)
+ tileCache->setMaxDiskUsage(cacheSize);
+ } else {
+ tileCache->setMaxDiskUsage(300 * 1024 * 1024);
+ }
+
+ if (parameters.contains(QStringLiteral("mapbox.cache.memory.size"))) {
+ bool ok = false;
+ int cacheSize = parameters.value(QStringLiteral("mapbox.cache.memory.size")).toString().toInt(&ok);
+ if (ok)
+ tileCache->setMaxMemoryUsage(cacheSize);
+ }
+
+ if (parameters.contains(QStringLiteral("mapbox.cache.texture.size"))) {
+ bool ok = false;
+ int cacheSize = parameters.value(QStringLiteral("mapbox.cache.texture.size")).toString().toInt(&ok);
+ if (ok)
+ tileCache->setExtraTextureUsage(cacheSize);
+ }
+
+ setTileCache(tileCache);
+
*error = QGeoServiceProvider::NoError;
errorString->clear();
}
diff --git a/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.h b/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.h
index 379ca6b8..292e4211 100644
--- a/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.h
+++ b/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.h
@@ -53,6 +53,9 @@ public:
~QGeoTiledMappingManagerEngineMapbox();
QGeoMap *createMap();
+
+private:
+ QString m_cacheDirectory;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.cpp b/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.cpp
index 69a832df..062b4f89 100644
--- a/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.cpp
+++ b/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.cpp
@@ -44,14 +44,14 @@
QT_BEGIN_NAMESPACE
-QGeoTileFetcherMapbox::QGeoTileFetcherMapbox(QObject *parent)
+QGeoTileFetcherMapbox::QGeoTileFetcherMapbox(int scaleFactor, QObject *parent)
: QGeoTileFetcher(parent), m_networkManager(new QNetworkAccessManager(this)),
m_userAgent("Qt Location based application"),
- m_mapId(""),
m_format("png"),
m_replyFormat("png"),
m_accessToken("")
{
+ m_scaleFactor = qBound(1, scaleFactor, 2);
}
void QGeoTileFetcherMapbox::setUserAgent(const QByteArray &userAgent)
@@ -59,9 +59,9 @@ void QGeoTileFetcherMapbox::setUserAgent(const QByteArray &userAgent)
m_userAgent = userAgent;
}
-void QGeoTileFetcherMapbox::setMapId(const QString &mapId)
+void QGeoTileFetcherMapbox::setMapIds(const QVector<QString> &mapIds)
{
- m_mapId = mapId;
+ m_mapIds = mapIds;
}
void QGeoTileFetcherMapbox::setFormat(const QString &format)
@@ -87,10 +87,11 @@ QGeoTiledMapReply *QGeoTileFetcherMapbox::getTileImage(const QGeoTileSpec &spec)
request.setRawHeader("User-Agent", m_userAgent);
request.setUrl(QUrl(QStringLiteral("http://api.tiles.mapbox.com/v4/") +
- m_mapId + QLatin1Char('/') +
+ ((spec.mapId() >= m_mapIds.size()) ? QStringLiteral("mapbox.streets") : m_mapIds[spec.mapId()]) + QLatin1Char('/') +
QString::number(spec.zoom()) + QLatin1Char('/') +
QString::number(spec.x()) + QLatin1Char('/') +
- QString::number(spec.y()) + QLatin1Char('.') +
+ QString::number(spec.y()) +
+ ((m_scaleFactor > 1) ? (QLatin1Char('@') + QString::number(m_scaleFactor) + QLatin1String("x.")) : QLatin1String(".")) +
m_format + QLatin1Char('?') +
QStringLiteral("access_token=") + m_accessToken));
diff --git a/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.h b/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.h
index ddec2896..e52651e1 100644
--- a/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.h
+++ b/src/plugins/geoservices/mapbox/qgeotilefetchermapbox.h
@@ -37,6 +37,7 @@
#ifndef QGEOTILEFETCHERMAPBOX_H
#define QGEOTILEFETCHERMAPBOX_H
+#include <qvector.h>
#include <QtLocation/private/qgeotilefetcher_p.h>
QT_BEGIN_NAMESPACE
@@ -49,10 +50,10 @@ class QGeoTileFetcherMapbox : public QGeoTileFetcher
Q_OBJECT
public:
- QGeoTileFetcherMapbox(QObject *parent = 0);
+ QGeoTileFetcherMapbox(int scaleFactor = 2, QObject *parent = 0);
void setUserAgent(const QByteArray &userAgent);
- void setMapId(const QString &mapId);
+ void setMapIds(const QVector<QString> &mapIds);
void setFormat(const QString &format);
void setAccessToken(const QString &accessToken);
@@ -61,10 +62,11 @@ private:
QNetworkAccessManager *m_networkManager;
QByteArray m_userAgent;
- QString m_mapId;
QString m_format;
QString m_replyFormat;
QString m_accessToken;
+ QVector<QString> m_mapIds;
+ int m_scaleFactor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/nokia.pro b/src/plugins/geoservices/nokia/nokia.pro
index cd340f50..a063aaf2 100644
--- a/src/plugins/geoservices/nokia/nokia.pro
+++ b/src/plugins/geoservices/nokia/nokia.pro
@@ -26,7 +26,8 @@ HEADERS += \
uri_constants.h \
qgeoerror_messages.h \
qgeomapversion.h \
- qgeotiledmap_nokia.h
+ qgeotiledmap_nokia.h \
+ qgeofiletilecachenokia.h
SOURCES += \
@@ -45,7 +46,8 @@ SOURCES += \
uri_constants.cpp \
qgeoerror_messages.cpp \
qgeomapversion.cpp \
- qgeotiledmap_nokia.cpp
+ qgeotiledmap_nokia.cpp \
+ qgeofiletilecachenokia.cpp
include(placesv2/placesv2.pri)
diff --git a/src/plugins/geoservices/nokia/qgeofiletilecachenokia.cpp b/src/plugins/geoservices/nokia/qgeofiletilecachenokia.cpp
new file mode 100644
index 00000000..8b795325
--- /dev/null
+++ b/src/plugins/geoservices/nokia/qgeofiletilecachenokia.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** 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 "qgeofiletilecachenokia.h"
+#include <QtLocation/private/qgeotilespec_p.h>
+#include <QDir>
+
+QT_BEGIN_NAMESPACE
+
+QGeoFileTileCacheNokia::QGeoFileTileCacheNokia(int ppi, const QString &directory, QObject *parent)
+ :QGeoFileTileCache(directory, parent)
+{
+ m_ppi = QString::number(ppi) + QLatin1String("p");
+}
+
+QGeoFileTileCacheNokia::~QGeoFileTileCacheNokia()
+{
+
+}
+
+QString QGeoFileTileCacheNokia::tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const
+{
+ QString filename = spec.plugin();
+ filename += QLatin1String("-");
+ filename += QString::number(spec.mapId());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.zoom());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.x());
+ filename += QLatin1String("-");
+ filename += QString::number(spec.y());
+
+ //Append version if real version number to ensure backwards compatibility and eviction of old tiles
+ if (spec.version() != -1) {
+ filename += QLatin1String("-");
+ filename += QString::number(spec.version());
+ }
+
+ filename += QLatin1String("-");
+ filename += m_ppi;
+
+ filename += QLatin1String(".");
+ filename += format;
+
+ QDir dir = QDir(directory);
+
+ return dir.filePath(filename);
+}
+
+QGeoTileSpec QGeoFileTileCacheNokia::filenameToTileSpec(const QString &filename) const
+{
+ QGeoTileSpec emptySpec;
+
+ QStringList parts = filename.split('.');
+
+ if (parts.length() != 2)
+ return emptySpec;
+
+ QString name = parts.at(0);
+ QStringList fields = name.split('-');
+
+ int length = fields.length();
+ if (length != 6 && length != 7)
+ return emptySpec;
+ else if (fields.last() != m_ppi)
+ return QGeoTileSpec();
+
+ QList<int> numbers;
+
+ bool ok = false;
+ for (int i = 1; i < length-1; ++i) { // skipping -<ppi>
+ ok = false;
+ int value = fields.at(i).toInt(&ok);
+ if (!ok)
+ return emptySpec;
+ numbers.append(value);
+ }
+
+ //File name without version, append default
+ if (numbers.length() < 5)
+ numbers.append(-1);
+
+ return QGeoTileSpec(fields.at(0),
+ numbers.at(0),
+ numbers.at(1),
+ numbers.at(2),
+ numbers.at(3),
+ numbers.at(4));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/nokia/qgeofiletilecachenokia.h b/src/plugins/geoservices/nokia/qgeofiletilecachenokia.h
new file mode 100644
index 00000000..aba232f5
--- /dev/null
+++ b/src/plugins/geoservices/nokia/qgeofiletilecachenokia.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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 QGEOFILETILECACHENOKIA_H
+#define QGEOFILETILECACHENOKIA_H
+
+#include <QtLocation/private/qgeofiletilecache_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoFileTileCacheNokia : public QGeoFileTileCache
+{
+ Q_OBJECT
+public:
+ QGeoFileTileCacheNokia(int ppi, const QString &directory = QString(), QObject *parent = 0);
+ ~QGeoFileTileCacheNokia();
+
+protected:
+ virtual QString tileSpecToFilename(const QGeoTileSpec &spec, const QString &format, const QString &directory) const Q_DECL_OVERRIDE;
+ virtual QGeoTileSpec filenameToTileSpec(const QString &filename) const Q_DECL_OVERRIDE;
+
+ QString m_ppi;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOFILETILECACHENOKIA_H
diff --git a/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp b/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp
index f6d05c36..4deac4ee 100644
--- a/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qgeoserviceproviderplugin_nokia.cpp
@@ -81,7 +81,11 @@ namespace
token = parameters.value(QStringLiteral("here.token")).toString();
if (isValidParameter(appId) && isValidParameter(token))
- return;
+ return;
+ else if (!isValidParameter(appId))
+ qWarning() << "Invalid here.app_id";
+ else
+ qWarning() << "Invalid here.token";
if (parameters.contains(QStringLiteral("app_id")) || parameters.contains(QStringLiteral("token")))
qWarning() << QStringLiteral("Please prefix 'app_id' and 'token' with prefix 'here' (e.g.: 'here.app_id')");
diff --git a/src/plugins/geoservices/nokia/qgeotiledmappingmanagerengine_nokia.cpp b/src/plugins/geoservices/nokia/qgeotiledmappingmanagerengine_nokia.cpp
index 4f44e5fd..e823c7e8 100644
--- a/src/plugins/geoservices/nokia/qgeotiledmappingmanagerengine_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qgeotiledmappingmanagerengine_nokia.cpp
@@ -39,7 +39,7 @@
#include "qgeotiledmap_nokia.h"
#include "qgeotilefetcher_nokia.h"
#include "qgeotilespec_p.h"
-#include "qgeofiletilecache_p.h"
+#include "qgeofiletilecachenokia.h"
#include <QDebug>
#include <QDir>
@@ -95,7 +95,14 @@ QGeoTiledMappingManagerEngineNokia::QGeoTiledMappingManagerEngineNokia(
types << QGeoMapType(QGeoMapType::CarNavigationMap, tr("Car Navigation Map"), tr("Normal map view in daylight mode for car navigation"), false, false, 21);
setSupportedMapTypes(types);
- QGeoTileFetcherNokia *fetcher = new QGeoTileFetcherNokia(parameters, networkManager, this, tileSize());
+ int ppi = 250;
+ if (parameters.contains(QStringLiteral("here.mapping.highdpi_tiles"))) {
+ const QString param = parameters.value(QStringLiteral("here.mapping.highdpi_tiles")).toString().toLower();
+ if (param == "false")
+ ppi = 72;
+ }
+
+ QGeoTileFetcherNokia *fetcher = new QGeoTileFetcherNokia(parameters, networkManager, this, tileSize(), ppi);
setTileFetcher(fetcher);
// TODO: do this in a plugin-neutral way so that other tiled map plugins
@@ -108,7 +115,7 @@ QGeoTiledMappingManagerEngineNokia::QGeoTiledMappingManagerEngineNokia(
m_cacheDirectory = QAbstractGeoTileCache::baseCacheDirectory() + QLatin1String("here");
}
- QAbstractGeoTileCache *tileCache = new QGeoFileTileCache(m_cacheDirectory);
+ QGeoFileTileCache *tileCache = new QGeoFileTileCacheNokia(ppi, m_cacheDirectory);
setTileCache(tileCache);
if (parameters.contains(QStringLiteral("here.mapping.cache.disk.size"))) {
diff --git a/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp b/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp
index 50acc2a0..a55f71c0 100644
--- a/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp
+++ b/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp
@@ -56,11 +56,11 @@ QT_BEGIN_NAMESPACE
namespace
{
- QString sizeToStr(const QSize &size)
+ QString sizeToStr(int size)
{
- if (size.height() >= 512 || size.width() >= 512)
+ if (size > 256)
return QStringLiteral("512");
- else if (size.height() >= 256 || size.width() >= 256)
+ else if (size > 128)
return QStringLiteral("256");
else
return QStringLiteral("128"); // 128 pixel tiles are deprecated.
@@ -74,13 +74,14 @@ namespace
QGeoTileFetcherNokia::QGeoTileFetcherNokia(const QVariantMap &parameters,
QGeoNetworkAccessManager *networkManager,
QGeoTiledMappingManagerEngineNokia *engine,
- const QSize &tileSize)
-: QGeoTileFetcher(engine), m_engineNokia(engine), m_networkManager(networkManager),
- m_tileSize(tileSize), m_copyrightsReply(0),
+ const QSize &tileSize,
+ int ppi)
+: QGeoTileFetcher(engine), m_engineNokia(engine), m_networkManager(networkManager), m_ppi(ppi), m_copyrightsReply(0),
m_baseUriProvider(new QGeoUriProvider(this, parameters, QStringLiteral("here.mapping.host"), MAP_TILES_HOST)),
m_aerialUriProvider(new QGeoUriProvider(this, parameters, QStringLiteral("here.mapping.host.aerial"), MAP_TILES_HOST_AERIAL))
{
Q_ASSERT(networkManager);
+ m_tileSize = qMax(tileSize.width(), tileSize.height());
m_networkManager->setParent(this);
m_applicationId = parameters.value(QStringLiteral("here.app_id")).toString();
@@ -94,7 +95,11 @@ QGeoTileFetcherNokia::~QGeoTileFetcherNokia()
QGeoTiledMapReply *QGeoTileFetcherNokia::getTileImage(const QGeoTileSpec &spec)
{
// TODO add error detection for if request.connectivityMode() != QGraphicsGeoMap::OnlineMode
- QString rawRequest = getRequestString(spec);
+ int ppi = m_ppi;
+ if ((spec.mapId() == 2) || (spec.mapId() == 12) || (spec.mapId() == 21))
+ ppi = 72; // HiDpi apparently not supported for these maps
+
+ QString rawRequest = getRequestString(spec, ppi);
if (rawRequest.isEmpty()) {
return new QGeoTiledMapReply(QGeoTiledMapReply::UnknownError,
tr("Mapping manager no longer exists"), this);
@@ -110,7 +115,7 @@ QGeoTiledMapReply *QGeoTileFetcherNokia::getTileImage(const QGeoTileSpec &spec)
return mapReply;
}
-QString QGeoTileFetcherNokia::getRequestString(const QGeoTileSpec &spec)
+QString QGeoTileFetcherNokia::getRequestString(const QGeoTileSpec &spec, int ppi)
{
if (!m_engineNokia)
return QString();
@@ -136,11 +141,11 @@ QString QGeoTileFetcherNokia::getRequestString(const QGeoTileSpec &spec)
requestString += slash;
requestString += QString::number(spec.y());
requestString += slash;
- requestString += sizeToStr(m_tileSize);
+ requestString += ((ppi > 72)) ? sizeToStr(m_tileSize * 2) : sizeToStr(m_tileSize);
static const QString slashpng("/png8");
requestString += slashpng;
- if (!m_token.isEmpty() && !m_applicationId.isEmpty()) {
+ if (!m_token.isEmpty() && !m_applicationId.isEmpty()) { // TODO: remove the if
requestString += "?token=";
requestString += m_token;
@@ -148,9 +153,10 @@ QString QGeoTileFetcherNokia::getRequestString(const QGeoTileSpec &spec)
requestString += m_applicationId;
}
+ requestString += "&ppi=" + QString::number(ppi);
+
requestString += "&lg=";
requestString += getLanguageString();
-
return requestString;
}
diff --git a/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.h b/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.h
index 44f2ad07..06d1bba9 100644
--- a/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.h
+++ b/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.h
@@ -57,7 +57,7 @@ class QGeoTileFetcherNokia : public QGeoTileFetcher
public:
QGeoTileFetcherNokia(const QVariantMap &parameters, QGeoNetworkAccessManager *networkManager,
- QGeoTiledMappingManagerEngineNokia *engine, const QSize &tileSize);
+ QGeoTiledMappingManagerEngineNokia *engine, const QSize &tileSize, int ppi);
~QGeoTileFetcherNokia();
QGeoTiledMapReply *getTileImage(const QGeoTileSpec &spec);
@@ -74,13 +74,14 @@ public Q_SLOTS:
private:
Q_DISABLE_COPY(QGeoTileFetcherNokia)
- QString getRequestString(const QGeoTileSpec &spec);
+ QString getRequestString(const QGeoTileSpec &spec, int ppi=72);
QString getLanguageString() const;
QPointer<QGeoTiledMappingManagerEngineNokia> m_engineNokia;
QGeoNetworkAccessManager *m_networkManager;
- QSize m_tileSize;
+ int m_tileSize;
+ int m_ppi;
QString m_token;
QNetworkReply *m_copyrightsReply;
QNetworkReply *m_versionReply;
diff --git a/src/plugins/geoservices/osm/osm.pro b/src/plugins/geoservices/osm/osm.pro
index 56f4cb33..86a62744 100644
--- a/src/plugins/geoservices/osm/osm.pro
+++ b/src/plugins/geoservices/osm/osm.pro
@@ -1,6 +1,6 @@
TARGET = qtgeoservices_osm
-QT += location-private positioning-private network
+QT += location-private positioning-private network concurrent
HEADERS += \
qgeoserviceproviderpluginosm.h \
@@ -15,6 +15,7 @@ HEADERS += \
qplacesearchreplyosm.h \
qplacecategoriesreplyosm.h \
qgeotiledmaposm.h \
+ qgeofiletilecacheosm.h \
qgeotileproviderosm.h
SOURCES += \
@@ -30,6 +31,7 @@ SOURCES += \
qplacesearchreplyosm.cpp \
qplacecategoriesreplyosm.cpp \
qgeotiledmaposm.cpp \
+ qgeofiletilecacheosm.cpp \
qgeotileproviderosm.cpp
diff --git a/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
new file mode 100644
index 00000000..a780faa9
--- /dev/null
+++ b/src/plugins/geoservices/osm/qgeofiletilecacheosm.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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 "qgeofiletilecacheosm.h"
+#include <QtLocation/private/qgeotilespec_p.h>
+#include <QDir>
+#include <QDirIterator>
+#include <QPair>
+#include <QDateTime>
+#include <QtConcurrent>
+#include <QThread>
+
+QT_BEGIN_NAMESPACE
+
+QGeoFileTileCacheOsm::QGeoFileTileCacheOsm(const QString &offlineDirectory, const QString &directory, QObject *parent)
+ :QGeoFileTileCache(directory, parent), m_offlineDirectory(offlineDirectory),
+ m_requestCancel(0)
+{
+}
+
+QGeoFileTileCacheOsm::~QGeoFileTileCacheOsm()
+{
+ m_requestCancel = 1;
+ m_future.waitForFinished();
+}
+
+QSharedPointer<QGeoTileTexture> QGeoFileTileCacheOsm::get(const QGeoTileSpec &spec)
+{
+ QSharedPointer<QGeoTileTexture> tt = getFromMemory(spec);
+ if (tt)
+ return tt;
+ if (tt = getFromOfflineStorage(spec))
+ return tt;
+ return getFromDisk(spec);
+}
+
+void QGeoFileTileCacheOsm::init()
+{
+ QGeoFileTileCache::init();
+ if (!m_offlineDirectory.isEmpty())
+ m_future = QtConcurrent::run(this, &QGeoFileTileCacheOsm::initOfflineRegistry);
+}
+
+QSharedPointer<QGeoTileTexture> QGeoFileTileCacheOsm::getFromOfflineStorage(const QGeoTileSpec &spec)
+{
+ QMutexLocker locker(&storageLock);
+ if (m_tilespecToOfflineFilepath.contains(spec)) {
+ QFile file(m_tilespecToOfflineFilepath[spec]);
+ file.open(QIODevice::ReadOnly);
+ QByteArray bytes = file.readAll();
+ file.close();
+ locker.unlock();
+
+ QImage image;
+ if (!image.loadFromData(bytes)) {
+ handleError(spec, QLatin1String("Problem with tile image"));
+ return QSharedPointer<QGeoTileTexture>(0);
+ }
+
+ addToMemoryCache(spec, bytes, QString());
+ QSharedPointer<QGeoTileTexture> tt = addToTextureCache(spec, image);
+ if (tt)
+ return tt;
+ }
+
+ return QSharedPointer<QGeoTileTexture>();
+}
+
+void QGeoFileTileCacheOsm::initOfflineRegistry()
+{
+ // Dealing with duplicates: picking the newest
+ QMap<QString, QPair<QString, QDateTime> > fileDates; // key is filename, value is <filepath, lastmodified>
+ QDirIterator it(m_offlineDirectory, QStringList() << "*.*", QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks );
+ while (it.hasNext()) {
+ const QString &path = it.next();
+ QFileInfo f(path);
+ if (!fileDates.contains(f.fileName()) || fileDates[f.fileName()].second < f.lastModified())
+ fileDates[f.fileName()] = QPair<QString, QDateTime>(f.filePath(), f.lastModified());
+ if (m_requestCancel)
+ return;
+ }
+
+ int count = 0;
+ for (auto i= fileDates.begin(); i != fileDates.end(); ++i) {
+ QGeoTileSpec spec = filenameToTileSpec(i.key());
+ if (spec.zoom() == -1)
+ continue;
+ count++;
+ storageLock.lock();
+ m_tilespecToOfflineFilepath[spec] = i.value().first;
+ storageLock.unlock();
+ if (m_requestCancel)
+ return;
+ }
+ qWarning() << "OSM Offline tiles: "<<count;
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qgeofiletilecacheosm.h b/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
new file mode 100644
index 00000000..f48fad7f
--- /dev/null
+++ b/src/plugins/geoservices/osm/qgeofiletilecacheosm.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 QGEOFILETILECACHEOSM_H
+#define QGEOFILETILECACHEOSM_H
+
+#include <QtLocation/private/qgeofiletilecache_p.h>
+#include <QHash>
+#include <QtConcurrent>
+#include <qatomic.h>
+
+QT_BEGIN_NAMESPACE
+
+class QGeoFileTileCacheOsm : public QGeoFileTileCache
+{
+ Q_OBJECT
+public:
+ QGeoFileTileCacheOsm(const QString &offlineDirectory = QString(), const QString &directory = QString(), QObject *parent = 0);
+ ~QGeoFileTileCacheOsm();
+
+ QSharedPointer<QGeoTileTexture> get(const QGeoTileSpec &spec) Q_DECL_OVERRIDE;
+
+protected:
+ void init() Q_DECL_OVERRIDE;
+ QSharedPointer<QGeoTileTexture> getFromOfflineStorage(const QGeoTileSpec &spec);
+
+ void initOfflineRegistry();
+
+ QString m_offlineDirectory;
+ QHash<QGeoTileSpec, QString> m_tilespecToOfflineFilepath;
+ QAtomicInt m_requestCancel;
+ QFuture<void> m_future;
+ QMutex storageLock;
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOFILETILECACHEOSM_H
diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
index fba177f4..2b562e62 100644
--- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
+++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp
@@ -40,7 +40,7 @@
#include "qgeotiledmappingmanagerengineosm.h"
#include "qgeotilefetcherosm.h"
#include "qgeotiledmaposm.h"
-#include "qgeotileproviderosm.h"
+#include "qgeofiletilecacheosm.h"
#include <QtLocation/private/qgeocameracapabilities_p.h>
#include <QtLocation/private/qgeomaptype_p.h>
@@ -191,9 +191,40 @@ QGeoTiledMappingManagerEngineOsm::QGeoTiledMappingManagerEngineOsm(const QVarian
setTileFetcher(tileFetcher);
- QAbstractGeoTileCache *tileCache = new QGeoFileTileCache(QAbstractGeoTileCache::baseCacheDirectory() + QStringLiteral("osm"));
+ if (parameters.contains(QStringLiteral("osm.mapping.cache.directory"))) {
+ m_cacheDirectory = parameters.value(QStringLiteral("osm.mapping.cache.directory")).toString();
+ } else {
+ // managerName() is not yet set, we have to hardcode the plugin name below
+ m_cacheDirectory = QAbstractGeoTileCache::baseCacheDirectory() + QLatin1String("osm");
+ }
+ if (parameters.contains(QStringLiteral("osm.mapping.offline.directory")))
+ m_offlineDirectory = parameters.value(QStringLiteral("osm.mapping.offline.directory")).toString();
+
+ QAbstractGeoTileCache *tileCache = new QGeoFileTileCacheOsm(m_offlineDirectory, m_cacheDirectory);
+
// 50mb of disk cache by default to minimize n. of accesses to public OSM servers
tileCache->setMaxDiskUsage(50 * 1024 * 1024);
+
+ if (parameters.contains(QStringLiteral("osm.mapping.cache.disk.size"))) {
+ bool ok = false;
+ int cacheSize = parameters.value(QStringLiteral("osm.mapping.cache.disk.size")).toString().toInt(&ok);
+ if (ok)
+ tileCache->setMaxDiskUsage(cacheSize);
+ } else {
+ tileCache->setMaxDiskUsage(100 * 1024 * 1024);
+ }
+ if (parameters.contains(QStringLiteral("osm.mapping.cache.memory.size"))) {
+ bool ok = false;
+ int cacheSize = parameters.value(QStringLiteral("osm.mapping.cache.memory.size")).toString().toInt(&ok);
+ if (ok)
+ tileCache->setMaxMemoryUsage(cacheSize);
+ }
+ if (parameters.contains(QStringLiteral("osm.mapping.cache.texture.size"))) {
+ bool ok = false;
+ int cacheSize = parameters.value(QStringLiteral("osm.mapping.cache.texture.size")).toString().toInt(&ok);
+ if (ok)
+ tileCache->setExtraTextureUsage(cacheSize);
+ }
setTileCache(tileCache);
*error = QGeoServiceProvider::NoError;
diff --git a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h
index 247e4377..7536e655 100644
--- a/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h
+++ b/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.h
@@ -73,6 +73,8 @@ protected:
private:
QVector<QGeoTileProviderOsm *> m_providers;
QString m_customCopyright;
+ QString m_cacheDirectory;
+ QString m_offlineDirectory;
};
QT_END_NAMESPACE
diff --git a/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h b/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h
index f2d817b1..b9c4774a 100644
--- a/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h
+++ b/src/plugins/position/geoclue/qgeopositioninfosource_geocluemaster.h
@@ -65,17 +65,17 @@ public:
~QGeoPositionInfoSourceGeoclueMaster();
// From QGeoPositionInfoSource
- void setUpdateInterval(int msec);
- QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const;
- PositioningMethods supportedPositioningMethods() const;
- void setPreferredPositioningMethods(PositioningMethods methods);
- int minimumUpdateInterval() const;
+ void setUpdateInterval(int msec) override;
+ QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override;
+ PositioningMethods supportedPositioningMethods() const override;
+ void setPreferredPositioningMethods(PositioningMethods methods) override;
+ int minimumUpdateInterval() const override;
- Error error() const;
+ Error error() const override;
- virtual void startUpdates() Q_DECL_OVERRIDE;
- virtual void stopUpdates() Q_DECL_OVERRIDE;
- virtual void requestUpdate(int timeout = 5000) Q_DECL_OVERRIDE;
+ void startUpdates() override;
+ void stopUpdates() override;
+ void requestUpdate(int timeout = 5000) override;
private slots:
void positionProviderChanged(const QString &name, const QString &description,
diff --git a/src/plugins/position/position.pro b/src/plugins/position/position.pro
index df1930b3..4df733b9 100644
--- a/src/plugins/position/position.pro
+++ b/src/plugins/position/position.pro
@@ -2,10 +2,10 @@ TEMPLATE = subdirs
qtHaveModule(dbus):SUBDIRS += geoclue
config_gypsy:SUBDIRS += gypsy
+config_winrt:SUBDIRS += winrt
qtHaveModule(simulator):SUBDIRS += simulator
osx|ios|tvos:SUBDIRS += corelocation
android:SUBDIRS += android
-winrt:SUBDIRS += winrt
win32:qtHaveModule(serialport):SUBDIRS += serialnmea
SUBDIRS += \
diff --git a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
index 245d855e..bc3ce6e7 100644
--- a/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
+++ b/src/plugins/position/winrt/qgeopositioninfosource_winrt.cpp
@@ -62,10 +62,10 @@ typedef IAsyncOperationCompletedHandler<Geoposition*> PositionHandler;
typedef IAsyncOperationCompletedHandler<GeolocationAccessStatus> AccessHandler;
#endif
-QT_BEGIN_NAMESPACE
-
Q_DECLARE_METATYPE(QGeoPositionInfo)
+QT_BEGIN_NAMESPACE
+
#ifndef Q_OS_WINRT
namespace QEventDispatcherWinRT {
HRESULT runOnXamlThread(const std::function<HRESULT ()> &delegate, bool waitForRun = true)