Esempio n. 1
0
void StackedTileLoader::updateTile( TileId const &tileId, QImage const &tileImage )
{
    Q_ASSERT( !tileImage.isNull() );

    d->detectMaxTileLevel();

    const TileId stackedTileId( 0, tileId.zoomLevel(), tileId.x(), tileId.y() );

    StackedTile * displayedTile = d->m_tilesOnDisplay.take( stackedTileId );
    if ( displayedTile ) {
        Q_ASSERT( !d->m_tileCache.contains( stackedTileId ) );

        QVector<QSharedPointer<TextureTile> > tiles = displayedTile->tiles();
        delete displayedTile;
        displayedTile = 0;

        for ( int i = 0; i < tiles.count(); ++ i) {
            if ( tiles[i]->id() == tileId ) {
                const Blending *blending = tiles[i]->blending();
                tiles[i] = QSharedPointer<TextureTile>( new TextureTile( tileId, tileImage, blending ) );
            }
        }

        const QImage resultImage = d->m_layerDecorator.merge( stackedTileId, tiles );
        displayedTile = new StackedTile( stackedTileId, resultImage, tiles );
        d->m_tilesOnDisplay.insert( stackedTileId, displayedTile );

        emit tileUpdateAvailable( stackedTileId );
    } else {
        d->m_tileCache.remove( stackedTileId );
    }
}
Esempio n. 2
0
const StackedTile* StackedTileLoader::loadTile( TileId const & stackedTileId )
{
    // check if the tile is in the hash
    d->m_cacheLock.lockForRead();
    StackedTile * stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
    d->m_cacheLock.unlock();
    if ( stackedTile ) {
        stackedTile->setUsed( true );
        return stackedTile;
    }
    // here ends the performance critical section of this method

    d->m_cacheLock.lockForWrite();

    // has another thread loaded our tile due to a race condition?
    stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
    if ( stackedTile ) {
        Q_ASSERT( stackedTile->used() && "other thread should have marked tile as used" );
        d->m_cacheLock.unlock();
        return stackedTile;
    }

    // the tile was not in the hash so check if it is in the cache
    stackedTile = d->m_tileCache.take( stackedTileId );
    if ( stackedTile ) {
        Q_ASSERT( !stackedTile->used() && "tiles in m_tileCache are invisible and should thus be marked as unused" );
        stackedTile->setUsed( true );
        d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
        d->m_cacheLock.unlock();
        return stackedTile;
    }

    // tile (valid) has not been found in hash or cache, so load it from disk
    // and place it in the hash from where it will get transferred to the cache

    mDebug() << "load tile from disk:" << stackedTileId;

    stackedTile = d->m_layerDecorator->loadTile( stackedTileId );
    Q_ASSERT( stackedTile );
    stackedTile->setUsed( true );

    d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
    d->m_cacheLock.unlock();

    emit tileLoaded( stackedTileId );

    return stackedTile;
}
Esempio n. 3
0
const StackedTile* StackedTileLoader::loadTile( TileId const & stackedTileId )
{
    // check if the tile is in the hash
    d->m_cacheLock.lockForRead();
    StackedTile * stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
    d->m_cacheLock.unlock();
    if ( stackedTile ) {
        stackedTile->setUsed( true );
        return stackedTile;
    }
    // here ends the performance critical section of this method

    d->m_cacheLock.lockForWrite();

    // has another thread loaded our tile due to a race condition?
    stackedTile = d->m_tilesOnDisplay.value( stackedTileId, 0 );
    if ( stackedTile ) {
        stackedTile->setUsed( true );
        d->m_cacheLock.unlock();
        return stackedTile;
    }

    mDebug() << "StackedTileLoader::loadTile" << stackedTileId.toString();

    // the tile was not in the hash so check if it is in the cache
    stackedTile = d->m_tileCache.take( stackedTileId );
    if ( stackedTile ) {
        stackedTile->setUsed( true );
        d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
        d->m_cacheLock.unlock();
        return stackedTile;
    }

    // tile (valid) has not been found in hash or cache, so load it from disk
    // and place it in the hash from where it will get transferred to the cache

    // mDebug() << "load Tile from Disk: " << stackedTileId.toString();

    QVector<QSharedPointer<TextureTile> > tiles;
    QVector<GeoSceneTexture const *> const textureLayers = d->findRelevantTextureLayers( stackedTileId );
    QVector<GeoSceneTexture const *>::const_iterator pos = textureLayers.constBegin();
    QVector<GeoSceneTexture const *>::const_iterator const end = textureLayers.constEnd();
    for (; pos != end; ++pos ) {
        GeoSceneTexture const * const textureLayer = *pos;
        TileId const tileId( textureLayer->sourceDir(), stackedTileId.zoomLevel(),
                             stackedTileId.x(), stackedTileId.y() );
        mDebug() << "StackedTileLoader::loadTile: tile" << textureLayer->sourceDir()
                 << tileId.toString() << textureLayer->tileSize();
        const QImage tileImage = d->m_tileLoader->loadTile( tileId, DownloadBrowse );
        const Blending *blending = d->m_blendingFactory.findBlending( textureLayer->blending() );
        if ( blending == 0 && !textureLayer->blending().isEmpty() ) {
            mDebug() << Q_FUNC_INFO << "could not find blending" << textureLayer->blending();
        }
        QSharedPointer<TextureTile> tile( new TextureTile( tileId, tileImage, blending ) );
        tiles.append( tile );
    }
    Q_ASSERT( !tiles.isEmpty() );

    const QImage resultImage = d->m_layerDecorator.merge( stackedTileId, tiles );
    stackedTile = new StackedTile( stackedTileId, resultImage, tiles );
    stackedTile->setUsed( true );

    d->m_tilesOnDisplay[ stackedTileId ] = stackedTile;
    d->m_cacheLock.unlock();
    return stackedTile;
}