Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backport release-3_40] Fix freeze on long indexation for snapping on intersections #59498

Merged
merged 1 commit into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 7 additions & 16 deletions src/core/qgssnappingutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,21 +291,15 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap,
QgsPointLocator::Match bestMatch;
QgsPointLocator::MatchList edges; // for snap on intersection
_updateBestMatch( bestMatch, pointMap, loc, type, tolerance, filter, relaxed );

if ( mSnappingConfig.intersectionSnapping() )
{
QgsPointLocator *locEdges = locatorForLayerUsingStrategy( mCurrentLayer, pointMap, tolerance );
if ( !locEdges )
return QgsPointLocator::Match();
edges = locEdges->edgesInRect( pointMap, tolerance );
}
edges = loc->edgesInRect( pointMap, tolerance, filter, relaxed );

for ( QgsVectorLayer *vl : mExtraSnapLayers )
{
QgsPointLocator *loc = locatorForLayerUsingStrategy( vl, pointMap, tolerance );
_updateBestMatch( bestMatch, pointMap, loc, type, tolerance, filter, false );
if ( mSnappingConfig.intersectionSnapping() )
edges << loc->edgesInRect( pointMap, tolerance );
edges << loc->edgesInRect( pointMap, tolerance, filter, false );
}

if ( mSnappingConfig.intersectionSnapping() )
Expand Down Expand Up @@ -357,11 +351,9 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap,
if ( QgsPointLocator *loc = locatorForLayerUsingStrategy( layerConfig.layer, pointMap, tolerance ) )
{
_updateBestMatch( bestMatch, pointMap, loc, layerConfig.type, tolerance, filter, relaxed );

if ( mSnappingConfig.intersectionSnapping() )
{
edges << loc->edgesInRect( pointMap, tolerance );
}
edges << loc->edgesInRect( pointMap, tolerance, filter, relaxed );

// We keep the maximum tolerance for intersection snapping and extra snapping
maxTolerance = std::max( maxTolerance, tolerance );
// To avoid yet an additional setting, on extra snappings, we use the combination of all enabled snap types
Expand All @@ -374,7 +366,7 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap,
QgsPointLocator *loc = locatorForLayerUsingStrategy( vl, pointMap, maxTolerance );
_updateBestMatch( bestMatch, pointMap, loc, maxTypes, maxTolerance, filter, false );
if ( mSnappingConfig.intersectionSnapping() )
edges << loc->edgesInRect( pointMap, maxTolerance );
edges << loc->edgesInRect( pointMap, maxTolerance, filter, false );
}

if ( mSnappingConfig.intersectionSnapping() )
Expand Down Expand Up @@ -405,9 +397,8 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap,
if ( QgsPointLocator *loc = locatorForLayerUsingStrategy( vl, pointMap, tolerance ) )
{
_updateBestMatch( bestMatch, pointMap, loc, type, tolerance, filter, relaxed );

if ( mSnappingConfig.intersectionSnapping() )
edges << loc->edgesInRect( pointMap, tolerance );
edges << loc->edgesInRect( pointMap, tolerance, filter, relaxed );
}
}

Expand All @@ -416,7 +407,7 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPointXY &pointMap,
QgsPointLocator *loc = locatorForLayerUsingStrategy( vl, pointMap, tolerance );
_updateBestMatch( bestMatch, pointMap, loc, type, tolerance, filter, false );
if ( mSnappingConfig.intersectionSnapping() )
edges << loc->edgesInRect( pointMap, tolerance );
edges << loc->edgesInRect( pointMap, tolerance, filter, false );
}

if ( mSnappingConfig.intersectionSnapping() )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,15 @@ void TestQgsMapToolAddFeatureLine::testWithTopologicalEditingDifferentCanvasCrs(
snapConfig.project()->setTopologicalEditing( true );
mCanvas->snappingUtils()->setConfig( snapConfig );

// Wait for indexing to complete
if ( QgsPointLocator *loc = mCanvas->snappingUtils()->locatorForLayer( mLayerCRS3946Line ) )
{
if ( loc->isIndexing() )
{
loc->waitForIndexingFinished();
}
}

// add a line with one vertex near the previous line
utils.mouseClick( 10, 0, Qt::LeftButton );
utils.mouseClick( 4.9, 5.1, Qt::LeftButton );
Expand Down Expand Up @@ -1086,6 +1095,15 @@ void TestQgsMapToolAddFeatureLine::testWithTopologicalEditingWIthDiffLayerWithDi
snapConfig.project()->setTopologicalEditing( true );
mCanvas->snappingUtils()->setConfig( snapConfig );

// Wait for indexing to complete
if ( QgsPointLocator *loc = mCanvas->snappingUtils()->locatorForLayer( mLayerCRS3945Line ) )
{
if ( loc->isIndexing() )
{
loc->waitForIndexingFinished();
}
}

// test the topological editing
utils.mouseClick( 0, 5, Qt::LeftButton );
utils.mouseClick( 10.1, 5, Qt::LeftButton );
Expand Down
20 changes: 19 additions & 1 deletion tests/src/app/testqgsadvanceddigitizing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#include "qgstest.h"

#include "qgsadvanceddigitizingdockwidget.h"
#include "qgsguiutils.h"
#include "qgsapplication.h"
#include "qgsmapcanvas.h"
#include "qgsvectorlayer.h"
Expand Down Expand Up @@ -606,6 +605,16 @@ void TestQgsAdvancedDigitizing::coordinateConstraintWhenSnapping()
snapConfig.setEnabled( true );
mCanvas->snappingUtils()->setConfig( snapConfig );

// move to trigger a re-indexing and wait for it to complete
utils.mouseMove( 0, 0 );
if ( QgsPointLocator *loc = mCanvas->snappingUtils()->locatorForLayer( mLayer3950 ) )
{
if ( loc->isIndexing() )
{
loc->waitForIndexingFinished();
}
}

// simple snap test
utils.mouseClick( 0, 2, Qt::LeftButton );
utils.mouseClick( 2.02, 2, Qt::LeftButton );
Expand Down Expand Up @@ -806,6 +815,15 @@ void TestQgsAdvancedDigitizing::lineExtensionConstraintGeographicCrs()
snapConfig.setTypeFlag( Qgis::SnappingType::Vertex | Qgis::SnappingType::Segment );
mCanvas->snappingUtils()->setConfig( snapConfig );

// Wait for indexing to complete
if ( QgsPointLocator *loc = mCanvas->snappingUtils()->locatorForLayer( mLayer4326 ) )
{
if ( loc->isIndexing() )
{
loc->waitForIndexingFinished();
}
}

// test snapping on segment
utils.mouseMove( 4.9, 5.1 );
QCOMPARE( mAdvancedDigitizingDockWidget->currentPointV2(), QgsPoint( 5, 5 ) );
Expand Down
Loading