/**************************************************************************** ** ** 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 "qgeotiledmappingmanagerengine_p.h" #include "qgeotiledmappingmanagerengine_p_p.h" #include "qgeotilefetcher_p.h" #include "qgeotiledmap_p.h" #include "qgeotilerequestmanager_p.h" #include "qgeofiletilecache_p.h" #include "qgeotilespec_p.h" #include #include #include #include QT_BEGIN_NAMESPACE QGeoTiledMappingManagerEngine::QGeoTiledMappingManagerEngine(QObject *parent) : QGeoMappingManagerEngine(parent), m_prefetchStyle(QGeoTiledMap::PrefetchTwoNeighbourLayers), d_ptr(new QGeoTiledMappingManagerEnginePrivate) { } /*! Destroys this mapping manager. */ QGeoTiledMappingManagerEngine::~QGeoTiledMappingManagerEngine() { delete d_ptr; } /*! Sets the tile fetcher. Takes ownership of the QObject. */ void QGeoTiledMappingManagerEngine::setTileFetcher(QGeoTileFetcher *fetcher) { Q_D(QGeoTiledMappingManagerEngine); if (d->fetcher_) d->fetcher_->deleteLater(); fetcher->setParent(this); d->fetcher_ = fetcher; qRegisterMetaType(); connect(d->fetcher_, SIGNAL(tileFinished(QGeoTileSpec,QByteArray,QString)), this, SLOT(engineTileFinished(QGeoTileSpec,QByteArray,QString)), Qt::QueuedConnection); connect(d->fetcher_, SIGNAL(tileError(QGeoTileSpec,QString)), this, SLOT(engineTileError(QGeoTileSpec,QString)), Qt::QueuedConnection); engineInitialized(); } QGeoTileFetcher *QGeoTiledMappingManagerEngine::tileFetcher() { Q_D(QGeoTiledMappingManagerEngine); return d->fetcher_; } QGeoMap *QGeoTiledMappingManagerEngine::createMap() { return NULL; } void QGeoTiledMappingManagerEngine::releaseMap(QGeoTiledMap *map) { d_ptr->mapHash_.remove(map); QHash > newTileHash = d_ptr->tileHash_; typedef QHash >::const_iterator h_iter; h_iter hi = d_ptr->tileHash_.constBegin(); h_iter hend = d_ptr->tileHash_.constEnd(); for (; hi != hend; ++hi) { QSet maps = hi.value(); if (maps.contains(map)) { maps.remove(map); if (maps.isEmpty()) newTileHash.remove(hi.key()); else newTileHash.insert(hi.key(), maps); } } d_ptr->tileHash_ = newTileHash; } void QGeoTiledMappingManagerEngine::updateTileRequests(QGeoTiledMap *map, const QSet &tilesAdded, const QSet &tilesRemoved) { Q_D(QGeoTiledMappingManagerEngine); typedef QSet::const_iterator tile_iter; // add and remove tiles from tileset for this map QSet oldTiles = d->mapHash_.value(map); tile_iter rem = tilesRemoved.constBegin(); tile_iter remEnd = tilesRemoved.constEnd(); for (; rem != remEnd; ++rem) { oldTiles.remove(*rem); } tile_iter add = tilesAdded.constBegin(); tile_iter addEnd = tilesAdded.constEnd(); for (; add != addEnd; ++add) { oldTiles.insert(*add); } d->mapHash_.insert(map, oldTiles); // add and remove map from mapset for the tiles QSet reqTiles; QSet cancelTiles; rem = tilesRemoved.constBegin(); for (; rem != remEnd; ++rem) { QSet mapSet = d->tileHash_.value(*rem); mapSet.remove(map); if (mapSet.isEmpty()) { cancelTiles.insert(*rem); d->tileHash_.remove(*rem); } else { d->tileHash_.insert(*rem, mapSet); } } add = tilesAdded.constBegin(); for (; add != addEnd; ++add) { QSet mapSet = d->tileHash_.value(*add); if (mapSet.isEmpty()) { reqTiles.insert(*add); } mapSet.insert(map); d->tileHash_.insert(*add, mapSet); } cancelTiles -= reqTiles; QMetaObject::invokeMethod(d->fetcher_, "updateTileRequests", Qt::QueuedConnection, Q_ARG(QSet, reqTiles), Q_ARG(QSet, cancelTiles)); } void QGeoTiledMappingManagerEngine::engineTileFinished(const QGeoTileSpec &spec, const QByteArray &bytes, const QString &format) { Q_D(QGeoTiledMappingManagerEngine); QSet maps = d->tileHash_.value(spec); typedef QSet::const_iterator map_iter; map_iter map = maps.constBegin(); map_iter mapEnd = maps.constEnd(); for (; map != mapEnd; ++map) { QSet tileSet = d->mapHash_.value(*map); tileSet.remove(spec); if (tileSet.isEmpty()) d->mapHash_.remove(*map); else d->mapHash_.insert(*map, tileSet); } d->tileHash_.remove(spec); tileCache()->insert(spec, bytes, format, d->cacheHint_); map = maps.constBegin(); mapEnd = maps.constEnd(); for (; map != mapEnd; ++map) { (*map)->requestManager()->tileFetched(spec); } } void QGeoTiledMappingManagerEngine::engineTileError(const QGeoTileSpec &spec, const QString &errorString) { Q_D(QGeoTiledMappingManagerEngine); QSet maps = d->tileHash_.value(spec); typedef QSet::const_iterator map_iter; map_iter map = maps.constBegin(); map_iter mapEnd = maps.constEnd(); for (; map != mapEnd; ++map) { QSet tileSet = d->mapHash_.value(*map); tileSet.remove(spec); if (tileSet.isEmpty()) d->mapHash_.remove(*map); else d->mapHash_.insert(*map, tileSet); } d->tileHash_.remove(spec); for (map = maps.constBegin(); map != mapEnd; ++map) { (*map)->requestManager()->tileError(spec, errorString); } emit tileError(spec, errorString); } void QGeoTiledMappingManagerEngine::setTileSize(const QSize &tileSize) { Q_D(QGeoTiledMappingManagerEngine); d->tileSize_ = tileSize; } void QGeoTiledMappingManagerEngine::setTileVersion(int version) { Q_D(QGeoTiledMappingManagerEngine); if (d->m_tileVersion != version) { d->m_tileVersion = version; emit tileVersionChanged(); } } QSize QGeoTiledMappingManagerEngine::tileSize() const { Q_D(const QGeoTiledMappingManagerEngine); return d->tileSize_; } int QGeoTiledMappingManagerEngine::tileVersion() const { Q_D(const QGeoTiledMappingManagerEngine); return d->m_tileVersion; } QAbstractGeoTileCache::CacheAreas QGeoTiledMappingManagerEngine::cacheHint() const { Q_D(const QGeoTiledMappingManagerEngine); return d->cacheHint_; } void QGeoTiledMappingManagerEngine::setCacheHint(QAbstractGeoTileCache::CacheAreas cacheHint) { Q_D(QGeoTiledMappingManagerEngine); d->cacheHint_ = cacheHint; } /*! Sets the tile cache. Takes ownership of the QObject. */ void QGeoTiledMappingManagerEngine::setTileCache(QAbstractGeoTileCache *cache) { Q_D(QGeoTiledMappingManagerEngine); Q_ASSERT_X(!d->tileCache_, Q_FUNC_INFO, "This should be called only once"); cache->setParent(this); d->tileCache_ = cache; d->tileCache_->init(); } QAbstractGeoTileCache *QGeoTiledMappingManagerEngine::tileCache() { Q_D(QGeoTiledMappingManagerEngine); if (!d->tileCache_) { QString cacheDirectory; if (!managerName().isEmpty()) cacheDirectory = QAbstractGeoTileCache::baseLocationCacheDirectory() + managerName(); d->tileCache_ = new QGeoFileTileCache(cacheDirectory); d->tileCache_->init(); } return d->tileCache_; } QSharedPointer QGeoTiledMappingManagerEngine::getTileTexture(const QGeoTileSpec &spec) { return d_ptr->tileCache_->get(spec); } /******************************************************************************* *******************************************************************************/ QGeoTiledMappingManagerEnginePrivate::QGeoTiledMappingManagerEnginePrivate() : m_tileVersion(-1), cacheHint_(QAbstractGeoTileCache::AllCaches), tileCache_(0), fetcher_(0) { } QGeoTiledMappingManagerEnginePrivate::~QGeoTiledMappingManagerEnginePrivate() { } QT_END_NAMESPACE