27 , mSnapToMapMode( SnapCurrentLayer )
28 , mStrategy( IndexHybrid )
30 , mDefaultTolerance( 10 )
32 , mSnapOnIntersection( false )
48 if ( !mLocators.contains( vl ) )
51 mLocators.insert( vl, vlpl );
53 return mLocators.value( vl );
56 void QgsSnappingUtils::clearAllLocators()
64 mTemporaryLocators.clear();
70 if ( willUseIndex( vl ) )
73 return temporaryLocatorForLayer( vl, pointMap, tolerance );
78 if ( mTemporaryLocators.contains( vl ) )
79 delete mTemporaryLocators.take( vl );
81 QgsRectangle rect( pointMap.
x() - tolerance, pointMap.
y() - tolerance,
82 pointMap.
x() + tolerance, pointMap.
y() + tolerance );
84 mTemporaryLocators.insert( vl, vlpl );
85 return mTemporaryLocators.value( vl );
96 if ( mHybridNonindexableLayers.contains( vl->
id() ) )
107 if ( segments.isEmpty() )
110 QSet<QgsPoint> endpoints;
113 QList<QgsGeometry*> geoms;
121 endpoints << pl[0] << pl[1];
129 QList<QgsPoint> newPoints;
134 if ( !endpoints.contains( p ) )
144 if ( !endpoints.contains( p ) )
151 if ( newPoints.isEmpty() )
156 double minSqrDist = 1e20;
157 foreach (
const QgsPoint& p, newPoints )
159 double sqrDist = pt.
sqrDist( p.
x(), p.
y() );
160 if ( sqrDist < minSqrDist )
162 minSqrDist = sqrDist;
214 if ( !mCurrentLayer )
217 prepareIndex( QList<QgsVectorLayer*>() << mCurrentLayer );
221 int type = mDefaultType;
224 QgsPointLocator* loc = locatorForLayerUsingStrategy( mCurrentLayer, pointMap, tolerance );
231 if ( mSnapOnIntersection )
233 QgsPointLocator* locEdges = locatorForLayerUsingStrategy( mCurrentLayer, pointMap, tolerance );
242 QList<QgsVectorLayer*>
layers;
243 foreach (
const LayerConfig& layerConfig, mLayers )
244 layers << layerConfig.
layer;
245 prepareIndex( layers );
249 double maxSnapIntTolerance = 0;
251 foreach (
const LayerConfig& layerConfig, mLayers )
254 if (
QgsPointLocator* loc = locatorForLayerUsingStrategy( layerConfig.
layer, pointMap, tolerance ) )
258 if ( mSnapOnIntersection )
260 edges << loc->edgesInRect( pointMap, tolerance );
261 maxSnapIntTolerance = qMax( maxSnapIntTolerance, tolerance );
266 if ( mSnapOnIntersection )
275 int type = mDefaultType;
277 QList<QgsVectorLayer*>
layers;
278 foreach (
const QString& layerID, mMapSettings.
layers() )
281 prepareIndex( layers );
288 if (
QgsPointLocator* loc = locatorForLayerUsingStrategy( vl, pointMap, tolerance ) )
292 if ( mSnapOnIntersection )
293 edges << loc->edgesInRect( pointMap, tolerance );
297 if ( mSnapOnIntersection )
307 void QgsSnappingUtils::prepareIndex(
const QList<QgsVectorLayer*>& layers )
310 QList<QgsVectorLayer*> layersToIndex;
316 if ( layersToIndex.isEmpty() )
325 QTime tt; tt.start();
327 mHybridNonindexableLayers.insert( vl->
id() );
328 QgsDebugMsg( QString(
"Index init: %1 ms (%2)" ).arg( tt.elapsed() ).arg( vl->
id() ) );
331 QgsDebugMsg( QString(
"Prepare index total: %1 ms" ).arg( t.elapsed() ) );
337 if ( !mCurrentLayer )
343 QgsPointLocator* loc = locatorForLayerUsingStrategy( mCurrentLayer, pointMap, tolerance );
356 mMapSettings = settings;
358 if ( newDestCRS != oldDestCRS )
369 mDefaultTolerance = tolerance;
376 tolerance = mDefaultTolerance;
395 if ( snapType ==
"to segment" )
397 else if ( snapType ==
"to vertex and segment" )
399 else if ( snapType ==
"to vertex" )
409 bool snappingDefinedInProject, ok;
417 if ( layerIdList.size() != enabledList.size() ||
418 layerIdList.size() != toleranceList.size() ||
419 layerIdList.size() != toleranceUnitList.size() ||
420 layerIdList.size() != snapToList.size() )
423 if ( !snappingDefinedInProject )
427 if ( snapMode ==
"current_layer" )
429 else if ( snapMode ==
"all_layers" )
437 QStringList::const_iterator layerIt( layerIdList.constBegin() );
438 QStringList::const_iterator tolIt( toleranceList.constBegin() );
439 QStringList::const_iterator tolUnitIt( toleranceUnitList.constBegin() );
440 QStringList::const_iterator snapIt( snapToList.constBegin() );
441 QStringList::const_iterator enabledIt( enabledList.constBegin() );
442 for ( ; layerIt != layerIdList.constEnd(); ++layerIt, ++tolIt, ++tolUnitIt, ++snapIt, ++enabledIt )
445 if ( *enabledIt !=
"enabled" )
460 void QgsSnappingUtils::onLayersWillBeRemoved( QStringList layerIds )
463 foreach ( QString layerId, layerIds )
465 for ( LocatorsMap::iterator it = mLocators.begin(); it != mLocators.end(); )
467 if ( it.key()->id() == layerId )
470 it = mLocators.erase( it );
478 for ( LocatorsMap::iterator it = mTemporaryLocators.begin(); it != mTemporaryLocators.end(); )
480 if ( it.key()->id() == layerId )
483 it = mTemporaryLocators.erase( it );