@@ -25,6 +25,7 @@ QgsSnappingUtils::QgsSnappingUtils( QObject* parent )
25
25
: QObject( parent )
26
26
, mCurrentLayer( 0 )
27
27
, mSnapToMapMode( SnapCurrentLayer )
28
+ , mStrategy( IndexHybrid )
28
29
, mDefaultType( QgsPointLocator::Vertex )
29
30
, mDefaultTolerance( 10 )
30
31
, mDefaultUnit( QgsTolerance::Pixels )
@@ -57,6 +58,38 @@ void QgsSnappingUtils::clearAllLocators()
57
58
foreach ( QgsPointLocator* vlpl, mLocators )
58
59
delete vlpl;
59
60
mLocators .clear ();
61
+
62
+ foreach ( QgsPointLocator* vlpl, mTemporaryLocators )
63
+ delete vlpl;
64
+ mTemporaryLocators .clear ();
65
+ }
66
+
67
+
68
+ QgsPointLocator* QgsSnappingUtils::locatorForLayerUsingStrategy ( QgsVectorLayer* vl, const QgsPoint& pointMap, double tolerance )
69
+ {
70
+ if ( mStrategy == IndexAlwaysFull )
71
+ return locatorForLayer ( vl );
72
+ else if ( mStrategy == IndexNeverFull )
73
+ return temporaryLocatorForLayer ( vl, pointMap, tolerance );
74
+ else // Hybrid
75
+ {
76
+ if ( vl->pendingFeatureCount () > 100000 )
77
+ return temporaryLocatorForLayer ( vl, pointMap, tolerance );
78
+ else
79
+ return locatorForLayer ( vl );
80
+ }
81
+ }
82
+
83
+ QgsPointLocator* QgsSnappingUtils::temporaryLocatorForLayer ( QgsVectorLayer* vl, const QgsPoint& pointMap, double tolerance )
84
+ {
85
+ if ( mTemporaryLocators .contains ( vl ) )
86
+ delete mTemporaryLocators .take ( vl );
87
+
88
+ QgsRectangle rect ( pointMap.x () - tolerance, pointMap.y () - tolerance,
89
+ pointMap.x () + tolerance, pointMap.y () + tolerance );
90
+ QgsPointLocator* vlpl = new QgsPointLocator ( vl, destCRS (), &rect );
91
+ mTemporaryLocators .insert ( vl, vlpl );
92
+ return mTemporaryLocators .value ( vl );
60
93
}
61
94
62
95
@@ -174,17 +207,18 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPoint& pointMap, Qg
174
207
int type = mDefaultType ;
175
208
176
209
// use ad-hoc locator
177
- QgsPointLocator* loc = locatorForLayer ( mCurrentLayer );
178
- loc->init ( QgsPointLocator::Vertex | QgsPointLocator::Edge );
210
+ QgsPointLocator* loc = locatorForLayerUsingStrategy ( mCurrentLayer , pointMap, tolerance );
179
211
if ( !loc )
180
212
return QgsPointLocator::Match ();
213
+ loc->init ( QgsPointLocator::Vertex | QgsPointLocator::Edge );
181
214
182
215
QgsPointLocator::Match bestMatch;
183
216
_updateBestMatch ( bestMatch, pointMap, loc, type, tolerance, filter );
184
217
185
218
if ( mSnapOnIntersection )
186
219
{
187
- QgsPointLocator::MatchList edges = locatorForLayer ( mCurrentLayer )->edgesInTolerance ( pointMap, tolerance );
220
+ QgsPointLocator* locEdges = locatorForLayerUsingStrategy ( mCurrentLayer , pointMap, tolerance );
221
+ QgsPointLocator::MatchList edges = locEdges->edgesInTolerance ( pointMap, tolerance );
188
222
bestMatch.replaceIfBetter ( _findClosestSegmentIntersection ( pointMap, edges ), tolerance );
189
223
}
190
224
@@ -199,7 +233,7 @@ QgsPointLocator::Match QgsSnappingUtils::snapToMap( const QgsPoint& pointMap, Qg
199
233
foreach ( const LayerConfig& layerConfig, mLayers )
200
234
{
201
235
double tolerance = QgsTolerance::toleranceInMapUnits ( layerConfig.tolerance , mMapSettings , layerConfig.unit );
202
- if ( QgsPointLocator* loc = locatorForLayer ( layerConfig.layer ) )
236
+ if ( QgsPointLocator* loc = locatorForLayerUsingStrategy ( layerConfig.layer , pointMap, tolerance ) )
203
237
{
204
238
loc->init ( layerConfig.type );
205
239
@@ -228,14 +262,14 @@ QgsPointLocator::Match QgsSnappingUtils::snapToCurrentLayer( const QPoint& point
228
262
if ( !mCurrentLayer )
229
263
return QgsPointLocator::Match ();
230
264
231
- QgsPointLocator* loc = locatorForLayer ( mCurrentLayer );
232
- loc->init ( type );
233
- if ( !loc )
234
- return QgsPointLocator::Match ();
235
-
236
265
QgsPoint pointMap = mMapSettings .mapToPixel ().toMapCoordinates ( point );
237
266
double tolerance = QgsTolerance::vertexSearchRadius ( mMapSettings );
238
267
268
+ QgsPointLocator* loc = locatorForLayerUsingStrategy ( mCurrentLayer , pointMap, tolerance );
269
+ if ( !loc )
270
+ return QgsPointLocator::Match ();
271
+ loc->init ( type );
272
+
239
273
QgsPointLocator::Match bestMatch;
240
274
_updateBestMatch ( bestMatch, pointMap, loc, type, tolerance, filter );
241
275
return bestMatch;
@@ -356,6 +390,15 @@ void QgsSnappingUtils::onLayersWillBeRemoved( QStringList layerIds )
356
390
continue ;
357
391
}
358
392
}
393
+
394
+ for ( LocatorsMap::const_iterator it = mTemporaryLocators .constBegin (); it != mTemporaryLocators .constEnd (); ++it )
395
+ {
396
+ if ( it.key ()->id () == layerId )
397
+ {
398
+ delete mTemporaryLocators .take ( it.key () );
399
+ continue ;
400
+ }
401
+ }
359
402
}
360
403
}
361
404
0 commit comments