Skip to content

Commit 66ebe34

Browse files
committedMay 21, 2020
[feature][selfsnap] add snapping to currently digitized feature for capture tool
1 parent d48c178 commit 66ebe34

15 files changed

+495
-5
lines changed
 

‎images/images.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@
700700
<file>themes/default/mIconSnappingMiddle.svg</file>
701701
<file>themes/default/mIconSnappingOnScale.svg</file>
702702
<file>themes/default/mIconSnappingVertex.svg</file>
703+
<file>themes/default/mIconSnappingSelf.svg</file>
703704
<file>themes/default/mIconSnappingSegment.svg</file>
704705
<file>themes/default/mIconTopologicalEditing.svg</file>
705706
<file>themes/default/mIconSnappingIntersection.svg</file>
Lines changed: 141 additions & 0 deletions
Loading

‎python/core/auto_generated/qgscadutils.sip.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ The QgsCadUtils class provides routines for CAD editing.
5353

5454
QgsPointXY finalMapPoint;
5555

56+
QgsPointLocator::Match snapMatch;
57+
5658
QgsPointLocator::Match edgeMatch;
5759

5860
double softLockCommonAngle;

‎python/core/auto_generated/qgssnappingconfig.sip.in

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,20 @@ Returns if the snapping on intersection is enabled
343343
void setIntersectionSnapping( bool enabled );
344344
%Docstring
345345
Sets if the snapping on intersection is enabled
346+
%End
347+
348+
bool selfSnapping() const;
349+
%Docstring
350+
Returns if self snapping (snapping to the currently digitised feature) is enabled
351+
352+
.. versionadded:: 3.14
353+
%End
354+
355+
void setSelfSnapping( bool enabled );
356+
%Docstring
357+
Sets if self snapping (snapping to the currently digitised feature) is enabled
358+
359+
.. versionadded:: 3.14
346360
%End
347361

348362
SIP_PYDICT individualLayerSettings() const;

‎python/core/auto_generated/qgssnappingutils.sip.in

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,42 @@ Set if invisible features must be snapped or not.
166166
.. versionadded:: 3.2
167167
%End
168168

169+
void addExtraSnapLayer( QgsVectorLayer *vl );
170+
%Docstring
171+
Supply an extra snapping layer (typically a memory layer).
172+
This is can be used by map tools to provide additionnal
173+
snappings points.
174+
175+
.. seealso:: :py:func:`removeExtraSnapLayer`
176+
177+
.. seealso:: :py:func:`getExtraSnapLayers`
178+
179+
.. versionadded:: 3.14
180+
%End
181+
182+
void removeExtraSnapLayer( QgsVectorLayer *vl );
183+
%Docstring
184+
Removes an extra snapping layer
185+
186+
.. seealso:: :py:func:`addExtraSnapLayer`
187+
188+
.. seealso:: :py:func:`getExtraSnapLayers`
189+
190+
.. versionadded:: 3.14
191+
%End
192+
193+
QSet<QgsVectorLayer *> getExtraSnapLayers();
194+
%Docstring
195+
Returns the list of extra snapping layers
196+
197+
.. seealso:: :py:func:`addExtraSnapLayer`
198+
199+
.. seealso:: :py:func:`removeExtraSnapLayer`
200+
201+
.. versionadded:: 3.14
202+
%End
203+
204+
169205
public slots:
170206

171207
void setConfig( const QgsSnappingConfig &snappingConfig );

‎src/app/qgssnappingwidget.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,14 @@ QgsSnappingWidget::QgsSnappingWidget( QgsProject *project, QgsMapCanvas *canvas,
287287
tracingMenu->addAction( widgetAction );
288288
mEnableTracingAction->setMenu( tracingMenu );
289289

290+
// self-snapping button
291+
mSelfSnappingAction = new QAction( tr( "Self-snapping" ), this );
292+
mSelfSnappingAction->setCheckable( true );
293+
mSelfSnappingAction->setIcon( QIcon( QgsApplication::getThemeIcon( "/mIconSnappingSelf.svg" ) ) );
294+
mSelfSnappingAction->setToolTip( tr( "Enable Self-snapping" ) );
295+
mSelfSnappingAction->setObjectName( QStringLiteral( "SelfSnappingAction" ) );
296+
connect( mSelfSnappingAction, &QAction::toggled, this, &QgsSnappingWidget::enableSelfSnapping );
297+
290298
// layout
291299
if ( mDisplayMode == ToolBar )
292300
{
@@ -316,6 +324,7 @@ QgsSnappingWidget::QgsSnappingWidget( QgsProject *project, QgsMapCanvas *canvas,
316324
mAvoidIntersectionsModeAction = tb->addWidget( mAvoidIntersectionsModeButton );
317325
tb->addAction( mIntersectionSnappingAction );
318326
tb->addAction( mEnableTracingAction );
327+
tb->addAction( mSelfSnappingAction );
319328
}
320329
else
321330
{
@@ -350,6 +359,12 @@ QgsSnappingWidget::QgsSnappingWidget( QgsProject *project, QgsMapCanvas *canvas,
350359
interButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
351360
layout->addWidget( interButton );
352361

362+
QToolButton *selfsnapButton = new QToolButton();
363+
selfsnapButton->addAction( mSelfSnappingAction );
364+
selfsnapButton->setDefaultAction( mSelfSnappingAction );
365+
selfsnapButton->setToolButtonStyle( Qt::ToolButtonTextBesideIcon );
366+
layout->addWidget( selfsnapButton );
367+
353368
layout->setContentsMargins( 0, 0, 0, 0 );
354369
layout->setAlignment( Qt::AlignRight );
355370
layout->setSpacing( mDisplayMode == Widget ? 3 : 0 );
@@ -488,6 +503,11 @@ void QgsSnappingWidget::projectSnapSettingsChanged()
488503
mIntersectionSnappingAction->setChecked( config.intersectionSnapping() );
489504
}
490505

506+
if ( config.selfSnapping() != mSelfSnappingAction->isChecked() )
507+
{
508+
mSelfSnappingAction->setChecked( config.selfSnapping() );
509+
}
510+
491511
toggleSnappingWidgets( config.enabled() );
492512

493513
}
@@ -552,6 +572,7 @@ void QgsSnappingWidget::toggleSnappingWidgets( bool enabled )
552572
mAdvancedConfigWidget->setEnabled( enabled );
553573
}
554574
mIntersectionSnappingAction->setEnabled( enabled );
575+
mSelfSnappingAction->setEnabled( enabled );
555576
mEnableTracingAction->setEnabled( enabled );
556577
}
557578

@@ -593,6 +614,12 @@ void QgsSnappingWidget::enableIntersectionSnapping( bool enabled )
593614
mProject->setSnappingConfig( mConfig );
594615
}
595616

617+
void QgsSnappingWidget::enableSelfSnapping( bool enabled )
618+
{
619+
mConfig.setSelfSnapping( enabled );
620+
mProject->setSnappingConfig( mConfig );
621+
}
622+
596623
void QgsSnappingWidget::onSnappingTreeLayersChanged()
597624
{
598625
mLayerTreeView->expandAll();

‎src/app/qgssnappingwidget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ class APP_EXPORT QgsSnappingWidget : public QWidget
114114

115115
void enableIntersectionSnapping( bool enabled );
116116

117+
void enableSelfSnapping( bool enabled );
118+
117119
void modeButtonTriggered( QAction *action );
118120
void avoidIntersectionsModeButtonTriggered( QAction *action );
119121
void typeButtonTriggered( QAction *action );
@@ -172,6 +174,7 @@ class APP_EXPORT QgsSnappingWidget : public QWidget
172174
QAction *mIntersectionSnappingAction = nullptr;
173175
QAction *mEnableTracingAction = nullptr;
174176
QgsDoubleSpinBox *mTracingOffsetSpinBox = nullptr;
177+
QAction *mSelfSnappingAction = nullptr;
175178
QTreeView *mLayerTreeView = nullptr;
176179
QWidget *mAdvancedConfigWidget = nullptr;
177180
QgsFloatingWidget *mAdvancedConfigContainer = nullptr;

‎src/core/qgssnappingconfig.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ bool QgsSnappingConfig::operator==( const QgsSnappingConfig &other ) const
179179
&& mTolerance == other.mTolerance
180180
&& mUnits == other.mUnits
181181
&& mIntersectionSnapping == other.mIntersectionSnapping
182+
&& mSelfSnapping == other.mSelfSnapping
182183
&& mIndividualLayerSettings == other.mIndividualLayerSettings
183184
&& mScaleDependencyMode == other.mScaleDependencyMode
184185
&& mMinimumScale == other.mMinimumScale
@@ -218,6 +219,7 @@ void QgsSnappingConfig::reset()
218219
mUnits = units;
219220
}
220221
mIntersectionSnapping = false;
222+
mSelfSnapping = false;
221223

222224
// set advanced config
223225
if ( mProject )
@@ -343,6 +345,16 @@ void QgsSnappingConfig::setIntersectionSnapping( bool enabled )
343345
mIntersectionSnapping = enabled;
344346
}
345347

348+
bool QgsSnappingConfig::selfSnapping() const
349+
{
350+
return mSelfSnapping;
351+
}
352+
353+
void QgsSnappingConfig::setSelfSnapping( bool enabled )
354+
{
355+
mSelfSnapping = enabled;
356+
}
357+
346358
QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings> QgsSnappingConfig::individualLayerSettings() const
347359
{
348360
return mIndividualLayerSettings;
@@ -459,6 +471,9 @@ void QgsSnappingConfig::readProject( const QDomDocument &doc )
459471
if ( snapSettingsElem.hasAttribute( QStringLiteral( "intersection-snapping" ) ) )
460472
mIntersectionSnapping = snapSettingsElem.attribute( QStringLiteral( "intersection-snapping" ) ) == QLatin1String( "1" );
461473

474+
if ( snapSettingsElem.hasAttribute( QStringLiteral( "self-snapping" ) ) )
475+
mSelfSnapping = snapSettingsElem.attribute( QStringLiteral( "self-snapping" ) ) == QLatin1String( "1" );
476+
462477
// do not clear the settings as they must be automatically synchronized with current layers
463478
QDomNodeList nodes = snapSettingsElem.elementsByTagName( QStringLiteral( "individual-layer-settings" ) );
464479
if ( nodes.count() )
@@ -504,6 +519,7 @@ void QgsSnappingConfig::writeProject( QDomDocument &doc )
504519
snapSettingsElem.setAttribute( QStringLiteral( "tolerance" ), mTolerance );
505520
snapSettingsElem.setAttribute( QStringLiteral( "unit" ), static_cast<int>( mUnits ) );
506521
snapSettingsElem.setAttribute( QStringLiteral( "intersection-snapping" ), QString::number( mIntersectionSnapping ) );
522+
snapSettingsElem.setAttribute( QStringLiteral( "self-snapping" ), QString::number( mSelfSnapping ) );
507523
snapSettingsElem.setAttribute( QStringLiteral( "scaleDependencyMode" ), QString::number( mScaleDependencyMode ) );
508524
snapSettingsElem.setAttribute( QStringLiteral( "minScale" ), mMinimumScale );
509525
snapSettingsElem.setAttribute( QStringLiteral( "maxScale" ), mMaximumScale );

‎src/core/qgssnappingconfig.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,20 @@ class CORE_EXPORT QgsSnappingConfig
335335
//! Sets if the snapping on intersection is enabled
336336
void setIntersectionSnapping( bool enabled );
337337

338+
/**
339+
* Returns if self snapping (snapping to the currently digitised feature) is enabled
340+
*
341+
* \since QGIS 3.14
342+
*/
343+
bool selfSnapping() const;
344+
345+
/**
346+
* Sets if self snapping (snapping to the currently digitised feature) is enabled
347+
*
348+
* \since QGIS 3.14
349+
*/
350+
void setSelfSnapping( bool enabled );
351+
338352
//! Returns individual snapping settings for all layers
339353
#ifndef SIP_RUN
340354
QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings> individualLayerSettings() const;
@@ -458,6 +472,7 @@ class CORE_EXPORT QgsSnappingConfig
458472
double mMaximumScale = 0.0;
459473
QgsTolerance::UnitType mUnits = QgsTolerance::ProjectUnits;
460474
bool mIntersectionSnapping = false;
475+
bool mSelfSnapping = false;
461476

462477
QHash<QgsVectorLayer *, IndividualLayerSettings> mIndividualLayerSettings;
463478

0 commit comments

Comments
 (0)
Please sign in to comment.