40 , mMapCanvas( canvas )
41 , mCommonAngleConstraint(
QgsSettings().value( QStringLiteral(
"/Cad/CommonAngle" ), 90 ).toDouble() )
47 mAngleConstraint.reset(
new CadConstraint( mAngleLineEdit, mLockAngleButton, mRelativeAngleButton, mRepeatingLockAngleButton ) );
48 mDistanceConstraint.reset(
new CadConstraint( mDistanceLineEdit, mLockDistanceButton,
nullptr, mRepeatingLockDistanceButton ) );
49 mXConstraint.reset(
new CadConstraint( mXLineEdit, mLockXButton, mRelativeXButton, mRepeatingLockXButton ) );
50 mYConstraint.reset(
new CadConstraint( mYLineEdit, mLockYButton, mRelativeYButton, mRepeatingLockYButton ) );
53 mMapCanvas->installEventFilter(
this );
54 mAngleLineEdit->installEventFilter(
this );
55 mDistanceLineEdit->installEventFilter(
this );
56 mXLineEdit->installEventFilter(
this );
57 mYLineEdit->installEventFilter(
this );
60 connect( mEnableAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::activateCad );
61 connect( mConstructionModeAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::setConstructionMode );
62 connect( mParallelAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
63 connect( mPerpendicularAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
64 connect( mLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
65 connect( mLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
66 connect( mLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
67 connect( mLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
68 connect( mRelativeAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
69 connect( mRelativeXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
70 connect( mRelativeYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
71 connect( mRepeatingLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
72 connect( mRepeatingLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
73 connect( mRepeatingLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
74 connect( mRepeatingLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
75 connect( mAngleLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
76 connect( mDistanceLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
77 connect( mXLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
78 connect( mYLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
79 connect( mAngleLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
80 connect( mDistanceLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
81 connect( mXLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
82 connect( mYLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
94 QMenu *menu =
new QMenu(
this );
96 QActionGroup *angleButtonGroup =
new QActionGroup( menu );
97 mCommonAngleActions = QMap<QAction *, double>();
98 QList< QPair< double, QString > > commonAngles;
100 QList<double> anglesDouble( { 0.0, 5.0, 10.0, 15.0, 18.0, 22.5, 30.0, 45.0, 90.0} );
101 for ( QList<double>::const_iterator it = anglesDouble.constBegin(); it != anglesDouble.constEnd(); ++it )
104 menuText = tr(
"Do Not Snap to Common Angles" );
106 menuText = QString( tr(
"%1, %2, %3, %4°…" ) ).arg( *it, 0,
'f', 1 ).arg( *it * 2, 0,
'f', 1 ).arg( *it * 3, 0,
'f', 1 ).arg( *it * 4, 0,
'f', 1 );
107 commonAngles << QPair<double, QString>( *it, menuText );
109 for ( QList< QPair<double, QString > >::const_iterator it = commonAngles.constBegin(); it != commonAngles.constEnd(); ++it )
111 QAction *action =
new QAction( it->second, menu );
112 action->setCheckable(
true );
113 action->setChecked( it->first == mCommonAngleConstraint );
114 menu->addAction( action );
115 angleButtonGroup->addAction( action );
116 mCommonAngleActions.insert( action, it->first );
119 qobject_cast< QToolButton *>( mToolbar->widgetForAction( mSettingsAction ) )->setPopupMode( QToolButton::InstantPopup );
120 mSettingsAction->setMenu( menu );
121 connect( menu, &QMenu::triggered,
this, &QgsAdvancedDigitizingDockWidget::settingsButtonTriggered );
124 mConstructionModeAction->setToolTip(
"<b>" + tr(
"Construction mode" ) +
"</b><br>(" + tr(
"press c to toggle on/off" ) +
")" );
125 mDistanceLineEdit->setToolTip(
"<b>" + tr(
"Distance" ) +
"</b><br>(" + tr(
"press d for quick access" ) +
")" );
126 mLockDistanceButton->setToolTip(
"<b>" + tr(
"Lock distance" ) +
"</b><br>(" + tr(
"press Ctrl + d for quick access" ) +
")" );
127 mRepeatingLockDistanceButton->setToolTip(
"<b>" + tr(
"Continuously lock distance" ) +
"</b>" );
129 mRelativeAngleButton->setToolTip(
"<b>" + tr(
"Toggles relative angle to previous segment" ) +
"</b><br>(" + tr(
"press Shift + a for quick access" ) +
")" );
130 mAngleLineEdit->setToolTip(
"<b>" + tr(
"Angle" ) +
"</b><br>(" + tr(
"press a for quick access" ) +
")" );
131 mLockAngleButton->setToolTip(
"<b>" + tr(
"Lock angle" ) +
"</b><br>(" + tr(
"press Ctrl + a for quick access" ) +
")" );
132 mRepeatingLockAngleButton->setToolTip(
"<b>" + tr(
"Continuously lock angle" ) +
"</b>" );
134 mRelativeXButton->setToolTip(
"<b>" + tr(
"Toggles relative x to previous node" ) +
"</b><br>(" + tr(
"press Shift + x for quick access" ) +
")" );
135 mXLineEdit->setToolTip(
"<b>" + tr(
"X coordinate" ) +
"</b><br>(" + tr(
"press x for quick access" ) +
")" );
136 mLockXButton->setToolTip(
"<b>" + tr(
"Lock x coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + x for quick access" ) +
")" );
137 mRepeatingLockXButton->setToolTip(
"<b>" + tr(
"Continuously lock x coordinate" ) +
"</b>" );
139 mRelativeYButton->setToolTip(
"<b>" + tr(
"Toggles relative y to previous node" ) +
"</b><br>(" + tr(
"press Shift + y for quick access" ) +
")" );
140 mYLineEdit->setToolTip(
"<b>" + tr(
"Y coordinate" ) +
"</b><br>(" + tr(
"press y for quick access" ) +
")" );
141 mLockYButton->setToolTip(
"<b>" + tr(
"Lock y coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + y for quick access" ) +
")" );
142 mRepeatingLockYButton->setToolTip(
"<b>" + tr(
"Continuously lock y coordinate" ) +
"</b>" );
145 updateCapacity(
true );
155 setCadEnabled(
false );
158 void QgsAdvancedDigitizingDockWidget::setCadEnabled(
bool enabled )
160 mCadEnabled = enabled;
161 mEnableAction->setChecked( enabled );
162 mConstructionModeAction->setEnabled( enabled );
163 mParallelAction->setEnabled( enabled );
164 mPerpendicularAction->setEnabled( enabled );
165 mSettingsAction->setEnabled( enabled );
166 mInputWidgets->setEnabled( enabled );
169 setConstructionMode(
false );
172 void QgsAdvancedDigitizingDockWidget::activateCad(
bool enabled )
174 enabled &= mCurrentMapToolSupportsCad;
176 mSessionActive = enabled;
178 if ( enabled && !isVisible() )
183 setCadEnabled( enabled );
186 void QgsAdvancedDigitizingDockWidget::additionalConstraintClicked(
bool activated )
192 if ( sender() == mParallelAction )
194 lockAdditionalConstraint(
Parallel );
196 else if ( sender() == mPerpendicularAction )
202 void QgsAdvancedDigitizingDockWidget::setConstraintRelative(
bool activate )
204 if ( sender() == mRelativeAngleButton )
206 mAngleConstraint->setRelative( activate );
208 else if ( sender() == mRelativeXButton )
210 mXConstraint->setRelative( activate );
212 else if ( sender() == mRelativeYButton )
214 mYConstraint->setRelative( activate );
218 void QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock(
bool activate )
220 if ( sender() == mRepeatingLockDistanceButton )
222 mDistanceConstraint->setRepeatingLock( activate );
224 else if ( sender() == mRepeatingLockAngleButton )
226 mAngleConstraint->setRepeatingLock( activate );
228 else if ( sender() == mRepeatingLockXButton )
230 mXConstraint->setRepeatingLock( activate );
232 else if ( sender() == mRepeatingLockYButton )
234 mYConstraint->setRepeatingLock( activate );
238 void QgsAdvancedDigitizingDockWidget::setConstructionMode(
bool enabled )
240 mConstructionMode = enabled;
241 mConstructionModeAction->setChecked( enabled );
244 void QgsAdvancedDigitizingDockWidget::settingsButtonTriggered( QAction *action )
247 QMap<QAction *, double>::const_iterator ica = mCommonAngleActions.constFind( action );
248 if ( ica != mCommonAngleActions.constEnd() )
250 ica.key()->setChecked(
true );
251 mCommonAngleConstraint = ica.value();
263 if ( releaseRepeatingLocks || !mAngleConstraint->isRepeatingLock() )
265 if ( releaseRepeatingLocks || !mDistanceConstraint->isRepeatingLock() )
267 if ( releaseRepeatingLocks || !mXConstraint->isRepeatingLock() )
269 if ( releaseRepeatingLocks || !mYConstraint->isRepeatingLock() )
274 void QgsAdvancedDigitizingDockWidget::emit
pointChanged()
277 QPoint globalPos = mMapCanvas->cursor().pos();
278 QPoint pos = mMapCanvas->mapFromGlobal( globalPos );
279 QMouseEvent *e =
new QMouseEvent( QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier );
280 mCurrentMapTool->canvasMoveEvent( e );
287 if ( obj == mAngleLineEdit || obj == mLockAngleButton )
289 constraint = mAngleConstraint.get();
291 else if ( obj == mDistanceLineEdit || obj == mLockDistanceButton )
293 constraint = mDistanceConstraint.get();
295 else if ( obj == mXLineEdit || obj == mLockXButton )
297 constraint = mXConstraint.get();
299 else if ( obj == mYLineEdit || obj == mLockYButton )
301 constraint = mYConstraint.get();
306 double QgsAdvancedDigitizingDockWidget::parseUserInput(
const QString &inputValue,
bool &ok )
const 322 value = result.toDouble( &ok );
327 void QgsAdvancedDigitizingDockWidget::updateConstraintValue(
CadConstraint *constraint,
const QString &textValue,
bool convertExpression )
329 if ( !constraint || textValue.isEmpty() )
338 double value = parseUserInput( textValue, ok );
342 constraint->
setValue( value, convertExpression );
347 void QgsAdvancedDigitizingDockWidget::lockConstraint(
bool activate )
357 QString textValue = constraint->
lineEdit()->text();
358 if ( !textValue.isEmpty() )
361 double value = parseUserInput( textValue, ok );
381 if ( constraint == mAngleConstraint.get() )
391 void QgsAdvancedDigitizingDockWidget::constraintTextEdited(
const QString &textValue )
399 updateConstraintValue( constraint, textValue,
false );
402 void QgsAdvancedDigitizingDockWidget::constraintFocusOut()
404 QLineEdit *lineEdit = qobject_cast< QLineEdit * >( sender()->parent() );
414 updateConstraintValue( constraint, lineEdit->text(), true );
417 void QgsAdvancedDigitizingDockWidget::lockAdditionalConstraint(
AdditionalConstraint constraint )
419 mAdditionalConstraint = constraint;
420 mPerpendicularAction->setChecked( constraint ==
Perpendicular );
421 mParallelAction->setChecked( constraint ==
Parallel );
424 void QgsAdvancedDigitizingDockWidget::updateCapacity(
bool updateUIwithoutChange )
426 CadCapacities newCapacities =
nullptr;
428 if ( mCadPointList.count() > 1 )
432 if ( mCadPointList.count() > 2 )
436 if ( !updateUIwithoutChange && newCapacities == mCapacities )
446 bool relativeAngle = mCadEnabled && newCapacities.testFlag(
RelativeAngle );
447 bool absoluteAngle = mCadEnabled && newCapacities.testFlag(
AbsoluteAngle );
450 mPerpendicularAction->setEnabled( absoluteAngle && snappingEnabled );
451 mParallelAction->setEnabled( absoluteAngle && snappingEnabled );
454 if ( !snappingEnabled )
456 mPerpendicularAction->setToolTip( tr(
"Snapping must be enabled to utilize perpendicular mode" ) );
457 mParallelAction->setToolTip( tr(
"Snapping must be enabled to utilize parallel mode" ) );
461 mPerpendicularAction->setToolTip(
"<b>" + tr(
"Perpendicular" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
462 mParallelAction->setToolTip(
"<b>" + tr(
"Parallel" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
466 if ( !absoluteAngle )
472 mLockAngleButton->setEnabled( absoluteAngle );
473 mRelativeAngleButton->setEnabled( relativeAngle );
474 mAngleLineEdit->setEnabled( absoluteAngle );
475 if ( !absoluteAngle )
479 if ( !relativeAngle )
481 mAngleConstraint->setRelative(
false );
483 else if ( relativeAngle && !mCapacities.testFlag(
RelativeAngle ) )
486 mAngleConstraint->setRelative(
true );
490 mLockDistanceButton->setEnabled( relativeCoordinates );
491 mDistanceLineEdit->setEnabled( relativeCoordinates );
492 if ( !relativeCoordinates )
497 mRelativeXButton->setEnabled( relativeCoordinates );
498 mRelativeYButton->setEnabled( relativeCoordinates );
501 mCapacities = newCapacities;
519 context.
xConstraint = _constraint( mXConstraint.get() );
520 context.
yConstraint = _constraint( mYConstraint.get() );
531 bool res = output.
valid;
533 mSnappedSegment.clear();
538 mSnappedSegment << edgePt0 << edgePt1;
559 updateCurrentPoint( point );
561 updateUnlockedConstraintValues( point );
569 emit
pushWarning( tr(
"Some constraints are incompatible. Resulting point might be incorrect." ) );
576 void QgsAdvancedDigitizingDockWidget::updateUnlockedConstraintValues(
const QgsPointXY &point )
578 bool previousPointExist, penulPointExist;
583 if ( !mAngleConstraint->isLocked() && previousPointExist )
586 if ( penulPointExist && mAngleConstraint->relative() )
589 angle = std::atan2( previousPt.
y() - penultimatePt.
y(),
590 previousPt.
x() - penultimatePt.
x() );
592 angle = ( std::atan2( point.
y() - previousPt.
y(),
593 point.
x() - previousPt.
x()
594 ) - angle ) * 180 / M_PI;
596 angle = std::fmod( angle, 360.0 );
597 mAngleConstraint->setValue( angle );
600 if ( !mDistanceConstraint->isLocked() && previousPointExist )
602 mDistanceConstraint->setValue( std::sqrt( previousPt.
sqrDist( point ) ) );
605 if ( !mXConstraint->isLocked() )
607 if ( previousPointExist && mXConstraint->relative() )
609 mXConstraint->setValue( point.
x() - previousPt.
x() );
613 mXConstraint->setValue( point.
x() );
617 if ( !mYConstraint->isLocked() )
619 if ( previousPointExist && mYConstraint->relative() )
621 mYConstraint->setValue( point.
y() - previousPt.
y() );
625 mYConstraint->setValue( point.
y() );
631 QList<QgsPointXY> QgsAdvancedDigitizingDockWidget::snapSegmentToAllLayers(
const QgsPointXY &originalMapPoint,
bool *snapped )
const 633 QList<QgsPointXY> segment;
646 match = snappingUtils->
snapToMap( originalMapPoint );
648 snappingUtils->
setConfig( canvasConfig );
653 segment << pt1 << pt2;
658 *snapped = segment.count() == 2;
671 bool previousPointExist, penulPointExist, snappedSegmentExist;
674 mSnappedSegment = snapSegmentToAllLayers( e->
originalMapPoint(), &snappedSegmentExist );
676 if ( !previousPointExist || !snappedSegmentExist )
681 double angle = std::atan2( mSnappedSegment[0].y() - mSnappedSegment[1].y(), mSnappedSegment[0].x() - mSnappedSegment[1].x() );
683 if ( mAngleConstraint->relative() && penulPointExist )
685 angle -= std::atan2( previousPt.
y() - penultimatePt.
y(), previousPt.
x() - penultimatePt.
x() );
695 mAngleConstraint->setValue( angle );
696 mAngleConstraint->setLockMode( lockMode );
714 case Qt::Key_Backspace:
717 removePreviousPoint();
751 case Qt::Key_Backspace:
754 removePreviousPoint();
780 bool QgsAdvancedDigitizingDockWidget::eventFilter( QObject *obj, QEvent *event )
784 return QgsDockWidget::eventFilter( obj, event );
792 if ( event->type() == QEvent::ShortcutOverride ||
event->type() == QEvent::KeyPress )
794 if ( QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>( event ) )
796 return filterKeyPress( keyEvent );
799 return QgsDockWidget::eventFilter( obj, event );
802 bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e )
808 QEvent::Type type = e->type();
814 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
816 mXConstraint->toggleLocked();
820 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
824 mXConstraint->toggleRelative();
830 else if ( type == QEvent::KeyPress )
832 mXLineEdit->setFocus();
833 mXLineEdit->selectAll();
841 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
843 mYConstraint->toggleLocked();
847 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
851 mYConstraint->toggleRelative();
857 else if ( type == QEvent::KeyPress )
859 mYLineEdit->setFocus();
860 mYLineEdit->selectAll();
868 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
872 mAngleConstraint->toggleLocked();
877 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
881 mAngleConstraint->toggleRelative();
887 else if ( type == QEvent::KeyPress )
889 mAngleLineEdit->setFocus();
890 mAngleLineEdit->selectAll();
898 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
902 mDistanceConstraint->toggleLocked();
908 else if ( type == QEvent::KeyPress )
910 mDistanceLineEdit->setFocus();
911 mDistanceLineEdit->selectAll();
918 if ( type == QEvent::KeyPress )
920 setConstructionMode( !mConstructionMode );
927 if ( type == QEvent::KeyPress )
929 bool parallel = mParallelAction->isChecked();
930 bool perpendicular = mPerpendicularAction->isChecked();
932 if ( !parallel && !perpendicular )
936 else if ( perpendicular )
938 lockAdditionalConstraint(
Parallel );
953 return e->isAccepted();
961 mErrorLabel->setText( tr(
"CAD tools can not be used on geographic coordinates. Change the coordinates system in the project properties." ) );
963 mEnableAction->setEnabled(
false );
964 setCadEnabled(
false );
968 mEnableAction->setEnabled(
true );
972 mCurrentMapToolSupportsCad =
true;
974 if ( mSessionActive && !isVisible() )
978 setCadEnabled( mSessionActive );
986 mEnableAction->setEnabled(
false );
987 mErrorLabel->setText( tr(
"CAD tools are not enabled for the current map tool" ) );
991 mCurrentMapToolSupportsCad =
false;
993 setCadEnabled(
false );
998 mCadPaintItem->update();
1005 mCadPointList << point;
1009 mCadPointList.insert( 0, point );
1015 void QgsAdvancedDigitizingDockWidget::removePreviousPoint()
1021 mCadPointList.removeAt( i );
1027 mCadPointList.clear();
1028 mSnappedSegment.clear();
1029 mSnappedToVertex =
false;
1034 void QgsAdvancedDigitizingDockWidget::updateCurrentPoint(
const QgsPointXY &point )
1038 mCadPointList << point;
1043 mCadPointList[0] = point;
1051 mLockerButton->setChecked( mode == HardLock );
1052 if ( mRepeatingLockButton )
1054 if ( mode == HardLock )
1056 mRepeatingLockButton->setEnabled(
true );
1060 mRepeatingLockButton->setChecked(
false );
1061 mRepeatingLockButton->setEnabled(
false );
1065 if ( mode == NoLock )
1073 mRepeatingLock = repeating;
1074 if ( mRepeatingLockButton )
1075 mRepeatingLockButton->setChecked( repeating );
1080 mRelative = relative;
1081 if ( mRelativeButton )
1083 mRelativeButton->setChecked( relative );
1091 mLineEdit->setText( QLocale().toString( value,
'f', 6 ) );
1096 setLockMode( mLockMode == HardLock ? NoLock : HardLock );
1101 setRelative( !mRelative );
1109 return mCadPointList.value( 0 );
1119 return mCadPointList.value( 1 );
1129 return mCadPointList.value( 2 );
Class for parsing and evaluation of expressions (formerly called "search strings").
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
Returns if snapping is enabled.
Structure with details of one constraint.
A class to represent a 2D point.
double qgsPermissiveToDouble(QString string, bool &ok)
Converts a string to a double in a permissive way, e.g., allowing for incorrect numbers of digits bet...
QVariant evaluate()
Evaluate the feature and return the result.
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
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.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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.
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) ...
double softLockCommonAngle
Angle (in degrees) to which we have soft-locked ourselves (if not set it is -1)
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
Gets 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.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
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
Returns snapping utility class that is associated with map canvas.
bool relative
Whether the value is relative to previous value.
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
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.