diff options
author | Basel Hashisho <basel.hashisho@nokia.com> | 2012-02-17 12:07:01 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-03-09 16:04:55 +0100 |
commit | 53e5f30e06091f5b05c9283657e454bc45896075 (patch) | |
tree | a9a5be51418b008f61165b510f1d87aa748a020e /src/plugins/geoservices/nokia/qgeotilefetcher_nokia.cpp | |
parent | f61e60ec2d66e181caf9e81b126936075e6fca5d (diff) | |
download | qtlocation-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.cpp | 375 |
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 ¶m) +{ + 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 |