1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company 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 "qgeotilefetcher_nokia.h"
38#include "qgeomapreply_nokia.h"
39#include "qgeotiledmap_nokia.h"
40#include "qgeotiledmappingmanagerengine_nokia.h"
41#include "qgeonetworkaccessmanager.h"
42#include "qgeouriprovider.h"
43#include "uri_constants.h"
44
45#include <QtLocation/private/qgeotilespec_p.h>
46
47#include <QDebug>
48#include <QSize>
49#include <QDir>
50#include <QUrl>
51#include <QTime>
52
53#include <map>
54
55QT_BEGIN_NAMESPACE
56
57namespace
58{
59 QString sizeToStr(int size)
60 {
61 if (size > 256)
62 return QStringLiteral("512");
63 else if (size > 128)
64 return QStringLiteral("256");
65 else
66 return QStringLiteral("128"); // 128 pixel tiles are deprecated.
67 }
68
69 bool isAerialType(const QString mapScheme)
70 {
71 return mapScheme.startsWith(s: "satellite") || mapScheme.startsWith(s: "hybrid") || mapScheme.startsWith(s: "terrain");
72 }
73}
74QGeoTileFetcherNokia::QGeoTileFetcherNokia(const QVariantMap &parameters,
75 QGeoNetworkAccessManager *networkManager,
76 QGeoTiledMappingManagerEngineNokia *engine,
77 const QSize &tileSize,
78 int ppi)
79: QGeoTileFetcher(engine), m_engineNokia(engine), m_networkManager(networkManager), m_ppi(ppi), m_copyrightsReply(0),
80 m_baseUriProvider(new QGeoUriProvider(this, parameters, QStringLiteral("here.mapping.host"), MAP_TILES_HOST)),
81 m_aerialUriProvider(new QGeoUriProvider(this, parameters, QStringLiteral("here.mapping.host.aerial"), MAP_TILES_HOST_AERIAL))
82{
83 Q_ASSERT(networkManager);
84 m_tileSize = qMax(a: tileSize.width(), b: tileSize.height());
85 m_networkManager->setParent(this);
86
87 m_applicationId = parameters.value(QStringLiteral("here.app_id")).toString();
88 m_token = parameters.value(QStringLiteral("here.token")).toString();
89}
90
91QGeoTileFetcherNokia::~QGeoTileFetcherNokia()
92{
93}
94
95QGeoTiledMapReply *QGeoTileFetcherNokia::getTileImage(const QGeoTileSpec &spec)
96{
97 // TODO add error detection for if request.connectivityMode() != QGraphicsGeoMap::OnlineMode
98 int ppi = m_ppi;
99 if ((spec.mapId() == 2) || (spec.mapId() == 12) || (spec.mapId() == 21)) {
100 ppi = 72; // HiDpi apparently not supported for these maps
101 } else if ((spec.mapId() >= 7 && spec.mapId() <= 11)
102 || (spec.mapId() == 14)
103 || (spec.mapId() == 16)
104 || (spec.mapId() == 18)
105 || (spec.mapId() == 20)) {
106 ppi = 250; // LoDpi apparently not supported for these maps
107 }
108
109 QString rawRequest = getRequestString(spec, ppi);
110 if (rawRequest.isEmpty()) {
111 return new QGeoTiledMapReply(QGeoTiledMapReply::UnknownError,
112 tr(s: "Mapping manager no longer exists"), this);
113 }
114
115 QNetworkRequest netRequest((QUrl(rawRequest))); // The extra pair of parens disambiguates this from a function declaration
116 netRequest.setAttribute(code: QNetworkRequest::HttpPipeliningAllowedAttribute, value: true);
117
118 QNetworkReply *netReply = m_networkManager->get(request: netRequest);
119
120 QGeoTiledMapReply *mapReply = new QGeoMapReplyNokia(netReply, spec);
121
122 return mapReply;
123}
124
125QString QGeoTileFetcherNokia::getRequestString(const QGeoTileSpec &spec, int ppi)
126{
127 if (!m_engineNokia)
128 return QString();
129
130 static const QString http("http://");
131 static const QString path("/maptile/2.1/maptile/newest/");
132 static const QChar slash('/');
133
134 QString requestString = http;
135
136 const QString mapScheme = m_engineNokia->getScheme(mapId: spec.mapId());
137 if (isAerialType(mapScheme))
138 requestString += m_aerialUriProvider->getCurrentHost();
139 else
140 requestString += m_baseUriProvider->getCurrentHost();
141
142 requestString += path;
143 requestString += mapScheme;
144 requestString += slash;
145 requestString += QString::number(spec.zoom());
146 requestString += slash;
147 requestString += QString::number(spec.x());
148 requestString += slash;
149 requestString += QString::number(spec.y());
150 requestString += slash;
151 requestString += ((ppi > 72)) ? sizeToStr(size: m_tileSize * 2) : sizeToStr(size: m_tileSize);
152 static const QString slashpng("/png8");
153 requestString += slashpng;
154
155 if (!m_token.isEmpty() && !m_applicationId.isEmpty()) { // TODO: remove the if
156 requestString += "?token=";
157 requestString += m_token;
158
159 requestString += "&app_id=";
160 requestString += m_applicationId;
161 }
162
163 requestString += "&ppi=" + QString::number(ppi);
164
165 requestString += "&lg=";
166 requestString += getLanguageString();
167 return requestString;
168}
169
170QString QGeoTileFetcherNokia::getLanguageString() const
171{
172 if (!m_engineNokia)
173 return QStringLiteral("ENG");
174
175 QLocale locale = m_engineNokia.data()->locale();
176
177 // English is the default, where no ln is specified. We hardcode the languages
178 // here even though the entire list is updated automagically from the server.
179 // The current languages are Arabic, Chinese, Simplified Chinese, English
180 // French, German, Italian, Polish, Russian and Spanish. The default is English.
181 // These are actually available from the same host under the URL: /maptiler/v2/info
182
183 switch (locale.language()) {
184 case QLocale::Arabic:
185 return QStringLiteral("ARA");
186 case QLocale::Chinese:
187 if (locale.script() == QLocale::TraditionalChineseScript)
188 return QStringLiteral("CHI");
189 else
190 return QStringLiteral("CHT");
191 case QLocale::Dutch:
192 return QStringLiteral("DUT");
193 case QLocale::French:
194 return QStringLiteral("FRE");
195 case QLocale::German:
196 return QStringLiteral("GER");
197 case QLocale::Gaelic:
198 return QStringLiteral("GLE");
199 case QLocale::Greek:
200 return QStringLiteral("GRE");
201 case QLocale::Hebrew:
202 return QStringLiteral("HEB");
203 case QLocale::Hindi:
204 return QStringLiteral("HIN");
205 case QLocale::Indonesian:
206 return QStringLiteral("IND");
207 case QLocale::Italian:
208 return QStringLiteral("ITA");
209 case QLocale::Persian:
210 return QStringLiteral("PER");
211 case QLocale::Polish:
212 return QStringLiteral("POL");
213 case QLocale::Portuguese:
214 return QStringLiteral("POR");
215 case QLocale::Russian:
216 return QStringLiteral("RUS");
217 case QLocale::Sinhala:
218 return QStringLiteral("SIN");
219 case QLocale::Spanish:
220 return QStringLiteral("SPA");
221 case QLocale::Thai:
222 return QStringLiteral("THA");
223 case QLocale::Turkish:
224 return QStringLiteral("TUR");
225 case QLocale::Ukrainian:
226 return QStringLiteral("UKR");
227 case QLocale::Urdu:
228 return QStringLiteral("URD");
229 case QLocale::Vietnamese:
230 return QStringLiteral("VIE");
231
232 default:
233 return QStringLiteral("ENG");
234 }
235 // No "lg" param means that we want English.
236}
237
238QString QGeoTileFetcherNokia::token() const
239{
240 return m_token;
241}
242
243QString QGeoTileFetcherNokia::applicationId() const
244{
245 return m_applicationId;
246}
247
248void QGeoTileFetcherNokia::copyrightsFetched()
249{
250 if (m_engineNokia && m_copyrightsReply->error() == QNetworkReply::NoError) {
251 QMetaObject::invokeMethod(obj: m_engineNokia.data(),
252 member: "loadCopyrightsDescriptorsFromJson",
253 type: Qt::QueuedConnection,
254 Q_ARG(QByteArray, m_copyrightsReply->readAll()));
255 }
256
257 m_copyrightsReply->deleteLater();
258}
259
260void QGeoTileFetcherNokia::versionFetched()
261{
262 if (m_engineNokia && m_versionReply->error() == QNetworkReply::NoError) {
263 QMetaObject::invokeMethod(obj: m_engineNokia.data(),
264 member: "parseNewVersionInfo",
265 type: Qt::QueuedConnection,
266 Q_ARG(QByteArray, m_versionReply->readAll()));
267 }
268
269 m_versionReply->deleteLater();
270}
271
272void QGeoTileFetcherNokia::fetchCopyrightsData()
273{
274 QString copyrightUrl = QStringLiteral("http://");
275
276 copyrightUrl += m_baseUriProvider->getCurrentHost();
277 copyrightUrl += QStringLiteral("/maptile/2.1/copyright/newest?output=json");
278
279 if (!token().isEmpty()) {
280 copyrightUrl += QStringLiteral("&token=");
281 copyrightUrl += token();
282 }
283
284 if (!applicationId().isEmpty()) {
285 copyrightUrl += QStringLiteral("&app_id=");
286 copyrightUrl += applicationId();
287 }
288
289 QNetworkRequest netRequest((QUrl(copyrightUrl)));
290 m_copyrightsReply = m_networkManager->get(request: netRequest);
291 if (m_copyrightsReply->error() != QNetworkReply::NoError) {
292 qWarning() << __FUNCTION__ << m_copyrightsReply->errorString();
293 m_copyrightsReply->deleteLater();
294 return;
295 }
296
297 if (m_copyrightsReply->isFinished()) {
298 copyrightsFetched();
299 } else {
300 connect(sender: m_copyrightsReply, SIGNAL(finished()), receiver: this, SLOT(copyrightsFetched()));
301 }
302}
303
304void QGeoTileFetcherNokia::fetchVersionData()
305{
306 QString versionUrl = QStringLiteral("http://");
307
308 versionUrl += m_baseUriProvider->getCurrentHost();
309 versionUrl += QStringLiteral("/maptile/2.1/version");
310
311 if (!token().isEmpty()) {
312 versionUrl += QStringLiteral("?token=");
313 versionUrl += token();
314 }
315
316 if (!applicationId().isEmpty()) {
317 versionUrl += QStringLiteral("&app_id=");
318 versionUrl += applicationId();
319 }
320
321 QNetworkRequest netRequest((QUrl(versionUrl)));
322 m_versionReply = m_networkManager->get(request: netRequest);
323
324 if (m_versionReply->error() != QNetworkReply::NoError) {
325 qWarning() << __FUNCTION__ << m_versionReply->errorString();
326 m_versionReply->deleteLater();
327 return;
328 }
329
330 if (m_versionReply->isFinished())
331 versionFetched();
332 else
333 connect(sender: m_versionReply, SIGNAL(finished()), receiver: this, SLOT(versionFetched()));
334}
335
336QT_END_NAMESPACE
337

source code of qtlocation/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp