summaryrefslogtreecommitdiff
path: root/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp
diff options
context:
space:
mode:
authorBasel Hashisho <basel.hashisho@nokia.com>2012-02-17 12:07:01 +0100
committerQt by Nokia <qt-info@nokia.com>2012-03-09 16:04:55 +0100
commit53e5f30e06091f5b05c9283657e454bc45896075 (patch)
treea9a5be51418b008f61165b510f1d87aa748a020e /src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp
parentf61e60ec2d66e181caf9e81b126936075e6fca5d (diff)
downloadqtlocation-53e5f30e06091f5b05c9283657e454bc45896075.tar.gz
Refactoring of QtLocation API
Refactoring QGeoMap, QGeoMappingManager, QGeoMappingManagerEngine Introducing QGeoMapData, QGeoTiledMap, QGeoTiledMappingManagerEngine, QGeoTileFetcher QGeoMap: Container for QGeoMapData QGeoMapData: No tiles data/functionality QGeoTiledMapData: Implements tiles data/functionality. QGeoMappingManager: Looses tiles-related data/functionality. QGeoMappingManagerEngine => QGeoMappingManagerEngine (no tiles data/functionality) QGeoTiledMappingManagerEngine (implements tiles-related data/functionality). QGeoTileFetcher: Implements tile fetching functionality from tiles provider. This commit compiles and runs through mapviewer example. Tests also were adjusted to fit refactored architecture. Change-Id: Id2b62d62d5cd4aaca8295c67e44c009cde636462 Reviewed-by: Alex <alex.blasche@nokia.com>
Diffstat (limited to 'src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp')
-rw-r--r--src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp375
1 files changed, 375 insertions, 0 deletions
diff --git a/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp b/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp
new file mode 100644
index 00000000..49ff9d38
--- /dev/null
+++ b/src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp
@@ -0,0 +1,375 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtLocation module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 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 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+** This file is part of the Ovi services plugin for the Maps and
+** Navigation API. The use of these services, whether by use of the
+** plugin or by other means, is governed by the terms and conditions
+** described by the file OVI_SERVICES_TERMS_AND_CONDITIONS.txt in
+** this package, located in the directory containing the Ovi services
+** plugin source code.
+**
+****************************************************************************/
+
+#include "qgeotilefetcher_nokia.h"
+#include "qgeomapreply_nokia.h"
+#include "qgeotiledmapdata_nokia.h"
+
+#include <qgeotilespec.h>
+#include <qgeotilecache_p.h>
+
+#include <QNetworkAccessManager>
+#include <QNetworkDiskCache>
+#include <QNetworkProxy>
+#include <QSize>
+#include <QDir>
+#include <QUrl>
+
+#define LARGE_TILE_DIMENSION 256
+
+#if defined(Q_OS_WINCE_WM) || defined(Q_WS_MAEMO_5) || defined(Q_WS_MAEMO_6)
+#undef DISK_CACHE_ENABLED
+#else
+#define DISK_CACHE_ENABLED 1
+#endif
+
+#undef DISK_CACHE_ENABLED
+
+QT_BEGIN_NAMESPACE
+
+const char* MAPTILES_HOST = "1-4.maptile.lbs.ovi.com";
+const char* MAPTILES_HOST_CN = "a-k.maptile.maps.svc.nokia.com.cn";
+
+QGeoTileFetcherNokia::QGeoTileFetcherNokia(QGeoTiledMappingManagerEngine *engine)
+ : QGeoTileFetcher(engine),
+ m_cache(0),
+ m_token(QGeoServiceProviderFactoryNokia::defaultToken),
+ m_referer(QGeoServiceProviderFactoryNokia::defaultReferer),
+ m_firstSubdomain(QChar::Null),
+ m_maxSubdomains(0)
+{
+}
+
+QGeoTileFetcherNokia::~QGeoTileFetcherNokia() {}
+
+bool QGeoTileFetcherNokia::init()
+{
+ setHost(MAPTILES_HOST);
+
+ m_networkManager = new QNetworkAccessManager(this);
+
+ if (m_parameters->contains("mapping.proxy")) {
+ QString proxy = m_parameters->value("mapping.proxy").toString();
+ if (!proxy.isEmpty()) {
+ QUrl proxyUrl(proxy);
+ if (proxyUrl.isValid()) {
+ m_networkManager->setProxy(QNetworkProxy(QNetworkProxy::HttpProxy,
+ proxyUrl.host(),
+ proxyUrl.port(8080),
+ proxyUrl.userName(),
+ proxyUrl.password()));
+ }
+ }
+ }
+
+ if (m_parameters->contains("mapping.host")) {
+ QString host = m_parameters->value("mapping.host").toString();
+ if (!host.isEmpty())
+ setHost(host);
+ }
+
+ if (m_parameters->contains("mapping.referer")) {
+ m_referer = m_parameters->value("mapping.referer").toString();
+ }
+
+ if (m_parameters->contains("mapping.app_id")) {
+ m_applicationId = m_parameters->value("mapping.app_id").toString();
+ }
+ else if (m_parameters->contains("app_id")) {
+ m_applicationId = m_parameters->value("app_id").toString();
+ }
+
+ if (m_parameters->contains("mapping.token")) {
+ m_token = m_parameters->value("mapping.token").toString();
+ }
+ else if (m_parameters->contains("token")) {
+ m_token = m_parameters->value("token").toString();
+ }
+#ifdef DISK_CACHE_ENABLED
+ QString cacheDir;
+ if (parameters.contains("mapping.cache.directory"))
+ cacheDir = parameters.value("mapping.cache.directory").toString();
+
+ if (cacheDir.isEmpty()) {
+ cacheDir = QDir::temp().path()+"/maptiles";
+ }
+ if (!cacheDir.isEmpty()) {
+ m_cache = new QNetworkDiskCache(this);
+ QDir dir;
+ dir.mkpath(cacheDir);
+ dir.setPath(cacheDir);
+
+ m_cache->setCacheDirectory(dir.path());
+
+ if (parameters.contains("mapping.cache.size")) {
+ bool ok = false;
+ qint64 cacheSize = parameters.value("mapping.cache.size").toString().toLongLong(&ok);
+ if (ok)
+ m_cache->setMaximumCacheSize(cacheSize);
+ }
+
+ if (m_cache->maximumCacheSize() > DISK_CACHE_MAX_SIZE)
+ m_cache->setMaximumCacheSize(DISK_CACHE_MAX_SIZE);
+
+ m_networkManager->setCache(m_cache);
+ }
+#endif
+
+#ifdef USE_CHINA_NETWORK_REGISTRATION
+ connect(&m_networkInfo, SIGNAL(currentMobileCountryCodeChanged(int, const QString&)),
+ SLOT(currentMobileCountryCodeChanged(int, const QString&)));
+ currentMobileCountryCodeChanged(0, m_networkInfo.currentMobileCountryCode(0));
+#endif
+
+ if (!isValidParameter(m_applicationId) || !isValidParameter(m_referer)) {
+ qWarning() << "Qt Location requires usage of app_id and token parameters obtained from:";
+ qWarning() << "https://api.forum.nokia.com/ovi-api/ui/registration";
+ }
+
+ // Temporary testing aid for setting China maptile server
+ QFile file("/.enable_china_maptile_server");
+ if (file.exists()) {
+ qDebug() << "CHINA MAPTILE SERVER SET FOR TESTING PURPOSES.";
+ setHost(MAPTILES_HOST_CN);
+ }
+
+ return true;
+}
+
+QGeoTiledMapReply* QGeoTileFetcherNokia::getTileImage(const QGeoTileSpec &spec)
+{
+ // TODO add error detection for if request.connectivityMode() != QGraphicsGeoMap::OnlineMode
+ QString rawRequest = getRequestString(spec);
+
+ QNetworkRequest netRequest((QUrl(rawRequest))); // The extra pair of parens disambiguates this from a function declaration
+ netRequest.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
+
+#ifdef DISK_CACHE_ENABLED
+ netRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
+#endif
+
+ QNetworkReply* netReply = m_networkManager->get(netRequest);
+
+ QGeoTiledMapReply* mapReply = new QGeoMapReplyNokia(netReply, spec);
+
+ // TODO goes badly on linux
+ //qDebug() << "request: " << QString::number(reinterpret_cast<int>(mapReply), 16) << " " << request.row() << "," << request.column();
+ // this one might work better. It follows defined behaviour, unlike reinterpret_cast
+ //qDebug("request: %p %i,%i @ %i", mapReply, request.row(), request.column(), request.zoomLevel());
+ return mapReply;
+}
+
+QString QGeoTileFetcherNokia::getRequestString(const QGeoTileSpec &spec)
+{
+ const char subdomain = m_maxSubdomains ? m_firstSubdomain.toAscii() +
+ (spec.x() + spec.y()) % m_maxSubdomains : 0;
+ static const QString http("http://");
+ static const QString path("/maptiler/v2/maptile/newest/");
+ static const QChar dot('.');
+ static const QChar slash('/');
+
+ QString requestString = http;
+ if (subdomain != 0) {
+ requestString += subdomain;
+ requestString += dot;
+ }
+ requestString += m_host;
+ requestString += path;
+
+ requestString += mapIdToStr(spec.mapId());
+ requestString += slash;
+ requestString += QString::number(spec.zoom());
+ requestString += slash;
+ requestString += QString::number(spec.x());
+ requestString += slash;
+ requestString += QString::number(spec.y());
+ requestString += slash;
+ requestString += sizeToStr(m_tileSize);
+ static const QString slashpng("/png8");
+ requestString += slashpng;
+
+ if (!m_token.isEmpty()) {
+ requestString += "?token=";
+ requestString += m_token;
+
+ if (!m_referer.isEmpty()) {
+ requestString += "&referer=";
+ requestString += m_referer;
+ }
+ } else if (!m_referer.isEmpty()) {
+ requestString += "?referer=";
+ requestString += m_referer;
+ }
+ if (!m_applicationId.isEmpty()) {
+ requestString += "&app_id=";
+ requestString += m_applicationId;
+ }
+ return requestString;
+}
+
+QString QGeoTileFetcherNokia::sizeToStr(const QSize &size)
+{
+ static const QString s256("256");
+ static const QString s128("128");
+ if (size.height() >= LARGE_TILE_DIMENSION ||
+ size.width() >= LARGE_TILE_DIMENSION)
+ return s256;
+ else
+ return s128;
+}
+
+QString QGeoTileFetcherNokia::mapIdToStr(int mapId)
+{
+ typedef std::map<int, QString> MapTypeRegistry;
+ static MapTypeRegistry registeredTypes;
+ if (registeredTypes.empty()) {
+ registeredTypes[0] = "normal.day";
+ registeredTypes[1] = "normal.day";
+ registeredTypes[2] = "satellite.day";
+ registeredTypes[3] = "terrain.day";
+ registeredTypes[4] = "hybrid.day";
+ registeredTypes[5] = "normal.day.transit";
+ registeredTypes[6] = "normal.day.grey";
+ registeredTypes[7] = "normal.day.mobile";
+ registeredTypes[8] = "terrain.day.mobile";
+ registeredTypes[9] = "hybrid.day.mobile";
+ registeredTypes[10] = "normal.day.transit.mobile";
+ registeredTypes[11] = "normal.day.grey.mobile";
+ }
+
+ MapTypeRegistry::const_iterator it = registeredTypes.find(mapId);
+ if (it != registeredTypes.end()) {
+ return it->second;
+ }
+
+ qWarning() << "Unknown mapId: " << mapId;
+ return "normal.day";
+}
+
+const QString & QGeoTileFetcherNokia::referer() const
+{
+ return m_referer;
+}
+
+void QGeoTileFetcherNokia::setParams(const QMap<QString, QVariant> *parameters)
+{
+ m_parameters = parameters;
+}
+
+void QGeoTileFetcherNokia::setTileSize(QSize tileSize)
+{
+ m_tileSize = tileSize;
+}
+
+const QString & QGeoTileFetcherNokia::token() const
+{
+ return m_token;
+}
+
+const QString & QGeoTileFetcherNokia::host() const
+{
+ return m_host;
+}
+
+const QString & QGeoTileFetcherNokia::applicationId() const
+{
+ return m_applicationId;
+}
+QChar QGeoTileFetcherNokia::firstSubdomain() const
+{
+ return m_firstSubdomain;
+}
+
+unsigned char QGeoTileFetcherNokia::maxSubdomains() const
+{
+ return m_maxSubdomains;
+}
+
+void QGeoTileFetcherNokia::setHost(const QString &host)
+{
+ if (host.length() > 4 && host.at(1) == QChar('-') && host.at(3) == QChar('.')) {
+ QString realHost = host.right(host.length() - 4);
+ m_firstSubdomain = host.at(0);
+ m_maxSubdomains = host.at(2).toAscii() - host.at(0).toAscii() + 1;
+ m_host = realHost;
+ } else {
+ m_host = host;
+ m_firstSubdomain = QChar::Null;
+ m_maxSubdomains = 0;
+ }
+}
+
+#ifdef USE_CHINA_NETWORK_REGISTRATION
+void QGeoTileFetcherNokia::currentMobileCountryCodeChanged(int interface, const QString & mcc)
+{
+ Q_UNUSED(interface)
+ if (mcc == "460" || mcc == "461" || mcc == "454" || mcc == "455") {
+ setHost(MAPTILES_HOST_CN);
+ }
+}
+#endif
+
+bool QGeoTileFetcherNokia::isValidParameter(const QString &param)
+{
+ if (param.isEmpty())
+ return false;
+
+ if (param.length() > 512)
+ return false;
+
+ foreach (QChar c, param) {
+ if (!c.isLetterOrNumber() || c.toAscii() != '%' || c.toAscii() != '-' ||
+ c.toAscii() != '+' || c.toAscii() != '_') {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+QT_END_NAMESPACE