1/****************************************************************************
2**
3** Copyright (C) 2014 Canonical Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the QtLocation module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qgeotiledmappingmanagerenginemapbox.h"
38#include "qgeotilefetchermapbox.h"
39
40#include <QtLocation/private/qgeocameracapabilities_p.h>
41#include <QtLocation/private/qgeomaptype_p.h>
42#include <QtLocation/private/qgeotiledmap_p.h>
43#include "qgeofiletilecachemapbox.h"
44#ifdef LOCATIONLABS
45#include <QtLocation/private/qgeotiledmaplabs_p.h>
46typedef QGeoTiledMapLabs Map;
47#else
48typedef QGeoTiledMap Map;
49#endif
50
51QT_BEGIN_NAMESPACE
52
53QGeoTiledMappingManagerEngineMapbox::QGeoTiledMappingManagerEngineMapbox(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)
54: QGeoTiledMappingManagerEngine()
55{
56 QGeoCameraCapabilities cameraCaps;
57 cameraCaps.setMinimumZoomLevel(0.0);
58 cameraCaps.setMaximumZoomLevel(19.0);
59 cameraCaps.setSupportsBearing(true);
60 cameraCaps.setSupportsTilting(true);
61 cameraCaps.setMinimumTilt(0);
62 cameraCaps.setMaximumTilt(80);
63 cameraCaps.setMinimumFieldOfView(20.0);
64 cameraCaps.setMaximumFieldOfView(120.0);
65 cameraCaps.setOverzoomEnabled(true);
66 setCameraCapabilities(cameraCaps);
67
68 setTileSize(QSize(256, 256));
69
70 const QByteArray pluginName = "mapbox";
71 QList<QGeoMapType> mapTypes;
72 // as index 0 to retain compatibility with the current API, that expects the passed map_id to be on by default.
73 if (parameters.contains(QStringLiteral("mapbox.mapping.map_id"))) {
74 const QString name = parameters.value(QStringLiteral("mapbox.mapping.map_id")).toString();
75 mapTypes << QGeoMapType(QGeoMapType::CustomMap, name, name, false, false, mapTypes.size() + 1, pluginName, cameraCaps);
76 } else if (parameters.contains(QStringLiteral("mapbox.map_id"))) { //deprecated
77 const QString name = parameters.value(QStringLiteral("mapbox.map_id")).toString();
78 mapTypes << QGeoMapType(QGeoMapType::CustomMap, name, name, false, false, mapTypes.size() + 1, pluginName, cameraCaps);
79 }
80
81 // As of 2016.06.15, valid mapbox map_ids are documented at https://www.mapbox.com/api-documentation/#maps
82 //: Noun describing map type 'Street map'
83 mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.streets"), tr(s: "Street"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
84 //: Noun describing type of a map using light colors (weak contrast)
85 mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.light"), tr(s: "Light"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
86 //: Noun describing type of a map using dark colors
87 mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.dark"), tr(s: "Dark"), false, true, mapTypes.size() + 1, pluginName, cameraCaps);
88 //: Noun describing type of a map created by satellite
89 mapTypes << QGeoMapType(QGeoMapType::SatelliteMapDay, QStringLiteral("mapbox.satellite"), tr(s: "Satellite"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
90 //: Noun describing type of a street map created by satellite
91 mapTypes << QGeoMapType(QGeoMapType::HybridMap, QStringLiteral("mapbox.streets-satellite"), tr(s: "Streets Satellite"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
92 //: Noun describing type of a map using wheat paste colors
93 mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.wheatpaste"), tr(s: "Wheatpaste"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
94 //: Noun describing type of a basic street map
95 mapTypes << QGeoMapType(QGeoMapType::StreetMap, QStringLiteral("mapbox.streets-basic"), tr(s: "Streets Basic"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
96 //: Noun describing type of a map using cartoon-style fonts
97 mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.comic"), tr(s: "Comic"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
98 //: Noun describing type of a map for outdoor activities
99 mapTypes << QGeoMapType(QGeoMapType::PedestrianMap, QStringLiteral("mapbox.outdoors"), tr(s: "Outdoors"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
100 //: Noun describing type of a map for sports
101 mapTypes << QGeoMapType(QGeoMapType::CycleMap, QStringLiteral("mapbox.run-bike-hike"), tr(s: "Run Bike Hike"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
102 //: Noun describing type of a map drawn by pencil
103 mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.pencil"), tr(s: "Pencil"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
104 //: Noun describing type of a treasure map with pirate boat watermark
105 mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.pirates"), tr(s: "Pirates"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
106 //: Noun describing type of a map using emerald colors
107 mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.emerald"), tr(s: "Emerald"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
108 //: Noun describing type of a map with high contrast
109 mapTypes << QGeoMapType(QGeoMapType::CustomMap, QStringLiteral("mapbox.high-contrast"), tr(s: "High Contrast"), false, false, mapTypes.size() + 1, pluginName, cameraCaps);
110
111 // New way to specify multiple customized map_ids via additional_map_ids
112 if (parameters.contains(QStringLiteral("mapbox.mapping.additional_map_ids"))) {
113 const QString ids = parameters.value(QStringLiteral("mapbox.mapping.additional_map_ids")).toString();
114 const QStringList idList = ids.split(sep: ',', behavior: Qt::SkipEmptyParts);
115
116 for (const QString &name: idList) {
117 if (!name.isEmpty())
118 mapTypes << QGeoMapType(QGeoMapType::CustomMap, name, name, false, false, mapTypes.size() + 1, pluginName, cameraCaps);
119 }
120 }
121
122 QVector<QString> mapIds;
123 for (int i=0; i < mapTypes.size(); ++i)
124 mapIds.push_back(t: mapTypes[i].name());
125
126 setSupportedMapTypes(mapTypes);
127
128 int scaleFactor = 1;
129 if (parameters.contains(QStringLiteral("mapbox.mapping.highdpi_tiles"))) {
130 const QString param = parameters.value(QStringLiteral("mapbox.mapping.highdpi_tiles")).toString().toLower();
131 if (param == "true")
132 scaleFactor = 2;
133 }
134
135 QGeoTileFetcherMapbox *tileFetcher = new QGeoTileFetcherMapbox(scaleFactor, this);
136 tileFetcher->setMapIds(mapIds);
137
138 if (parameters.contains(QStringLiteral("useragent"))) {
139 const QByteArray ua = parameters.value(QStringLiteral("useragent")).toString().toLatin1();
140 tileFetcher->setUserAgent(ua);
141 }
142 if (parameters.contains(QStringLiteral("mapbox.mapping.format"))) {
143 const QString format = parameters.value(QStringLiteral("mapbox.mapping.format")).toString();
144 tileFetcher->setFormat(format);
145 } else if (parameters.contains(QStringLiteral("mapbox.format"))) { //deprecated
146 const QString format = parameters.value(QStringLiteral("mapbox.format")).toString();
147 tileFetcher->setFormat(format);
148 }
149 if (parameters.contains(QStringLiteral("mapbox.access_token"))) {
150 const QString token = parameters.value(QStringLiteral("mapbox.access_token")).toString();
151 tileFetcher->setAccessToken(token);
152 }
153
154 setTileFetcher(tileFetcher);
155
156 // TODO: do this in a plugin-neutral way so that other tiled map plugins
157 // don't need this boilerplate or hardcode plugin name
158
159 if (parameters.contains(QStringLiteral("mapbox.mapping.cache.directory"))) {
160 m_cacheDirectory = parameters.value(QStringLiteral("mapbox.mapping.cache.directory")).toString();
161 } else {
162 // managerName() is not yet set, we have to hardcode the plugin name below
163 m_cacheDirectory = QAbstractGeoTileCache::baseLocationCacheDirectory() + QLatin1String(pluginName);
164 }
165
166 QGeoFileTileCache *tileCache = new QGeoFileTileCacheMapbox(mapTypes, scaleFactor, m_cacheDirectory);
167
168 /*
169 * Disk cache setup -- defaults to Unitary since:
170 *
171 * The Mapbox free plan allows for 6000 tiles to be stored for offline uses,
172 * As of 2016.06.15, according to https://www.mapbox.com/help/mobile-offline/ .
173 * Thus defaulting to Unitary strategy, and setting 6000 tiles as default cache disk size
174 */
175 if (parameters.contains(QStringLiteral("mapbox.mapping.cache.disk.cost_strategy"))) {
176 QString cacheStrategy = parameters.value(QStringLiteral("mapbox.mapping.cache.disk.cost_strategy")).toString().toLower();
177 if (cacheStrategy == QLatin1String("bytesize"))
178 tileCache->setCostStrategyDisk(QGeoFileTileCache::ByteSize);
179 else
180 tileCache->setCostStrategyDisk(QGeoFileTileCache::Unitary);
181 } else {
182 tileCache->setCostStrategyDisk(QGeoFileTileCache::Unitary);
183 }
184 if (parameters.contains(QStringLiteral("mapbox.mapping.cache.disk.size"))) {
185 bool ok = false;
186 int cacheSize = parameters.value(QStringLiteral("mapbox.mapping.cache.disk.size")).toString().toInt(ok: &ok);
187 if (ok)
188 tileCache->setMaxDiskUsage(cacheSize);
189 } else {
190 if (tileCache->costStrategyDisk() == QGeoFileTileCache::Unitary)
191 tileCache->setMaxDiskUsage(6000); // The maximum allowed with the free tier
192 }
193
194 /*
195 * Memory cache setup -- defaults to ByteSize (old behavior)
196 */
197 if (parameters.contains(QStringLiteral("mapbox.mapping.cache.memory.cost_strategy"))) {
198 QString cacheStrategy = parameters.value(QStringLiteral("mapbox.mapping.cache.memory.cost_strategy")).toString().toLower();
199 if (cacheStrategy == QLatin1String("bytesize"))
200 tileCache->setCostStrategyMemory(QGeoFileTileCache::ByteSize);
201 else
202 tileCache->setCostStrategyMemory(QGeoFileTileCache::Unitary);
203 } else {
204 tileCache->setCostStrategyMemory(QGeoFileTileCache::ByteSize);
205 }
206 if (parameters.contains(QStringLiteral("mapbox.mapping.cache.memory.size"))) {
207 bool ok = false;
208 int cacheSize = parameters.value(QStringLiteral("mapbox.mapping.cache.memory.size")).toString().toInt(ok: &ok);
209 if (ok)
210 tileCache->setMaxMemoryUsage(cacheSize);
211 }
212
213 /*
214 * Texture cache setup -- defaults to ByteSize (old behavior)
215 */
216 if (parameters.contains(QStringLiteral("mapbox.mapping.cache.texture.cost_strategy"))) {
217 QString cacheStrategy = parameters.value(QStringLiteral("mapbox.mapping.cache.texture.cost_strategy")).toString().toLower();
218 if (cacheStrategy == QLatin1String("bytesize"))
219 tileCache->setCostStrategyTexture(QGeoFileTileCache::ByteSize);
220 else
221 tileCache->setCostStrategyTexture(QGeoFileTileCache::Unitary);
222 } else {
223 tileCache->setCostStrategyTexture(QGeoFileTileCache::ByteSize);
224 }
225 if (parameters.contains(QStringLiteral("mapbox.mapping.cache.texture.size"))) {
226 bool ok = false;
227 int cacheSize = parameters.value(QStringLiteral("mapbox.mapping.cache.texture.size")).toString().toInt(ok: &ok);
228 if (ok)
229 tileCache->setExtraTextureUsage(cacheSize);
230 }
231
232 /* PREFETCHING */
233 if (parameters.contains(QStringLiteral("mapbox.mapping.prefetching_style"))) {
234 const QString prefetchingMode = parameters.value(QStringLiteral("mapbox.mapping.prefetching_style")).toString();
235 if (prefetchingMode == QStringLiteral("TwoNeighbourLayers"))
236 m_prefetchStyle = QGeoTiledMap::PrefetchTwoNeighbourLayers;
237 else if (prefetchingMode == QStringLiteral("OneNeighbourLayer"))
238 m_prefetchStyle = QGeoTiledMap::PrefetchNeighbourLayer;
239 else if (prefetchingMode == QStringLiteral("NoPrefetching"))
240 m_prefetchStyle = QGeoTiledMap::NoPrefetching;
241 }
242
243 setTileCache(tileCache);
244
245 *error = QGeoServiceProvider::NoError;
246 errorString->clear();
247}
248
249QGeoTiledMappingManagerEngineMapbox::~QGeoTiledMappingManagerEngineMapbox()
250{
251}
252
253QGeoMap *QGeoTiledMappingManagerEngineMapbox::createMap()
254{
255 QGeoTiledMap *map = new Map(this, 0);
256 map->setPrefetchStyle(m_prefetchStyle);
257 return map;
258}
259
260QT_END_NAMESPACE
261

source code of qtlocation/src/plugins/geoservices/mapbox/qgeotiledmappingmanagerenginemapbox.cpp