| /**************************************************************************** |
| ** |
| ** Copyright (C) 2015 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 "qgeotilefetcher_nokia.h" |
| #include "qgeomapreply_nokia.h" |
| #include "qgeotiledmap_nokia.h" |
| #include "qgeotiledmappingmanagerengine_nokia.h" |
| #include "qgeonetworkaccessmanager.h" |
| #include "qgeouriprovider.h" |
| #include "uri_constants.h" |
| |
| #include <QtLocation/private/qgeotilespec_p.h> |
| |
| #include <QDebug> |
| #include <QSize> |
| #include <QDir> |
| #include <QUrl> |
| #include <QTime> |
| |
| #include <map> |
| |
| QT_BEGIN_NAMESPACE |
| |
| namespace |
| { |
| QString sizeToStr(int size) |
| { |
| if (size > 256) |
| return QStringLiteral("512"); |
| else if (size > 128) |
| return QStringLiteral("256"); |
| else |
| return QStringLiteral("128"); // 128 pixel tiles are deprecated. |
| } |
| |
| bool isAerialType(const QString mapScheme) |
| { |
| return mapScheme.startsWith("satellite") || mapScheme.startsWith("hybrid") || mapScheme.startsWith("terrain"); |
| } |
| } |
| QGeoTileFetcherNokia::QGeoTileFetcherNokia(const QVariantMap ¶meters, |
| QGeoNetworkAccessManager *networkManager, |
| QGeoTiledMappingManagerEngineNokia *engine, |
| 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(); |
| m_token = parameters.value(QStringLiteral("here.token")).toString(); |
| } |
| |
| QGeoTileFetcherNokia::~QGeoTileFetcherNokia() |
| { |
| } |
| |
| QGeoTiledMapReply *QGeoTileFetcherNokia::getTileImage(const QGeoTileSpec &spec) |
| { |
| // TODO add error detection for if request.connectivityMode() != QGraphicsGeoMap::OnlineMode |
| int ppi = m_ppi; |
| if ((spec.mapId() == 2) || (spec.mapId() == 12) || (spec.mapId() == 21)) { |
| ppi = 72; // HiDpi apparently not supported for these maps |
| } else if ((spec.mapId() >= 7 && spec.mapId() <= 11) |
| || (spec.mapId() == 14) |
| || (spec.mapId() == 16) |
| || (spec.mapId() == 18) |
| || (spec.mapId() == 20)) { |
| ppi = 250; // LoDpi 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); |
| } |
| |
| QNetworkRequest netRequest((QUrl(rawRequest))); // The extra pair of parens disambiguates this from a function declaration |
| netRequest.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); |
| |
| QNetworkReply *netReply = m_networkManager->get(netRequest); |
| |
| QGeoTiledMapReply *mapReply = new QGeoMapReplyNokia(netReply, spec); |
| |
| return mapReply; |
| } |
| |
| QString QGeoTileFetcherNokia::getRequestString(const QGeoTileSpec &spec, int ppi) |
| { |
| if (!m_engineNokia) |
| return QString(); |
| |
| static const QString http("http://"); |
| static const QString path("/maptile/2.1/maptile/newest/"); |
| static const QChar slash('/'); |
| |
| QString requestString = http; |
| |
| const QString mapScheme = m_engineNokia->getScheme(spec.mapId()); |
| if (isAerialType(mapScheme)) |
| requestString += m_aerialUriProvider->getCurrentHost(); |
| else |
| requestString += m_baseUriProvider->getCurrentHost(); |
| |
| requestString += path; |
| requestString += mapScheme; |
| requestString += slash; |
| requestString += QString::number(spec.zoom()); |
| requestString += slash; |
| requestString += QString::number(spec.x()); |
| requestString += slash; |
| requestString += QString::number(spec.y()); |
| requestString += slash; |
| requestString += ((ppi > 72)) ? sizeToStr(m_tileSize * 2) : sizeToStr(m_tileSize); |
| static const QString slashpng("/png8"); |
| requestString += slashpng; |
| |
| if (!m_token.isEmpty() && !m_applicationId.isEmpty()) { // TODO: remove the if |
| requestString += "?token="; |
| requestString += m_token; |
| |
| requestString += "&app_id="; |
| requestString += m_applicationId; |
| } |
| |
| requestString += "&ppi=" + QString::number(ppi); |
| |
| requestString += "&lg="; |
| requestString += getLanguageString(); |
| return requestString; |
| } |
| |
| QString QGeoTileFetcherNokia::getLanguageString() const |
| { |
| if (!m_engineNokia) |
| return QStringLiteral("ENG"); |
| |
| QLocale locale = m_engineNokia.data()->locale(); |
| |
| // English is the default, where no ln is specified. We hardcode the languages |
| // here even though the entire list is updated automagically from the server. |
| // The current languages are Arabic, Chinese, Simplified Chinese, English |
| // French, German, Italian, Polish, Russian and Spanish. The default is English. |
| // These are actually available from the same host under the URL: /maptiler/v2/info |
| |
| switch (locale.language()) { |
| case QLocale::Arabic: |
| return QStringLiteral("ARA"); |
| case QLocale::Chinese: |
| if (locale.script() == QLocale::TraditionalChineseScript) |
| return QStringLiteral("CHI"); |
| else |
| return QStringLiteral("CHT"); |
| case QLocale::Dutch: |
| return QStringLiteral("DUT"); |
| case QLocale::French: |
| return QStringLiteral("FRE"); |
| case QLocale::German: |
| return QStringLiteral("GER"); |
| case QLocale::Gaelic: |
| return QStringLiteral("GLE"); |
| case QLocale::Greek: |
| return QStringLiteral("GRE"); |
| case QLocale::Hebrew: |
| return QStringLiteral("HEB"); |
| case QLocale::Hindi: |
| return QStringLiteral("HIN"); |
| case QLocale::Indonesian: |
| return QStringLiteral("IND"); |
| case QLocale::Italian: |
| return QStringLiteral("ITA"); |
| case QLocale::Persian: |
| return QStringLiteral("PER"); |
| case QLocale::Polish: |
| return QStringLiteral("POL"); |
| case QLocale::Portuguese: |
| return QStringLiteral("POR"); |
| case QLocale::Russian: |
| return QStringLiteral("RUS"); |
| case QLocale::Sinhala: |
| return QStringLiteral("SIN"); |
| case QLocale::Spanish: |
| return QStringLiteral("SPA"); |
| case QLocale::Thai: |
| return QStringLiteral("THA"); |
| case QLocale::Turkish: |
| return QStringLiteral("TUR"); |
| case QLocale::Ukrainian: |
| return QStringLiteral("UKR"); |
| case QLocale::Urdu: |
| return QStringLiteral("URD"); |
| case QLocale::Vietnamese: |
| return QStringLiteral("VIE"); |
| |
| default: |
| return QStringLiteral("ENG"); |
| } |
| // No "lg" param means that we want English. |
| } |
| |
| QString QGeoTileFetcherNokia::token() const |
| { |
| return m_token; |
| } |
| |
| QString QGeoTileFetcherNokia::applicationId() const |
| { |
| return m_applicationId; |
| } |
| |
| void QGeoTileFetcherNokia::copyrightsFetched() |
| { |
| if (m_engineNokia && m_copyrightsReply->error() == QNetworkReply::NoError) { |
| QMetaObject::invokeMethod(m_engineNokia.data(), |
| "loadCopyrightsDescriptorsFromJson", |
| Qt::QueuedConnection, |
| Q_ARG(QByteArray, m_copyrightsReply->readAll())); |
| } |
| |
| m_copyrightsReply->deleteLater(); |
| } |
| |
| void QGeoTileFetcherNokia::versionFetched() |
| { |
| if (m_engineNokia && m_versionReply->error() == QNetworkReply::NoError) { |
| QMetaObject::invokeMethod(m_engineNokia.data(), |
| "parseNewVersionInfo", |
| Qt::QueuedConnection, |
| Q_ARG(QByteArray, m_versionReply->readAll())); |
| } |
| |
| m_versionReply->deleteLater(); |
| } |
| |
| void QGeoTileFetcherNokia::fetchCopyrightsData() |
| { |
| QString copyrightUrl = QStringLiteral("http://"); |
| |
| copyrightUrl += m_baseUriProvider->getCurrentHost(); |
| copyrightUrl += QStringLiteral("/maptile/2.1/copyright/newest?output=json"); |
| |
| if (!token().isEmpty()) { |
| copyrightUrl += QStringLiteral("&token="); |
| copyrightUrl += token(); |
| } |
| |
| if (!applicationId().isEmpty()) { |
| copyrightUrl += QStringLiteral("&app_id="); |
| copyrightUrl += applicationId(); |
| } |
| |
| QNetworkRequest netRequest((QUrl(copyrightUrl))); |
| m_copyrightsReply = m_networkManager->get(netRequest); |
| if (m_copyrightsReply->error() != QNetworkReply::NoError) { |
| qWarning() << __FUNCTION__ << m_copyrightsReply->errorString(); |
| m_copyrightsReply->deleteLater(); |
| return; |
| } |
| |
| if (m_copyrightsReply->isFinished()) { |
| copyrightsFetched(); |
| } else { |
| connect(m_copyrightsReply, SIGNAL(finished()), this, SLOT(copyrightsFetched())); |
| } |
| } |
| |
| void QGeoTileFetcherNokia::fetchVersionData() |
| { |
| QString versionUrl = QStringLiteral("http://"); |
| |
| versionUrl += m_baseUriProvider->getCurrentHost(); |
| versionUrl += QStringLiteral("/maptile/2.1/version"); |
| |
| if (!token().isEmpty()) { |
| versionUrl += QStringLiteral("?token="); |
| versionUrl += token(); |
| } |
| |
| if (!applicationId().isEmpty()) { |
| versionUrl += QStringLiteral("&app_id="); |
| versionUrl += applicationId(); |
| } |
| |
| QNetworkRequest netRequest((QUrl(versionUrl))); |
| m_versionReply = m_networkManager->get(netRequest); |
| |
| if (m_versionReply->error() != QNetworkReply::NoError) { |
| qWarning() << __FUNCTION__ << m_versionReply->errorString(); |
| m_versionReply->deleteLater(); |
| return; |
| } |
| |
| if (m_versionReply->isFinished()) |
| versionFetched(); |
| else |
| connect(m_versionReply, SIGNAL(finished()), this, SLOT(versionFetched())); |
| } |
| |
| QT_END_NAMESPACE |