mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-18 00:03:05 -04:00
Use TaskManager to build index
This commit is contained in:
parent
ba867b46c6
commit
4081bea801
@ -42,10 +42,9 @@ do the searches on data reprojected to the given CRS. For accurate reprojection
|
||||
to set the correct ``transformContext`` if a ``destinationCrs`` is specified. This is usually taken
|
||||
from the current :py:func:`QgsProject.transformContext()`
|
||||
|
||||
:param asynchronous: if ``False``, point locator init() method will block until index is completely
|
||||
finished. if ``True``, index building will be done in another thread and init() method returns
|
||||
immediatly. initStarted() and initFinished() signals can be used to control current state of
|
||||
the point locator.
|
||||
:param asynchronous: if ``False``, point locator init() method will block until point locator index
|
||||
is completely built. if ``True``, index building will be done in another thread and init() method returns
|
||||
immediately. initFinished() signal will be emitted once the initialization is over.
|
||||
|
||||
If ``extent`` is not ``None``, the locator will index only a subset of the layer which falls within that extent.
|
||||
%End
|
||||
@ -246,11 +245,6 @@ Emitted whenever index has been built and initialization is finished
|
||||
features, otherwise ``True``
|
||||
%End
|
||||
|
||||
void initStarted();
|
||||
%Docstring
|
||||
Emitted whenever index initialization has started
|
||||
%End
|
||||
|
||||
protected:
|
||||
bool rebuildIndex( int maxFeaturesToIndex = -1 );
|
||||
protected slots:
|
||||
|
@ -177,13 +177,15 @@ Emitted when the snapping settings object changes.
|
||||
%End
|
||||
|
||||
protected:
|
||||
virtual void prepareIndexStarting();
|
||||
|
||||
virtual void prepareIndexStarting( int count );
|
||||
%Docstring
|
||||
Called when starting to index
|
||||
This methods is now deprecated and never called
|
||||
%End
|
||||
virtual void prepareIndexFinished();
|
||||
|
||||
virtual void prepareIndexProgress( int index );
|
||||
%Docstring
|
||||
Called when finished indexing a layer
|
||||
This methods is now deprecated and never called
|
||||
%End
|
||||
|
||||
void clearAllLocators();
|
||||
|
@ -25,12 +25,6 @@ Snapping utils instance that is connected to a canvas and updates the configurat
|
||||
public:
|
||||
QgsMapCanvasSnappingUtils( QgsMapCanvas *canvas, QObject *parent = 0 );
|
||||
|
||||
protected:
|
||||
virtual void prepareIndexStarting();
|
||||
|
||||
virtual void prepareIndexFinished();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -317,6 +317,7 @@ SET(QGIS_CORE_SRCS
|
||||
qgspluginlayerregistry.cpp
|
||||
qgspointxy.cpp
|
||||
qgspointlocator.cpp
|
||||
qgspointlocatorinittask.cpp
|
||||
qgsproject.cpp
|
||||
qgsprojectbadlayerhandler.cpp
|
||||
qgsprojectfiletransform.cpp
|
||||
@ -708,6 +709,7 @@ SET(QGIS_CORE_MOC_HDRS
|
||||
qgspluginlayer.h
|
||||
qgspointxy.h
|
||||
qgspointlocator.h
|
||||
qgspointlocatorinittask.h
|
||||
qgsproject.h
|
||||
qgsproxyprogresstask.h
|
||||
qgsrelationmanager.h
|
||||
|
@ -22,9 +22,11 @@
|
||||
#include "qgis.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsrenderer.h"
|
||||
#include "qgsapplication.h"
|
||||
#include "qgsvectorlayerfeatureiterator.h"
|
||||
#include "qgsexpressioncontextutils.h"
|
||||
#include "qgslinestring.h"
|
||||
#include "qgspointlocatorinittask.h"
|
||||
#include <spatialindex/SpatialIndex.h>
|
||||
|
||||
#include <QLinkedListIterator>
|
||||
@ -543,8 +545,6 @@ QgsPointLocator::QgsPointLocator( QgsVectorLayer *layer, const QgsCoordinateRefe
|
||||
connect( mLayer, &QgsVectorLayer::geometryChanged, this, &QgsPointLocator::onGeometryChanged );
|
||||
connect( mLayer, &QgsVectorLayer::attributeValueChanged, this, &QgsPointLocator::onAttributeValueChanged );
|
||||
connect( mLayer, &QgsVectorLayer::dataChanged, this, &QgsPointLocator::destroyIndex );
|
||||
|
||||
connect( &mFutureWatcher, &QFutureWatcher<bool>::finished, this, &QgsPointLocator::onRebuildIndexFinished );
|
||||
}
|
||||
|
||||
|
||||
@ -560,8 +560,8 @@ QgsCoordinateReferenceSystem QgsPointLocator::destinationCrs() const
|
||||
|
||||
void QgsPointLocator::setExtent( const QgsRectangle *extent )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
// already running, return!
|
||||
if ( mIsIndexing )
|
||||
// already indexing, return!
|
||||
return;
|
||||
|
||||
mExtent.reset( extent ? new QgsRectangle( *extent ) : nullptr );
|
||||
@ -571,8 +571,8 @@ void QgsPointLocator::setExtent( const QgsRectangle *extent )
|
||||
|
||||
void QgsPointLocator::setRenderContext( const QgsRenderContext *context )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
// already running, return!
|
||||
if ( mIsIndexing )
|
||||
// already indexing, return!
|
||||
return;
|
||||
|
||||
disconnect( mLayer, &QgsVectorLayer::styleChanged, this, &QgsPointLocator::destroyIndex );
|
||||
@ -588,10 +588,10 @@ void QgsPointLocator::setRenderContext( const QgsRenderContext *context )
|
||||
|
||||
}
|
||||
|
||||
|
||||
void QgsPointLocator::onRebuildIndexFinished()
|
||||
void QgsPointLocator::onRebuildIndexFinished( bool ok )
|
||||
{
|
||||
emit initFinished( mFuture.result() );
|
||||
mIsIndexing = false;
|
||||
emit initFinished( ok );
|
||||
}
|
||||
|
||||
void QgsPointLocator::init( int maxFeaturesToIndex )
|
||||
@ -599,7 +599,7 @@ void QgsPointLocator::init( int maxFeaturesToIndex )
|
||||
const QgsWkbTypes::GeometryType geomType = mLayer->geometryType();
|
||||
if ( geomType == QgsWkbTypes::NullGeometry // nothing to index
|
||||
|| hasIndex()
|
||||
|| mFuture.isRunning() ) // already running, return!
|
||||
|| mIsIndexing ) // already indexing, return!
|
||||
return;
|
||||
|
||||
mRenderer.reset( mLayer->renderer() ? mLayer->renderer()->clone() : nullptr );
|
||||
@ -609,23 +609,26 @@ void QgsPointLocator::init( int maxFeaturesToIndex )
|
||||
mContext->expressionContext() << QgsExpressionContextUtils::layerScope( mLayer );
|
||||
}
|
||||
|
||||
emit initStarted();
|
||||
mIsIndexing = true;
|
||||
|
||||
if ( mAsynchronous )
|
||||
{
|
||||
mFuture = QtConcurrent::run( this, &QgsPointLocator::rebuildIndex, maxFeaturesToIndex );
|
||||
mFutureWatcher.setFuture( mFuture );
|
||||
QgsPointLocatorInitTask *task = new QgsPointLocatorInitTask( this );
|
||||
connect( task, &QgsPointLocatorInitTask::rebuildIndexFinished, this, &QgsPointLocator::onRebuildIndexFinished );
|
||||
connect( task, &QgsPointLocatorInitTask::taskTerminated, this, [ = ] { mIsIndexing = false; } );
|
||||
QgsApplication::taskManager()->addTask( task );
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool ok = rebuildIndex( maxFeaturesToIndex );
|
||||
mIsIndexing = false;
|
||||
emit initFinished( ok );
|
||||
}
|
||||
}
|
||||
|
||||
bool QgsPointLocator::hasIndex() const
|
||||
{
|
||||
return mFuture.isRunning() || mRTree || mIsEmptyLayer;
|
||||
return mIsIndexing || mRTree || mIsEmptyLayer;
|
||||
}
|
||||
|
||||
|
||||
@ -876,7 +879,7 @@ void QgsPointLocator::onAttributeValueChanged( QgsFeatureId fid, int idx, const
|
||||
|
||||
QgsPointLocator::Match QgsPointLocator::nearestVertex( const QgsPointXY &point, double tolerance, MatchFilter *filter )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
if ( mIsIndexing )
|
||||
return Match();
|
||||
|
||||
if ( !mRTree )
|
||||
@ -897,7 +900,7 @@ QgsPointLocator::Match QgsPointLocator::nearestVertex( const QgsPointXY &point,
|
||||
|
||||
QgsPointLocator::Match QgsPointLocator::nearestEdge( const QgsPointXY &point, double tolerance, MatchFilter *filter )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
if ( mIsIndexing )
|
||||
return Match();
|
||||
|
||||
if ( !mRTree )
|
||||
@ -922,7 +925,7 @@ QgsPointLocator::Match QgsPointLocator::nearestEdge( const QgsPointXY &point, do
|
||||
|
||||
QgsPointLocator::Match QgsPointLocator::nearestArea( const QgsPointXY &point, double tolerance, MatchFilter *filter )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
if ( mIsIndexing )
|
||||
return Match();
|
||||
|
||||
if ( !mRTree )
|
||||
@ -959,7 +962,7 @@ QgsPointLocator::Match QgsPointLocator::nearestArea( const QgsPointXY &point, do
|
||||
|
||||
QgsPointLocator::MatchList QgsPointLocator::edgesInRect( const QgsRectangle &rect, QgsPointLocator::MatchFilter *filter )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
if ( mIsIndexing )
|
||||
return MatchList();
|
||||
|
||||
if ( !mRTree )
|
||||
@ -988,7 +991,7 @@ QgsPointLocator::MatchList QgsPointLocator::edgesInRect( const QgsPointXY &point
|
||||
|
||||
QgsPointLocator::MatchList QgsPointLocator::verticesInRect( const QgsRectangle &rect, QgsPointLocator::MatchFilter *filter )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
if ( mIsIndexing )
|
||||
return MatchList();
|
||||
|
||||
if ( !mRTree )
|
||||
@ -1014,7 +1017,7 @@ QgsPointLocator::MatchList QgsPointLocator::verticesInRect( const QgsPointXY &po
|
||||
|
||||
QgsPointLocator::MatchList QgsPointLocator::pointInPolygon( const QgsPointXY &point )
|
||||
{
|
||||
if ( mFuture.isRunning() )
|
||||
if ( mIsIndexing )
|
||||
return MatchList();
|
||||
|
||||
if ( !mRTree )
|
||||
|
@ -68,10 +68,9 @@ class CORE_EXPORT QgsPointLocator : public QObject
|
||||
* to set the correct \a transformContext if a \a destinationCrs is specified. This is usually taken
|
||||
* from the current QgsProject::transformContext().
|
||||
*
|
||||
* \param asynchronous if FALSE, point locator init() method will block until index is completely
|
||||
* finished. if TRUE, index building will be done in another thread and init() method returns
|
||||
* immediatly. initStarted() and initFinished() signals can be used to control current state of
|
||||
* the point locator.
|
||||
* \param asynchronous if FALSE, point locator init() method will block until point locator index
|
||||
* is completely built. if TRUE, index building will be done in another thread and init() method returns
|
||||
* immediately. initFinished() signal will be emitted once the initialization is over.
|
||||
*
|
||||
* If \a extent is not NULLPTR, the locator will index only a subset of the layer which falls within that extent.
|
||||
*/
|
||||
@ -301,17 +300,12 @@ class CORE_EXPORT QgsPointLocator : public QObject
|
||||
*/
|
||||
void initFinished( bool ok );
|
||||
|
||||
/**
|
||||
* Emitted whenever index initialization has started
|
||||
*/
|
||||
void initStarted();
|
||||
|
||||
protected:
|
||||
bool rebuildIndex( int maxFeaturesToIndex = -1 );
|
||||
protected slots:
|
||||
void destroyIndex();
|
||||
private slots:
|
||||
void onRebuildIndexFinished();
|
||||
void onRebuildIndexFinished( bool ok );
|
||||
void onFeatureAdded( QgsFeatureId fid );
|
||||
void onFeatureDeleted( QgsFeatureId fid );
|
||||
void onGeometryChanged( QgsFeatureId fid, const QgsGeometry &geom );
|
||||
@ -335,16 +329,16 @@ class CORE_EXPORT QgsPointLocator : public QObject
|
||||
|
||||
std::unique_ptr<QgsRenderContext> mContext;
|
||||
std::unique_ptr<QgsFeatureRenderer> mRenderer;
|
||||
QFuture<bool> mFuture;
|
||||
QFutureWatcher<bool> mFutureWatcher;
|
||||
int mMaxFeaturesToIndex = -1;
|
||||
bool mAsynchronous = false;
|
||||
bool mIsIndexing = false;
|
||||
|
||||
friend class QgsPointLocator_VisitorNearestVertex;
|
||||
friend class QgsPointLocator_VisitorNearestEdge;
|
||||
friend class QgsPointLocator_VisitorArea;
|
||||
friend class QgsPointLocator_VisitorEdgesInRect;
|
||||
friend class QgsPointLocator_VisitorVerticesInRect;
|
||||
friend class QgsPointLocatorInitTask;
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,7 +45,6 @@ QgsPointLocator *QgsSnappingUtils::locatorForLayer( QgsVectorLayer *vl )
|
||||
{
|
||||
QgsPointLocator *vlpl = new QgsPointLocator( vl, destinationCrs(), mMapSettings.transformContext(), nullptr, mAsynchronous );
|
||||
connect( vlpl, &QgsPointLocator::initFinished, this, &QgsSnappingUtils::onInitFinished );
|
||||
connect( vlpl, &QgsPointLocator::initStarted, this, &QgsSnappingUtils::onInitStarted );
|
||||
mLocators.insert( vl, vlpl );
|
||||
}
|
||||
return mLocators.value( vl );
|
||||
@ -80,7 +79,6 @@ QgsPointLocator *QgsSnappingUtils::temporaryLocatorForLayer( QgsVectorLayer *vl,
|
||||
pointMap.x() + tolerance, pointMap.y() + tolerance );
|
||||
QgsPointLocator *vlpl = new QgsPointLocator( vl, destinationCrs(), mMapSettings.transformContext(), &rect, mAsynchronous );
|
||||
connect( vlpl, &QgsPointLocator::initFinished, this, &QgsSnappingUtils::onInitFinished );
|
||||
connect( vlpl, &QgsPointLocator::initStarted, this, &QgsSnappingUtils::onInitStarted );
|
||||
|
||||
mTemporaryLocators.insert( vl, vlpl );
|
||||
return mTemporaryLocators.value( vl );
|
||||
@ -355,13 +353,6 @@ void QgsSnappingUtils::onInitFinished( bool ok )
|
||||
{
|
||||
mHybridMaxAreaPerLayer[loc->layer()->id()] /= 4;
|
||||
}
|
||||
|
||||
prepareIndexFinished();
|
||||
}
|
||||
|
||||
void QgsSnappingUtils::onInitStarted()
|
||||
{
|
||||
prepareIndexStarting();
|
||||
}
|
||||
|
||||
void QgsSnappingUtils::prepareIndex( const QList<LayerAndAreaOfInterest> &layers )
|
||||
|
@ -196,10 +196,16 @@ class CORE_EXPORT QgsSnappingUtils : public QObject
|
||||
void configChanged( const QgsSnappingConfig &snappingConfig );
|
||||
|
||||
protected:
|
||||
//! Called when starting to index
|
||||
virtual void prepareIndexStarting() {}
|
||||
//! Called when finished indexing a layer
|
||||
virtual void prepareIndexFinished() {}
|
||||
|
||||
/**
|
||||
* This methods is now deprecated and never called
|
||||
*/
|
||||
Q_DECL_DEPRECATED virtual void prepareIndexStarting( int count ) { Q_UNUSED( count ); }
|
||||
|
||||
/**
|
||||
* This methods is now deprecated and never called
|
||||
*/
|
||||
Q_DECL_DEPRECATED virtual void prepareIndexProgress( int index ) { Q_UNUSED( index ); }
|
||||
|
||||
//! Deletes all existing locators (e.g. when destination CRS has changed and we need to reindex)
|
||||
void clearAllLocators();
|
||||
@ -209,9 +215,6 @@ class CORE_EXPORT QgsSnappingUtils : public QObject
|
||||
//! called whenever a point locator has finished
|
||||
void onInitFinished( bool ok );
|
||||
|
||||
//! called whenever a point locator has started
|
||||
void onInitStarted();
|
||||
|
||||
private:
|
||||
void onIndividualLayerSettingsChanged( const QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings> &layerSettings );
|
||||
//! Gets destination CRS from map settings, or an invalid CRS if projections are disabled
|
||||
@ -266,13 +269,11 @@ class CORE_EXPORT QgsSnappingUtils : public QObject
|
||||
//! Disable or not the snapping on all features. By default is always TRUE except for non visible features on map canvas.
|
||||
bool mEnableSnappingForInvisibleFeature = true;
|
||||
|
||||
//! Number of index currently being prepared
|
||||
int mPreparingIndexCount = 0;
|
||||
|
||||
//! true if we have to build point locator asynchronously
|
||||
bool mAsynchronous = false;
|
||||
|
||||
friend class TestQgsVertexTool;
|
||||
friend class TestQgsMapToolTrimExtendFeature;
|
||||
};
|
||||
|
||||
|
||||
|
@ -58,19 +58,3 @@ void QgsMapCanvasSnappingUtils::canvasMapToolChanged()
|
||||
{
|
||||
setEnableSnappingForInvisibleFeature( QgsSettings().value( QStringLiteral( "/qgis/digitizing/snap_invisible_feature" ), false ).toBool() );
|
||||
}
|
||||
|
||||
void QgsMapCanvasSnappingUtils::prepareIndexStarting()
|
||||
{
|
||||
if ( !mPreparingIndexCount )
|
||||
QApplication::setOverrideCursor( Qt::BusyCursor );
|
||||
|
||||
mPreparingIndexCount++;
|
||||
}
|
||||
|
||||
void QgsMapCanvasSnappingUtils::prepareIndexFinished()
|
||||
{
|
||||
mPreparingIndexCount--;
|
||||
|
||||
if ( !mPreparingIndexCount )
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
@ -36,10 +36,6 @@ class GUI_EXPORT QgsMapCanvasSnappingUtils : public QgsSnappingUtils
|
||||
public:
|
||||
QgsMapCanvasSnappingUtils( QgsMapCanvas *canvas, QObject *parent = nullptr );
|
||||
|
||||
protected:
|
||||
void prepareIndexStarting() override;
|
||||
void prepareIndexFinished() override;
|
||||
|
||||
private slots:
|
||||
void canvasMapSettingsChanged();
|
||||
void canvasTransformContextChanged();
|
||||
@ -49,7 +45,6 @@ class GUI_EXPORT QgsMapCanvasSnappingUtils : public QgsSnappingUtils
|
||||
private:
|
||||
QgsMapCanvas *mCanvas = nullptr;
|
||||
QProgressDialog *mProgress = nullptr;
|
||||
int mPreparingIndexCount = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -164,6 +164,7 @@ class TestQgsMapToolTrimExtendFeature : public QObject
|
||||
mapSettings.setLayers( QList<QgsMapLayer *>() << vlPolygon.get() << vlMultiLine.get() << vlLineZ.get() << vlTopoEdit.get() << vlTopoLimit.get() );
|
||||
|
||||
QgsSnappingUtils *mSnappingUtils = new QgsMapCanvasSnappingUtils( mCanvas, this );
|
||||
mSnappingUtils->mAsynchronous = false;
|
||||
QgsSnappingConfig snappingConfig = mSnappingUtils->config();
|
||||
mSnappingUtils->setMapSettings( mapSettings );
|
||||
snappingConfig.setEnabled( true );
|
||||
|
Loading…
x
Reference in New Issue
Block a user