24 #include "qgsexpression.h" 40 , mMapCanvas( canvas )
41 , mCurrentMapToolSupportsCad( false )
42 , mCadEnabled( false )
43 , mConstructionMode( false )
44 , mCommonAngleConstraint(
QgsSettings().value( QStringLiteral(
"/Cad/CommonAngle" ), 90 ).toInt() )
45 , mSnappedToVertex( false )
46 , mSessionActive( false )
47 , mErrorMessage( nullptr )
53 mAngleConstraint.reset(
new CadConstraint( mAngleLineEdit, mLockAngleButton, mRelativeAngleButton, mRepeatingLockAngleButton ) );
54 mDistanceConstraint.reset(
new CadConstraint( mDistanceLineEdit, mLockDistanceButton,
nullptr, mRepeatingLockDistanceButton ) );
55 mXConstraint.reset(
new CadConstraint( mXLineEdit, mLockXButton, mRelativeXButton, mRepeatingLockXButton ) );
56 mYConstraint.reset(
new CadConstraint( mYLineEdit, mLockYButton, mRelativeYButton, mRepeatingLockYButton ) );
59 mMapCanvas->installEventFilter(
this );
60 mAngleLineEdit->installEventFilter(
this );
61 mDistanceLineEdit->installEventFilter(
this );
62 mXLineEdit->installEventFilter(
this );
63 mYLineEdit->installEventFilter(
this );
66 mEnableAction =
new QAction(
this );
67 mEnableAction->setText( tr(
"Enable advanced digitizing tools" ) );
69 mEnableAction->setCheckable(
true );
70 mEnabledButton->addAction( mEnableAction );
71 mEnabledButton->setDefaultAction( mEnableAction );
74 connect( mEnableAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::activateCad );
75 connect( mConstructionModeButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstructionMode );
76 connect( mParallelButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
77 connect( mPerpendicularButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
78 connect( mLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
79 connect( mLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
80 connect( mLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
81 connect( mLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
82 connect( mRelativeAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
83 connect( mRelativeXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
84 connect( mRelativeYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
85 connect( mRepeatingLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
86 connect( mRepeatingLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
87 connect( mRepeatingLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
88 connect( mRepeatingLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
89 connect( mAngleLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
90 connect( mDistanceLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
91 connect( mXLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
92 connect( mYLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
93 connect( mAngleLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
94 connect( mDistanceLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
95 connect( mXLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
96 connect( mYLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
108 QMenu *menu =
new QMenu(
this );
110 QActionGroup *angleButtonGroup =
new QActionGroup( menu );
111 mCommonAngleActions = QMap<QAction *, int>();
112 QList< QPair< int, QString > > commonAngles;
113 commonAngles << QPair<int, QString>( 0, tr(
"Do not snap to common angles" ) );
114 commonAngles << QPair<int, QString>( 30, tr(
"Snap to 30° angles" ) );
115 commonAngles << QPair<int, QString>( 45, tr(
"Snap to 45° angles" ) );
116 commonAngles << QPair<int, QString>( 90, tr(
"Snap to 90° angles" ) );
117 for ( QList< QPair< int, QString > >::const_iterator it = commonAngles.constBegin(); it != commonAngles.constEnd(); ++it )
119 QAction *action =
new QAction( it->second, menu );
120 action->setCheckable(
true );
121 action->setChecked( it->first == mCommonAngleConstraint );
122 menu->addAction( action );
123 angleButtonGroup->addAction( action );
124 mCommonAngleActions.insert( action, it->first );
127 mSettingsButton->setMenu( menu );
128 connect( mSettingsButton, SIGNAL( triggered( QAction * ) ),
this, SLOT( settingsButtonTriggered( QAction * ) ) );
131 mConstructionModeButton->setToolTip(
"<b>" + tr(
"Construction mode" ) +
"</b><br>(" + tr(
"press c to toggle on/off" ) +
")" );
132 mDistanceLineEdit->setToolTip(
"<b>" + tr(
"Distance" ) +
"</b><br>(" + tr(
"press d for quick access" ) +
")" );
133 mLockDistanceButton->setToolTip(
"<b>" + tr(
"Lock distance" ) +
"</b><br>(" + tr(
"press Ctrl + d for quick access" ) +
")" );
134 mRepeatingLockDistanceButton->setToolTip(
"<b>" + tr(
"Continuously lock distance" ) +
"</b>" );
136 mRelativeAngleButton->setToolTip(
"<b>" + tr(
"Toggles relative angle to previous segment" ) +
"</b><br>(" + tr(
"press Shift + a for quick access" ) +
")" );
137 mAngleLineEdit->setToolTip(
"<b>" + tr(
"Angle" ) +
"</b><br>(" + tr(
"press a for quick access" ) +
")" );
138 mLockAngleButton->setToolTip(
"<b>" + tr(
"Lock angle" ) +
"</b><br>(" + tr(
"press Ctrl + a for quick access" ) +
")" );
139 mRepeatingLockAngleButton->setToolTip(
"<b>" + tr(
"Continuously lock angle" ) +
"</b>" );
141 mRelativeXButton->setToolTip(
"<b>" + tr(
"Toggles relative x to previous node" ) +
"</b><br>(" + tr(
"press Shift + x for quick access" ) +
")" );
142 mXLineEdit->setToolTip(
"<b>" + tr(
"X coordinate" ) +
"</b><br>(" + tr(
"press x for quick access" ) +
")" );
143 mLockXButton->setToolTip(
"<b>" + tr(
"Lock x coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + x for quick access" ) +
")" );
144 mRepeatingLockXButton->setToolTip(
"<b>" + tr(
"Continuously lock x coordinate" ) +
"</b>" );
146 mRelativeYButton->setToolTip(
"<b>" + tr(
"Toggles relative y to previous node" ) +
"</b><br>(" + tr(
"press Shift + y for quick access" ) +
")" );
147 mYLineEdit->setToolTip(
"<b>" + tr(
"Y coordinate" ) +
"</b><br>(" + tr(
"press y for quick access" ) +
")" );
148 mLockYButton->setToolTip(
"<b>" + tr(
"Lock y coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + y for quick access" ) +
")" );
149 mRepeatingLockYButton->setToolTip(
"<b>" + tr(
"Continuously lock y coordinate" ) +
"</b>" );
152 updateCapacity(
true );
162 setCadEnabled(
false );
165 void QgsAdvancedDigitizingDockWidget::setCadEnabled(
bool enabled )
167 mCadEnabled = enabled;
168 mEnableAction->setChecked( enabled );
169 mCadButtons->setEnabled( enabled );
170 mInputWidgets->setEnabled( enabled );
173 setConstructionMode(
false );
176 void QgsAdvancedDigitizingDockWidget::activateCad(
bool enabled )
178 enabled &= mCurrentMapToolSupportsCad;
180 mSessionActive = enabled;
182 if ( enabled && !isVisible() )
187 setCadEnabled( enabled );
190 void QgsAdvancedDigitizingDockWidget::additionalConstraintClicked(
bool activated )
196 if ( sender() == mParallelButton )
198 lockAdditionalConstraint(
Parallel );
200 else if ( sender() == mPerpendicularButton )
206 void QgsAdvancedDigitizingDockWidget::setConstraintRelative(
bool activate )
208 if ( sender() == mRelativeAngleButton )
210 mAngleConstraint->setRelative( activate );
212 else if ( sender() == mRelativeXButton )
214 mXConstraint->setRelative( activate );
216 else if ( sender() == mRelativeYButton )
218 mYConstraint->setRelative( activate );
222 void QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock(
bool activate )
224 if ( sender() == mRepeatingLockDistanceButton )
226 mDistanceConstraint->setRepeatingLock( activate );
228 else if ( sender() == mRepeatingLockAngleButton )
230 mAngleConstraint->setRepeatingLock( activate );
232 else if ( sender() == mRepeatingLockXButton )
234 mXConstraint->setRepeatingLock( activate );
236 else if ( sender() == mRepeatingLockYButton )
238 mYConstraint->setRepeatingLock( activate );
242 void QgsAdvancedDigitizingDockWidget::setConstructionMode(
bool enabled )
244 mConstructionMode = enabled;
245 mConstructionModeButton->setChecked( enabled );
248 void QgsAdvancedDigitizingDockWidget::settingsButtonTriggered( QAction *action )
251 QMap<QAction *, int>::const_iterator ica = mCommonAngleActions.constFind( action );
252 if ( ica != mCommonAngleActions.constEnd() )
254 ica.key()->setChecked(
true );
255 mCommonAngleConstraint = ica.value();
267 if ( releaseRepeatingLocks || !mAngleConstraint->isRepeatingLock() )
269 if ( releaseRepeatingLocks || !mDistanceConstraint->isRepeatingLock() )
271 if ( releaseRepeatingLocks || !mXConstraint->isRepeatingLock() )
273 if ( releaseRepeatingLocks || !mYConstraint->isRepeatingLock() )
278 void QgsAdvancedDigitizingDockWidget::emit
pointChanged()
281 QPoint globalPos = mMapCanvas->cursor().pos();
282 QPoint pos = mMapCanvas->mapFromGlobal( globalPos );
283 QMouseEvent *e =
new QMouseEvent( QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier );
284 mCurrentMapTool->canvasMoveEvent( e );
291 if ( obj == mAngleLineEdit || obj == mLockAngleButton )
293 constraint = mAngleConstraint.get();
295 else if ( obj == mDistanceLineEdit || obj == mLockDistanceButton )
297 constraint = mDistanceConstraint.get();
299 else if ( obj == mXLineEdit || obj == mLockXButton )
301 constraint = mXConstraint.get();
303 else if ( obj == mYLineEdit || obj == mLockYButton )
305 constraint = mYConstraint.get();
310 double QgsAdvancedDigitizingDockWidget::parseUserInput(
const QString &inputValue,
bool &ok )
const 313 double value = inputValue.toDouble( &ok );
321 QgsExpression expr( inputValue );
322 QVariant result = expr.evaluate();
323 if ( expr.hasEvalError() )
326 value = result.toDouble( &ok );
331 void QgsAdvancedDigitizingDockWidget::updateConstraintValue(
CadConstraint *constraint,
const QString &textValue,
bool convertExpression )
333 if ( !constraint || textValue.isEmpty() )
342 double value = parseUserInput( textValue, ok );
346 constraint->
setValue( value, convertExpression );
351 void QgsAdvancedDigitizingDockWidget::lockConstraint(
bool activate )
361 QString textValue = constraint->
lineEdit()->text();
362 if ( !textValue.isEmpty() )
365 double value = parseUserInput( textValue, ok );
385 if ( constraint == mAngleConstraint.get() )
395 void QgsAdvancedDigitizingDockWidget::constraintTextEdited(
const QString &textValue )
403 updateConstraintValue( constraint, textValue,
false );
406 void QgsAdvancedDigitizingDockWidget::constraintFocusOut()
408 QLineEdit *lineEdit = qobject_cast< QLineEdit * >( sender()->parent() );
418 updateConstraintValue( constraint, lineEdit->text(), true );
421 void QgsAdvancedDigitizingDockWidget::lockAdditionalConstraint(
AdditionalConstraint constraint )
423 mAdditionalConstraint = constraint;
424 mPerpendicularButton->setChecked( constraint ==
Perpendicular );
425 mParallelButton->setChecked( constraint ==
Parallel );
428 void QgsAdvancedDigitizingDockWidget::updateCapacity(
bool updateUIwithoutChange )
430 CadCapacities newCapacities =
nullptr;
432 if ( mCadPointList.count() > 1 )
436 if ( mCadPointList.count() > 2 )
440 if ( !updateUIwithoutChange && newCapacities == mCapacities )
450 bool relativeAngle = mCadEnabled && newCapacities.testFlag(
RelativeAngle );
451 bool absoluteAngle = mCadEnabled && newCapacities.testFlag(
AbsoluteAngle );
454 mPerpendicularButton->setEnabled( absoluteAngle && snappingEnabled );
455 mParallelButton->setEnabled( absoluteAngle && snappingEnabled );
458 if ( !snappingEnabled )
460 mPerpendicularButton->setToolTip( tr(
"Snapping must be enabled to utilize perpendicular mode" ) );
461 mParallelButton->setToolTip( tr(
"Snapping must be enabled to utilize parallel mode" ) );
465 mPerpendicularButton->setToolTip(
"<b>" + tr(
"Perpendicular" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
466 mParallelButton->setToolTip(
"<b>" + tr(
"Parallel" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
470 if ( !absoluteAngle )
476 mLockAngleButton->setEnabled( absoluteAngle );
477 mRelativeAngleButton->setEnabled( relativeAngle );
478 mAngleLineEdit->setEnabled( absoluteAngle );
479 if ( !absoluteAngle )
483 if ( !relativeAngle )
485 mAngleConstraint->setRelative(
false );
487 else if ( relativeAngle && !mCapacities.testFlag(
RelativeAngle ) )
490 mAngleConstraint->setRelative(
true );
494 mLockDistanceButton->setEnabled( relativeCoordinates );
495 mDistanceLineEdit->setEnabled( relativeCoordinates );
496 if ( !relativeCoordinates )
501 mRelativeXButton->setEnabled( relativeCoordinates );
502 mRelativeYButton->setEnabled( relativeCoordinates );
505 mCapacities = newCapacities;
523 context.
xConstraint = _constraint( mXConstraint.get() );
524 context.
yConstraint = _constraint( mYConstraint.get() );
535 bool res = output.
valid;
537 mSnappedSegment.clear();
542 mSnappedSegment << edgePt0 << edgePt1;
561 updateCurrentPoint( point );
563 updateUnlockedConstraintValues( point );
571 emit
pushWarning( tr(
"Some constraints are incompatible. Resulting point might be incorrect." ) );
578 void QgsAdvancedDigitizingDockWidget::updateUnlockedConstraintValues(
const QgsPointXY &point )
580 bool previousPointExist, penulPointExist;
585 if ( !mAngleConstraint->isLocked() && previousPointExist )
588 if ( penulPointExist && mAngleConstraint->relative() )
591 angle = std::atan2( previousPt.
y() - penultimatePt.
y(),
592 previousPt.
x() - penultimatePt.
x() );
594 angle = ( std::atan2( point.
y() - previousPt.
y(),
595 point.
x() - previousPt.
x()
596 ) - angle ) * 180 / M_PI;
598 angle = std::fmod( angle, 360.0 );
599 mAngleConstraint->setValue( angle );
602 if ( !mDistanceConstraint->isLocked() && previousPointExist )
604 mDistanceConstraint->setValue( std::sqrt( previousPt.
sqrDist( point ) ) );
607 if ( !mXConstraint->isLocked() )
609 if ( previousPointExist && mXConstraint->relative() )
611 mXConstraint->setValue( point.
x() - previousPt.
x() );
615 mXConstraint->setValue( point.
x() );
619 if ( !mYConstraint->isLocked() )
621 if ( previousPointExist && mYConstraint->relative() )
623 mYConstraint->setValue( point.
y() - previousPt.
y() );
627 mYConstraint->setValue( point.
y() );
633 QList<QgsPointXY> QgsAdvancedDigitizingDockWidget::snapSegmentToAllLayers(
const QgsPointXY &originalMapPoint,
bool *snapped )
const 635 QList<QgsPointXY> segment;
648 match = snappingUtils->
snapToMap( originalMapPoint );
650 snappingUtils->
setConfig( canvasConfig );
655 segment << pt1 << pt2;
660 *snapped = segment.count() == 2;
673 bool previousPointExist, penulPointExist, snappedSegmentExist;
676 mSnappedSegment = snapSegmentToAllLayers( e->
originalMapPoint(), &snappedSegmentExist );
678 if ( !previousPointExist || !snappedSegmentExist )
683 double angle = std::atan2( mSnappedSegment[0].y() - mSnappedSegment[1].y(), mSnappedSegment[0].x() - mSnappedSegment[1].x() );
685 if ( mAngleConstraint->relative() && penulPointExist )
687 angle -= std::atan2( previousPt.
y() - penultimatePt.
y(), previousPt.
x() - penultimatePt.
x() );
697 mAngleConstraint->setValue( angle );
698 mAngleConstraint->setLockMode( lockMode );
716 case Qt::Key_Backspace:
719 removePreviousPoint();
753 case Qt::Key_Backspace:
756 removePreviousPoint();
782 bool QgsAdvancedDigitizingDockWidget::eventFilter( QObject *obj, QEvent *event )
786 if ( event->type() != QEvent::KeyPress )
790 QKeyEvent *keyEvent =
dynamic_cast<QKeyEvent *
>( event );
795 return filterKeyPress( keyEvent );
798 bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e )
804 if ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier )
806 mXConstraint->toggleLocked();
809 else if ( e->modifiers() == Qt::ShiftModifier )
813 mXConstraint->toggleRelative();
819 mXLineEdit->setFocus();
820 mXLineEdit->selectAll();
826 if ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier )
828 mYConstraint->toggleLocked();
831 else if ( e->modifiers() == Qt::ShiftModifier )
835 mYConstraint->toggleRelative();
841 mYLineEdit->setFocus();
842 mYLineEdit->selectAll();
848 if ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier )
852 mAngleConstraint->toggleLocked();
856 else if ( e->modifiers() == Qt::ShiftModifier )
860 mAngleConstraint->toggleRelative();
866 mAngleLineEdit->setFocus();
867 mAngleLineEdit->selectAll();
873 if ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier )
877 mDistanceConstraint->toggleLocked();
883 mDistanceLineEdit->setFocus();
884 mDistanceLineEdit->selectAll();
890 setConstructionMode( !mConstructionMode );
895 bool parallel = mParallelButton->isChecked();
896 bool perpendicular = mPerpendicularButton->isChecked();
898 if ( !parallel && !perpendicular )
902 else if ( perpendicular )
904 lockAdditionalConstraint(
Parallel );
925 mErrorLabel->setText( tr(
"CAD tools can not be used on geographic coordinates. Change the coordinates system in the project properties." ) );
927 mEnableAction->setEnabled(
false );
928 setCadEnabled(
false );
932 mEnableAction->setEnabled(
true );
935 setMaximumHeight( 220 );
937 mCurrentMapToolSupportsCad =
true;
939 if ( mSessionActive && !isVisible() )
943 setCadEnabled( mSessionActive );
951 mEnableAction->setEnabled(
false );
952 mErrorLabel->setText( tr(
"CAD tools are not enabled for the current map tool" ) );
955 setMaximumHeight( 80 );
957 mCurrentMapToolSupportsCad =
false;
959 setCadEnabled(
false );
964 mCadPaintItem->update();
971 mCadPointList << point;
975 mCadPointList.insert( 0, point );
981 void QgsAdvancedDigitizingDockWidget::removePreviousPoint()
987 mCadPointList.removeAt( i );
993 mCadPointList.clear();
994 mSnappedSegment.clear();
995 mSnappedToVertex =
false;
1000 void QgsAdvancedDigitizingDockWidget::updateCurrentPoint(
const QgsPointXY &point )
1004 mCadPointList << point;
1009 mCadPointList[0] = point;
1017 mLockerButton->setChecked( mode == HardLock );
1018 if ( mRepeatingLockButton )
1020 if ( mode == HardLock )
1022 mRepeatingLockButton->setEnabled(
true );
1026 mRepeatingLockButton->setChecked(
false );
1027 mRepeatingLockButton->setEnabled(
false );
1031 if ( mode == NoLock )
1039 mRepeatingLock = repeating;
1040 if ( mRepeatingLockButton )
1041 mRepeatingLockButton->setChecked( repeating );
1046 mRelative = relative;
1047 if ( mRelativeButton )
1049 mRelativeButton->setChecked( relative );
1057 mLineEdit->setText( QString::number( value,
'f' ) );
1062 setLockMode( mLockMode == HardLock ? NoLock : HardLock );
1067 setRelative( !mRelative );
1075 return mCadPointList.value( 0 );
1085 return mCadPointList.value( 1 );
1095 return mCadPointList.value( 2 );
QgsCadUtils::AlignMapPointConstraint yConstraint
Constraint for Y coordinate.
void snappingConfigChanged(const QgsSnappingConfig &config)
emitted whenever the configuration for snapping has changed
void focusOut()
Emitted when parent object loses focus.
A event filter for watching for focus events on a parent object.
This class is a composition of two QSettings instances:
bool enabled() const
return if snapping is enabled
Structure with details of one constraint.
A class to represent a 2D point.
int softLockCommonAngle
Angle (in degrees) to which we have soft-locked ourselves (if not set it is -1)
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
void setMapPoint(const QgsPointXY &point)
Set the (snapped) point this event points to in map coordinates.
Map canvas is a class for displaying all GIS data types on a canvas.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
QgsPointLocator::Match edgeMatch
Snapped segment - only valid if actually used for something.
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
bool locked
Whether the constraint is active, i.e. should be considered.
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
QgsCadUtils::AlignMapPointConstraint distanceConstraint
Constraint for distance.
Structure defining all constraints for alignMapPoint() method.
void edgePoints(QgsPointXY &pt1, QgsPointXY &pt2) const
Only for a valid edge match - obtain endpoints of the edge.
QgsCadUtils::AlignMapPointConstraint commonAngleConstraint
Constraint for soft lock to a common angle.
void destinationCrsChanged()
Emitted when map CRS has changed.
bool isGeographic() const
Returns whether the CRS is a geographic CRS (using lat/lon coordinates)
QgsPointXY finalMapPoint
map point aligned according to the constraints
double value
Numeric value of the constraint (coordinate/distance in map units or angle in degrees) ...
Structure returned from alignMapPoint() method.
double mapUnitsPerPixel
Map units/pixel ratio from map canvas. Needed for.
void setMode(SnappingMode mode)
define the mode of snapping
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
QgsPointXY originalMapPoint() const
Returns the original, unmodified map point of the mouse cursor.
QgsCadUtils::AlignMapPointConstraint xConstraint
Constraint for X coordinate.
QgsCadUtils::AlignMapPointConstraint angleConstraint
Constraint for angle.
bool valid
Whether the combination of constraints is actually valid.
static QgsProject * instance()
Returns the QgsProject singleton instance.
void setType(SnappingType type)
define the type of snapping
This class has all the configuration of snapping and can return answers to snapping queries...
QgsSnappingUtils * snappingUtils
Snapping utils that will be used to snap point to map. Must not be null.
This is a container for configuration of the snapping of the project.
static QgsCadUtils::AlignMapPointOutput alignMapPoint(const QgsPointXY &originalMapPoint, const QgsCadUtils::AlignMapPointContext &ctx)
Applies X/Y/angle/distance constraints from the given context to a map point.
QgsPointLocator::Match snapToMap(QPoint point, QgsPointLocator::MatchFilter *filter=nullptr)
Snap to map according to the current configuration. Optional filter allows discarding unwanted matche...
QgsSnappingUtils * snappingUtils() const
Return snapping utility class that is associated with map canvas.
bool relative
Whether the value is relative to previous value.
QgsSnappingConfig snappingConfig
void setConfig(const QgsSnappingConfig &snappingConfig)
The snapping configuration controls the behavior of this object.
The QgsAdvancedDigitizingCanvasItem class draws the graphical elements of the CAD tools (...
QList< QgsPointXY > cadPointList
List of recent CAD points in map coordinates.