15static void setSSL(QGeoMapType &mapType,
bool isHTTPS)
17 QVariantMap metadata = mapType.metadata();
18 metadata[
"isHTTPS"] = isHTTPS;
20 mapType = QGeoMapType(mapType.style(), mapType.name(), mapType.description(), mapType.mobile(),
21 mapType.night(), mapType.mapId(), mapType.pluginName(), mapType.cameraCapabilities(),
26 const QList<TileProvider *> &providers,
27 const QGeoCameraCapabilities &cameraCapabilities)
34 for (
int i = 0; i < providers.size(); ++i) {
35 TileProvider *p = providers[i];
44 if (m_provider && m_provider->isValid())
45 setSSL(m_mapType, m_provider->isHTTPS());
47 connect(
this, &QGeoTileProviderOsm::resolutionFinished,
this, &QGeoTileProviderOsm::updateCameraCapabilities);
221 m_cameraCapabilities.setMinimumZoomLevel(minimumZoomLevel());
222 m_cameraCapabilities.setMaximumZoomLevel(maximumZoomLevel());
224 m_mapType = QGeoMapType(m_mapType.style(), m_mapType.name(), m_mapType.description(), m_mapType.mobile(),
225 m_mapType.night(), m_mapType.mapId(), m_mapType.pluginName(), m_cameraCapabilities,
226 m_mapType.metadata());
228 if (m_provider && m_provider->isValid())
229 setSSL(m_mapType, m_provider->isHTTPS());
267TileProvider::TileProvider(
const QUrl &urlRedirector,
bool highDpi)
268: m_status(Idle), m_urlRedirector(urlRedirector), m_nm(
nullptr), m_timestamp(defaultTs), m_highDpi(highDpi)
270 if (!m_urlRedirector.isValid())
274TileProvider::TileProvider(
const QString &urlTemplate,
275 const QString &format,
276 const QString ©RightMap,
277 const QString ©RightData,
279 int minimumZoomLevel,
280 int maximumZoomLevel)
281: m_status(Invalid), m_nm(
nullptr), m_urlTemplate(urlTemplate),
282 m_format(format), m_copyRightMap(copyRightMap), m_copyRightData(copyRightData),
283 m_minimumZoomLevel(minimumZoomLevel), m_maximumZoomLevel(maximumZoomLevel), m_timestamp(defaultTs), m_highDpi(highDpi)
292void TileProvider::resolveProvider()
303 m_status = Resolving;
307 QNetworkRequest request;
308 request.setHeader(QNetworkRequest::UserAgentHeader, QByteArrayLiteral(
"QGeoTileFetcherOsm"));
309 request.setUrl(m_urlRedirector);
310 request.setAttribute(QNetworkRequest::BackgroundRequestAttribute,
true);
311 request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork);
312 QNetworkReply *reply = m_nm->get(request);
313 connect(reply, &QNetworkReply::finished,
314 this, &TileProvider::onNetworkReplyFinished);
315 connect(reply, &QNetworkReply::errorOccurred,
316 this, &TileProvider::onNetworkReplyError);
319void TileProvider::handleError(QNetworkReply::NetworkError error)
322 case QNetworkReply::ConnectionRefusedError:
323 case QNetworkReply::TooManyRedirectsError:
324 case QNetworkReply::InsecureRedirectError:
325 case QNetworkReply::ContentAccessDenied:
326 case QNetworkReply::ContentOperationNotPermittedError:
327 case QNetworkReply::ContentNotFoundError:
328 case QNetworkReply::AuthenticationRequiredError:
329 case QNetworkReply::ContentGoneError:
330 case QNetworkReply::OperationNotImplementedError:
331 case QNetworkReply::ServiceUnavailableError:
342void TileProvider::onNetworkReplyFinished()
344 QNetworkReply *reply =
static_cast<QNetworkReply *>(sender());
345 reply->deleteLater();
355 emit resolutionFinished(
this);
359 QObject errorEmitter;
360 QMetaObject::Connection errorEmitterConnection =
361 connect(&errorEmitter, &QObject::destroyed,
this, [
this](){
this->resolutionError(
this); });
363 if (reply->error() != QNetworkReply::NoError) {
364 handleError(reply->error());
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
419 QJsonParseError error;
420 QJsonDocument d = QJsonDocument::fromJson(reply->readAll(), &error);
421 if (error.error != QJsonParseError::NoError) {
422 qWarning() <<
"QGeoTileProviderOsm: Error parsing redirection data: "<<error.errorString() <<
"at "<<m_urlRedirector;
426 qWarning() <<
"QGeoTileProviderOsm: Invalid redirection data" <<
"at "<<m_urlRedirector;
429 const QJsonObject json = d.object();
430 const QJsonValue urlTemplate = json.value(QLatin1String(
"UrlTemplate"));
431 const QJsonValue imageFormat = json.value(QLatin1String(
"ImageFormat"));
432 const QJsonValue copyRightMap = json.value(QLatin1String(
"MapCopyRight"));
433 const QJsonValue copyRightData = json.value(QLatin1String(
"DataCopyRight"));
434 if ( urlTemplate == QJsonValue::Undefined
435 || imageFormat == QJsonValue::Undefined
436 || copyRightMap == QJsonValue::Undefined
437 || copyRightData == QJsonValue::Undefined
438 || !urlTemplate.isString()
439 || !imageFormat.isString()
440 || !copyRightMap.isString()
441 || !copyRightData.isString()) {
442 qWarning() <<
"QGeoTileProviderOsm: Incomplete redirection data" <<
"at "<<m_urlRedirector;
446 m_urlTemplate = urlTemplate.toString();
447 m_format = imageFormat.toString();
448 m_copyRightMap = copyRightMap.toString();
449 m_copyRightData = copyRightData.toString();
451 const QJsonValue enabled = json.value(QLatin1String(
"Enabled"));
452 if (enabled.isBool() && ! enabled.toBool()) {
453 qWarning() <<
"QGeoTileProviderOsm: Tileserver disabled" <<
"at "<<m_urlRedirector;
457 const QJsonValue copyRightStyle = json.value(QLatin1String(
"StyleCopyRight"));
458 if (copyRightStyle != QJsonValue::Undefined && copyRightStyle.isString())
459 m_copyRightStyle = copyRightStyle.toString();
461 m_minimumZoomLevel = 0;
462 m_maximumZoomLevel = 20;
463 const QJsonValue minZoom = json.value(QLatin1String(
"MinimumZoomLevel"));
464 if (minZoom.isDouble())
465 m_minimumZoomLevel = qBound(0,
int(minZoom.toDouble()),
maxValidZoom);
466 const QJsonValue maxZoom = json.value(QLatin1String(
"MaximumZoomLevel"));
467 if (maxZoom.isDouble())
468 m_maximumZoomLevel = qBound(0,
int(maxZoom.toDouble()),
maxValidZoom);
470 const QJsonValue ts = json.value(QLatin1String(
"Timestamp"));
472 m_timestamp = QDateTime::fromString(ts.toString(), Qt::ISODate);
476 QObject::disconnect(errorEmitterConnection);
477 emit resolutionFinished(
this);
491void TileProvider::setupProvider()
493 if (m_urlTemplate.isEmpty())
496 if (m_format.isEmpty())
499 if (m_minimumZoomLevel < 0 || m_minimumZoomLevel > 30)
502 if (m_maximumZoomLevel < 0 || m_maximumZoomLevel > 30 || m_maximumZoomLevel < m_minimumZoomLevel)
507 offset[0] = m_urlTemplate.indexOf(QLatin1String(
"%x"));
511 offset[1] = m_urlTemplate.indexOf(QLatin1String(
"%y"));
515 offset[2] = m_urlTemplate.indexOf(QLatin1String(
"%z"));
519 int sortedOffsets[3];
520 std::copy(offset, offset + 3, sortedOffsets);
521 sort2(sortedOffsets[0]
,sortedOffsets[1]
);
522 sort2(sortedOffsets[1]
,sortedOffsets[2]
);
523 sort2(sortedOffsets[0]
,sortedOffsets[1]
);
525 int min = sortedOffsets[0];
526 int max = sortedOffsets[2];
527 int mid = sortedOffsets[1];
530 for (
int i=0; i<3; i++) {
531 if (offset[0] == sortedOffsets[i])
533 else if (offset[1] == sortedOffsets[i])
539 m_urlPrefix = m_urlTemplate.mid(0 , min);
540 m_urlSuffix = m_urlTemplate.mid(max + 2, m_urlTemplate.size() - max - 2);
542 paramsSep[0] = m_urlTemplate.mid(min + 2, mid - min - 2);
543 paramsSep[1] = m_urlTemplate.mid(mid + 2, max - mid - 2);
617QUrl TileProvider::tileAddress(
int x,
int y,
int z)
const
619 if (z < m_minimumZoomLevel || z > m_maximumZoomLevel)
621 int params[3] = { x, y, z};
624 url += QString::number(params[paramsLUT[0]]);
626 url += QString::number(params[paramsLUT[1]]);
628 url += QString::number(params[paramsLUT[2]]);