Skip to content

Commit afa0335

Browse files
committed
[Globe] Rework qgis tilesource update logic
1 parent c131ee2 commit afa0335

File tree

4 files changed

+69
-86
lines changed

4 files changed

+69
-86
lines changed

src/plugins/globe/globe_plugin.cpp

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,18 @@ void GlobePlugin::applyProjectSettings()
602602
}
603603
}
604604

605+
QgsRectangle GlobePlugin::getQGISLayerExtent() const
606+
{
607+
QList<QgsRectangle> extents = mLayerExtents.values();
608+
QgsRectangle fullExtent = extents.isEmpty() ? QgsRectangle() : extents.front();
609+
for ( int i = 1, n = extents.size(); i < n; ++i )
610+
{
611+
if ( !extents[i].isNull() )
612+
fullExtent.combineExtentWith( extents[i] );
613+
}
614+
return fullExtent;
615+
}
616+
605617
void GlobePlugin::showCurrentCoordinates( const osgEarth::GeoPoint& geoPoint )
606618
{
607619
osg::Vec3d pos = geoPoint.vec3d();
@@ -743,25 +755,12 @@ void GlobePlugin::setupProxy()
743755
settings.endGroup();
744756
}
745757

746-
void GlobePlugin::refreshQGISMapLayer( QgsRectangle rect )
758+
void GlobePlugin::refreshQGISMapLayer( const QgsRectangle& dirtyRect )
747759
{
748760
if ( mTileSource )
749761
{
750-
if ( rect.isEmpty() )
751-
{
752-
if ( mLayerExtents.isEmpty() )
753-
{
754-
return;
755-
}
756-
757-
rect = mLayerExtents.values().front();
758-
foreach ( const QgsRectangle& extent, mLayerExtents.values() )
759-
{
760-
rect.combineExtentWith( extent );
761-
}
762-
}
763762
mOsgViewer->getDatabasePager()->clear();
764-
mTileSource->refresh( rect );
763+
mTileSource->refresh( dirtyRect );
765764
mOsgViewer->requestRedraw();
766765
}
767766
}
@@ -885,11 +884,7 @@ void GlobePlugin::updateLayers()
885884
if ( mOsgViewer )
886885
{
887886
// Get previous full extent
888-
QgsRectangle fullExtent = mLayerExtents.isEmpty() ? QgsRectangle() : mLayerExtents.values().front();
889-
foreach ( const QgsRectangle& rect, mLayerExtents.values() )
890-
{
891-
fullExtent.combineExtentWith( rect );
892-
}
887+
QgsRectangle dirtyExtent = getQGISLayerExtent();
893888
mLayerExtents.clear();
894889

895890
QStringList drapedLayers;
@@ -939,19 +934,16 @@ void GlobePlugin::updateLayers()
939934
drapedLayers.append( mapLayer->id() );
940935
QgsRectangle extent = QgsCoordinateTransformCache::instance()->transform( mapLayer->crs().authid(), GEO_EPSG_CRS_AUTHID )->transform( mapLayer->extent() );
941936
mLayerExtents.insert( mapLayer->id(), extent );
942-
if ( fullExtent.isEmpty() )
943-
{
944-
fullExtent = extent;
945-
}
946-
else
947-
{
948-
fullExtent.combineExtentWith( extent );
949-
}
950937
}
951938
}
952939

953940
mTileSource->setLayerSet( drapedLayers );
954-
refreshQGISMapLayer( fullExtent );
941+
QgsRectangle newExtent = getQGISLayerExtent();
942+
if ( dirtyExtent.isNull() )
943+
dirtyExtent = newExtent;
944+
else if ( !newExtent.isNull() )
945+
dirtyExtent.combineExtentWith( newExtent );
946+
refreshQGISMapLayer( dirtyExtent );
955947
}
956948
}
957949

@@ -981,8 +973,9 @@ void GlobePlugin::layerChanged( QgsMapLayer* mapLayer )
981973
QStringList layerSet = mTileSource->layerSet();
982974
layerSet.removeAll( mapLayer->id() );
983975
mTileSource->setLayerSet( layerSet );
984-
refreshQGISMapLayer( mLayerExtents[mapLayer->id()] );
976+
QgsRectangle dirtyExtent = mLayerExtents[mapLayer->id()];
985977
mLayerExtents.remove( mapLayer->id() );
978+
refreshQGISMapLayer( dirtyExtent );
986979
}
987980
mMapNode->getMap()->removeModelLayer( mMapNode->getMap()->getModelLayerByName( mapLayer->id().toStdString() ) );
988981
addModelLayer( static_cast<QgsVectorLayer*>( mapLayer ), layerConfig );
@@ -1007,13 +1000,16 @@ void GlobePlugin::layerChanged( QgsMapLayer* mapLayer )
10071000
// Remove any model layer of that layer, in case one existed
10081001
mMapNode->getMap()->removeModelLayer( mMapNode->getMap()->getModelLayerByName( mapLayer->id().toStdString() ) );
10091002
QgsRectangle layerExtent = QgsCoordinateTransformCache::instance()->transform( mapLayer->crs().authid(), GEO_EPSG_CRS_AUTHID )->transform( mapLayer->extent() );
1010-
QgsRectangle updateExtent = layerExtent;
1003+
QgsRectangle dirtyExtent = layerExtent;
10111004
if ( mLayerExtents.contains( mapLayer->id() ) )
10121005
{
1013-
updateExtent.combineExtentWith( mLayerExtents[mapLayer->id()] );
1006+
if ( dirtyExtent.isNull() )
1007+
dirtyExtent = mLayerExtents[mapLayer->id()];
1008+
else if ( !mLayerExtents[mapLayer->id()].isNull() )
1009+
dirtyExtent.combineExtentWith( mLayerExtents[mapLayer->id()] );
10141010
}
10151011
mLayerExtents[mapLayer->id()] = layerExtent;
1016-
refreshQGISMapLayer( updateExtent );
1012+
refreshQGISMapLayer( dirtyExtent );
10171013
}
10181014
}
10191015
}

src/plugins/globe/globe_plugin.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class GLOBE_EXPORT GlobePlugin : public QObject, public QgisPlugin
157157
void addModelLayer( QgsVectorLayer* mapLayer , QgsGlobeVectorLayerConfig *layerConfig );
158158
void setupControls();
159159
void applyProjectSettings();
160+
QgsRectangle getQGISLayerExtent() const;
160161

161162
private slots:
162163
void setGlobeEnabled( bool enabled );
@@ -165,7 +166,7 @@ class GLOBE_EXPORT GlobePlugin : public QObject, public QgisPlugin
165166
void applySettings();
166167
void layerChanged( QgsMapLayer* mapLayer = 0 );
167168
void rebuildQGISLayer();
168-
void refreshQGISMapLayer( QgsRectangle rect = QgsRectangle() );
169+
void refreshQGISMapLayer( const QgsRectangle &dirtyRect );
169170
void updateTileStats( int queued, int tot );
170171

171172
signals:

src/plugins/globe/qgsglobetilesource.cpp

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ QgsGlobeTileImage::QgsGlobeTileImage( QgsGlobeTileSource* tileSource, const QgsR
5656
, mTileSource( tileSource )
5757
, mTileExtent( tileExtent )
5858
, mTileSize( tileSize )
59-
, mImageUpdatePending( false )
6059
, mLod( tileLod )
6160
{
61+
mTileSource->addTile( this );
6262
#ifdef GLOBE_SHOW_TILE_STATS
6363
QgsGlobeTileStatistics::instance()->updateTileCount( + 1 );
6464
#endif
@@ -69,10 +69,8 @@ QgsGlobeTileImage::QgsGlobeTileImage( QgsGlobeTileSource* tileSource, const QgsR
6969
GL_BGRA, GL_UNSIGNED_BYTE,
7070
mTileData, osg::Image::NO_DELETE );
7171

72-
mLastUpdateTime = osgEarth::DateTime().asTimeStamp();
7372
mTileSource->mTileUpdateManager.addTile( const_cast<QgsGlobeTileImage*>( this ) );
7473
mDpi = 72;
75-
mImageUpdatePending = true;
7674
#else
7775
QImage qImage( mTileData, mTileSize, mTileSize, QImage::Format_ARGB32_Premultiplied );
7876
QPainter painter( &qImage );
@@ -84,35 +82,19 @@ QgsGlobeTileImage::QgsGlobeTileImage( QgsGlobeTileSource* tileSource, const QgsR
8482
mTileData, osg::Image::NO_DELETE );
8583
flipVertical();
8684
mDpi = qImage.logicalDpiX();
87-
mLastUpdateTime = osgEarth::DateTime().asTimeStamp();
8885
#endif
8986
}
9087

9188
QgsGlobeTileImage::~QgsGlobeTileImage()
9289
{
90+
mTileSource->removeTile( this );
9391
mTileSource->mTileUpdateManager.removeTile( this );
9492
delete[] mTileData;
9593
#ifdef GLOBE_SHOW_TILE_STATS
9694
QgsGlobeTileStatistics::instance()->updateTileCount( -1 );
9795
#endif
9896
}
9997

100-
bool QgsGlobeTileImage::requiresUpdateCall() const
101-
{
102-
if ( mLastUpdateTime < mTileSource->mLastModifiedTime )
103-
{
104-
mLastUpdateTime = mTileSource->mLastModifiedTime;
105-
if ( !mTileExtent.intersects( mTileSource->mLastUpdateExtent ) )
106-
{
107-
return false;
108-
}
109-
mTileSource->mTileUpdateManager.addTile( const_cast<QgsGlobeTileImage*>( this ) );
110-
mImageUpdatePending = true;
111-
return true;
112-
}
113-
return mImageUpdatePending;
114-
}
115-
11698
QgsMapSettings QgsGlobeTileImage::createSettings( int dpi , const QStringList &layerSet ) const
11799
{
118100
QgsMapSettings settings;
@@ -143,7 +125,6 @@ void QgsGlobeTileImage::update( osg::NodeVisitor * )
143125
mTileData, osg::Image::NO_DELETE );
144126
flipVertical();
145127
mUpdatedImage = QImage();
146-
mImageUpdatePending = false;
147128
}
148129
}
149130

@@ -237,14 +218,17 @@ void QgsGlobeTileUpdateManager::renderingFinished()
237218
QgsGlobeTileSource::QgsGlobeTileSource( QgsMapCanvas* canvas, const osgEarth::TileSourceOptions& options )
238219
: TileSource( options )
239220
, mCanvas( canvas )
240-
, mLastModifiedTime( 0 )
241221
{
222+
osgEarth::GeoExtent geoextent( osgEarth::SpatialReference::get( "wgs84" ), -180., -90., 180., 90. );
223+
osgEarth::DataExtentList extents;
224+
extents.push_back( geoextent );
225+
getDataExtents() = extents;
226+
dirtyDataExtents();
242227
}
243228

244229
osgEarth::TileSource::Status QgsGlobeTileSource::initialize( const osgDB::Options* /*dbOptions*/ )
245230
{
246231
setProfile( osgEarth::Registry::instance()->getGlobalGeodeticProfile() );
247-
mLastModifiedTime = osgEarth::DateTime().asTimeStamp();
248232
return STATUS_OK;
249233
}
250234

@@ -266,36 +250,40 @@ osg::Image* QgsGlobeTileSource::createImage( const osgEarth::TileKey& key, osgEa
266250
return new QgsGlobeTileImage( this, tileExtent, getPixelsPerTile(), key.getLOD() );
267251
}
268252

269-
bool QgsGlobeTileSource::hasDataInExtent( const osgEarth::GeoExtent &extent ) const
253+
void QgsGlobeTileSource::refresh( const QgsRectangle& dirtyExtent )
270254
{
271-
osgEarth::Bounds bounds = extent.bounds();
272-
QgsRectangle requestExtent( bounds.xMin(), bounds.yMin(), bounds.xMax(), bounds.yMax() );
273-
return requestExtent.intersects( mViewExtent );
255+
mTileUpdateManager.updateLayerSet( mLayerSet );
256+
mTileListLock.lock();
257+
foreach ( QgsGlobeTileImage* tile, mTiles )
258+
{
259+
if ( tile->extent().intersects( dirtyExtent ) )
260+
{
261+
mTileUpdateManager.addTile( tile );
262+
}
263+
}
264+
mTileListLock.unlock();
274265
}
275266

276-
bool QgsGlobeTileSource::hasData( const osgEarth::TileKey& key ) const
267+
void QgsGlobeTileSource::setLayerSet( const QStringList &layerSet )
277268
{
278-
const osgEarth::GeoExtent& tileExtent = key.getExtent();
279-
QgsRectangle rect( tileExtent.xMin(), tileExtent.yMin(), tileExtent.xMax(), tileExtent.yMax() );
280-
return rect.intersects( mViewExtent );
269+
mLayerSet = layerSet;
281270
}
282271

283-
void QgsGlobeTileSource::refresh( const QgsRectangle& updateExtent )
272+
const QStringList& QgsGlobeTileSource::layerSet() const
284273
{
285-
osgEarth::TimeStamp old = mLastModifiedTime;
286-
mLastModifiedTime = osgEarth::DateTime().asTimeStamp();
287-
mTileUpdateManager.updateLayerSet( mLayerSet );
288-
mLastUpdateExtent = updateExtent;
289-
QgsDebugMsg( QString( "Updated QGIS map layer modified time from %1 to %2" ).arg( old ).arg( mLastModifiedTime ) );
290-
mViewExtent = QgsCoordinateTransformCache::instance()->transform( mCanvas->mapSettings().destinationCrs().authid(), GEO_EPSG_CRS_AUTHID )->transform( mCanvas->fullExtent() );
274+
return mLayerSet;
291275
}
292276

293-
void QgsGlobeTileSource::setLayerSet( const QStringList &layerSet )
277+
void QgsGlobeTileSource::addTile( QgsGlobeTileImage* tile )
294278
{
295-
mLayerSet = layerSet;
279+
mTileListLock.lock();
280+
mTiles.append( tile );
281+
mTileListLock.unlock();
296282
}
297283

298-
const QStringList& QgsGlobeTileSource::layerSet() const
284+
void QgsGlobeTileSource::removeTile( QgsGlobeTileImage* tile )
299285
{
300-
return mLayerSet;
286+
mTileListLock.lock();
287+
mTiles.removeOne( tile );
288+
mTileListLock.unlock();
301289
}

src/plugins/globe/qgsglobetilesource.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ class QgsGlobeTileImage : public osg::Image
6060
public:
6161
QgsGlobeTileImage( QgsGlobeTileSource* tileSource, const QgsRectangle& tileExtent, int tileSize, int tileLod );
6262
~QgsGlobeTileImage();
63-
bool requiresUpdateCall() const;
63+
bool requiresUpdateCall() const { return !mUpdatedImage.isNull(); }
6464
QgsMapSettings createSettings( int dpi, const QStringList &layerSet ) const;
6565
void setUpdatedImage( const QImage& image ) { mUpdatedImage = image; }
6666
int dpi() const { return mDpi; }
67+
const QgsRectangle& extent() { return mTileExtent; }
6768

6869
void update( osg::NodeVisitor * );
6970

@@ -72,10 +73,8 @@ class QgsGlobeTileImage : public osg::Image
7273
private:
7374
QgsGlobeTileSource* mTileSource;
7475
QgsRectangle mTileExtent;
75-
mutable osgEarth::TimeStamp mLastUpdateTime;
7676
int mTileSize;
7777
unsigned char* mTileData;
78-
mutable bool mImageUpdatePending;
7978
int mLod;
8079
int mDpi;
8180
QImage mUpdatedImage;
@@ -114,25 +113,24 @@ class QgsGlobeTileSource : public osgEarth::TileSource
114113
Status initialize( const osgDB::Options *dbOptions ) override;
115114
osg::Image* createImage( const osgEarth::TileKey& key, osgEarth::ProgressCallback* progress ) override;
116115
osg::HeightField* createHeightField( const osgEarth::TileKey &/*key*/, osgEarth::ProgressCallback* /*progress*/ ) override { return 0; }
117-
bool hasDataInExtent( const osgEarth::GeoExtent &extent ) const override;
118-
bool hasData( const osgEarth::TileKey& key ) const override;
119116

120117
bool isDynamic() const override { return true; }
121-
osgEarth::TimeStamp getLastModifiedTime() const override { return mLastModifiedTime; }
122118

123-
void refresh( const QgsRectangle &updateExtent );
119+
void refresh( const QgsRectangle &dirtyExtent );
124120
void setLayerSet( const QStringList& layerSet );
125121
const QStringList &layerSet() const;
126122

127123
private:
128124
friend class QgsGlobeTileImage;
129125

126+
QMutex mTileListLock;
127+
QList<QgsGlobeTileImage*> mTiles;
130128
QgsMapCanvas* mCanvas;
131-
osgEarth::TimeStamp mLastModifiedTime;
132-
QgsRectangle mViewExtent;
133-
QgsRectangle mLastUpdateExtent;
134129
QStringList mLayerSet;
135130
QgsGlobeTileUpdateManager mTileUpdateManager;
131+
132+
void addTile( QgsGlobeTileImage* tile );
133+
void removeTile( QgsGlobeTileImage* tile );
136134
};
137135

138136
#endif // QGSGLOBETILESOURCE_H

0 commit comments

Comments
 (0)