40 , mMapCanvas( canvas )
41 , mCommonAngleConstraint(
QgsSettings().value( QStringLiteral(
"/Cad/CommonAngle" ), 90 ).toInt() )
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 mEnableAction =
new QAction(
this );
61 mEnableAction->setText( tr(
"Enable advanced digitizing tools" ) );
63 mEnableAction->setCheckable(
true );
64 mEnabledButton->addAction( mEnableAction );
65 mEnabledButton->setDefaultAction( mEnableAction );
68 connect( mEnableAction, &QAction::triggered,
this, &QgsAdvancedDigitizingDockWidget::activateCad );
69 connect( mConstructionModeButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstructionMode );
70 connect( mParallelButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
71 connect( mPerpendicularButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::additionalConstraintClicked );
72 connect( mLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
73 connect( mLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
74 connect( mLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
75 connect( mLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::lockConstraint );
76 connect( mRelativeAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
77 connect( mRelativeXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
78 connect( mRelativeYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRelative );
79 connect( mRepeatingLockDistanceButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
80 connect( mRepeatingLockAngleButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
81 connect( mRepeatingLockXButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
82 connect( mRepeatingLockYButton, &QAbstractButton::clicked,
this, &QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock );
83 connect( mAngleLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
84 connect( mDistanceLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
85 connect( mXLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
86 connect( mYLineEdit, &QLineEdit::returnPressed,
this, [ = ]() { lockConstraint(); } );
87 connect( mAngleLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
88 connect( mDistanceLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
89 connect( mXLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
90 connect( mYLineEdit, &QLineEdit::textEdited,
this, &QgsAdvancedDigitizingDockWidget::constraintTextEdited );
102 QMenu *menu =
new QMenu(
this );
104 QActionGroup *angleButtonGroup =
new QActionGroup( menu );
105 mCommonAngleActions = QMap<QAction *, int>();
106 QList< QPair< int, QString > > commonAngles;
107 commonAngles << QPair<int, QString>( 0, tr(
"Do Not Snap to Common Angles" ) );
108 commonAngles << QPair<int, QString>( 30, tr(
"Snap to 30° Angles" ) );
109 commonAngles << QPair<int, QString>( 45, tr(
"Snap to 45° Angles" ) );
110 commonAngles << QPair<int, QString>( 90, tr(
"Snap to 90° Angles" ) );
111 for ( QList< QPair< int, QString > >::const_iterator it = commonAngles.constBegin(); it != commonAngles.constEnd(); ++it )
113 QAction *action =
new QAction( it->second, menu );
114 action->setCheckable(
true );
115 action->setChecked( it->first == mCommonAngleConstraint );
116 menu->addAction( action );
117 angleButtonGroup->addAction( action );
118 mCommonAngleActions.insert( action, it->first );
121 mSettingsButton->setMenu( menu );
122 connect( mSettingsButton, SIGNAL( triggered( QAction * ) ),
this, SLOT( settingsButtonTriggered( QAction * ) ) );
125 mConstructionModeButton->setToolTip(
"<b>" + tr(
"Construction mode" ) +
"</b><br>(" + tr(
"press c to toggle on/off" ) +
")" );
126 mDistanceLineEdit->setToolTip(
"<b>" + tr(
"Distance" ) +
"</b><br>(" + tr(
"press d for quick access" ) +
")" );
127 mLockDistanceButton->setToolTip(
"<b>" + tr(
"Lock distance" ) +
"</b><br>(" + tr(
"press Ctrl + d for quick access" ) +
")" );
128 mRepeatingLockDistanceButton->setToolTip(
"<b>" + tr(
"Continuously lock distance" ) +
"</b>" );
130 mRelativeAngleButton->setToolTip(
"<b>" + tr(
"Toggles relative angle to previous segment" ) +
"</b><br>(" + tr(
"press Shift + a for quick access" ) +
")" );
131 mAngleLineEdit->setToolTip(
"<b>" + tr(
"Angle" ) +
"</b><br>(" + tr(
"press a for quick access" ) +
")" );
132 mLockAngleButton->setToolTip(
"<b>" + tr(
"Lock angle" ) +
"</b><br>(" + tr(
"press Ctrl + a for quick access" ) +
")" );
133 mRepeatingLockAngleButton->setToolTip(
"<b>" + tr(
"Continuously lock angle" ) +
"</b>" );
135 mRelativeXButton->setToolTip(
"<b>" + tr(
"Toggles relative x to previous node" ) +
"</b><br>(" + tr(
"press Shift + x for quick access" ) +
")" );
136 mXLineEdit->setToolTip(
"<b>" + tr(
"X coordinate" ) +
"</b><br>(" + tr(
"press x for quick access" ) +
")" );
137 mLockXButton->setToolTip(
"<b>" + tr(
"Lock x coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + x for quick access" ) +
")" );
138 mRepeatingLockXButton->setToolTip(
"<b>" + tr(
"Continuously lock x coordinate" ) +
"</b>" );
140 mRelativeYButton->setToolTip(
"<b>" + tr(
"Toggles relative y to previous node" ) +
"</b><br>(" + tr(
"press Shift + y for quick access" ) +
")" );
141 mYLineEdit->setToolTip(
"<b>" + tr(
"Y coordinate" ) +
"</b><br>(" + tr(
"press y for quick access" ) +
")" );
142 mLockYButton->setToolTip(
"<b>" + tr(
"Lock y coordinate" ) +
"</b><br>(" + tr(
"press Ctrl + y for quick access" ) +
")" );
143 mRepeatingLockYButton->setToolTip(
"<b>" + tr(
"Continuously lock y coordinate" ) +
"</b>" );
146 updateCapacity(
true );
156 setCadEnabled(
false );
159 void QgsAdvancedDigitizingDockWidget::setCadEnabled(
bool enabled )
161 mCadEnabled = enabled;
162 mEnableAction->setChecked( enabled );
163 mCadButtons->setEnabled( enabled );
164 mInputWidgets->setEnabled( enabled );
167 setConstructionMode(
false );
170 void QgsAdvancedDigitizingDockWidget::activateCad(
bool enabled )
172 enabled &= mCurrentMapToolSupportsCad;
174 mSessionActive = enabled;
176 if ( enabled && !isVisible() )
181 setCadEnabled( enabled );
184 void QgsAdvancedDigitizingDockWidget::additionalConstraintClicked(
bool activated )
190 if ( sender() == mParallelButton )
192 lockAdditionalConstraint(
Parallel );
194 else if ( sender() == mPerpendicularButton )
200 void QgsAdvancedDigitizingDockWidget::setConstraintRelative(
bool activate )
202 if ( sender() == mRelativeAngleButton )
204 mAngleConstraint->setRelative( activate );
206 else if ( sender() == mRelativeXButton )
208 mXConstraint->setRelative( activate );
210 else if ( sender() == mRelativeYButton )
212 mYConstraint->setRelative( activate );
216 void QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock(
bool activate )
218 if ( sender() == mRepeatingLockDistanceButton )
220 mDistanceConstraint->setRepeatingLock( activate );
222 else if ( sender() == mRepeatingLockAngleButton )
224 mAngleConstraint->setRepeatingLock( activate );
226 else if ( sender() == mRepeatingLockXButton )
228 mXConstraint->setRepeatingLock( activate );
230 else if ( sender() == mRepeatingLockYButton )
232 mYConstraint->setRepeatingLock( activate );
236 void QgsAdvancedDigitizingDockWidget::setConstructionMode(
bool enabled )
238 mConstructionMode = enabled;
239 mConstructionModeButton->setChecked( enabled );
242 void QgsAdvancedDigitizingDockWidget::settingsButtonTriggered( QAction *action )
245 QMap<QAction *, int>::const_iterator ica = mCommonAngleActions.constFind( action );
246 if ( ica != mCommonAngleActions.constEnd() )
248 ica.key()->setChecked(
true );
249 mCommonAngleConstraint = ica.value();
261 if ( releaseRepeatingLocks || !mAngleConstraint->isRepeatingLock() )
263 if ( releaseRepeatingLocks || !mDistanceConstraint->isRepeatingLock() )
265 if ( releaseRepeatingLocks || !mXConstraint->isRepeatingLock() )
267 if ( releaseRepeatingLocks || !mYConstraint->isRepeatingLock() )
272 void QgsAdvancedDigitizingDockWidget::emit
pointChanged()
275 QPoint globalPos = mMapCanvas->cursor().pos();
276 QPoint pos = mMapCanvas->mapFromGlobal( globalPos );
277 QMouseEvent *e =
new QMouseEvent( QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier );
278 mCurrentMapTool->canvasMoveEvent( e );
285 if ( obj == mAngleLineEdit || obj == mLockAngleButton )
287 constraint = mAngleConstraint.get();
289 else if ( obj == mDistanceLineEdit || obj == mLockDistanceButton )
291 constraint = mDistanceConstraint.get();
293 else if ( obj == mXLineEdit || obj == mLockXButton )
295 constraint = mXConstraint.get();
297 else if ( obj == mYLineEdit || obj == mLockYButton )
299 constraint = mYConstraint.get();
304 double QgsAdvancedDigitizingDockWidget::parseUserInput(
const QString &inputValue,
bool &ok )
const 307 double value = inputValue.toDouble( &ok );
320 value = result.toDouble( &ok );
325 void QgsAdvancedDigitizingDockWidget::updateConstraintValue(
CadConstraint *constraint,
const QString &textValue,
bool convertExpression )
327 if ( !constraint || textValue.isEmpty() )
336 double value = parseUserInput( textValue, ok );
340 constraint->
setValue( value, convertExpression );
345 void QgsAdvancedDigitizingDockWidget::lockConstraint(
bool activate )
355 QString textValue = constraint->
lineEdit()->text();
356 if ( !textValue.isEmpty() )
359 double value = parseUserInput( textValue, ok );
379 if ( constraint == mAngleConstraint.get() )
389 void QgsAdvancedDigitizingDockWidget::constraintTextEdited(
const QString &textValue )
397 updateConstraintValue( constraint, textValue,
false );
400 void QgsAdvancedDigitizingDockWidget::constraintFocusOut()
402 QLineEdit *lineEdit = qobject_cast< QLineEdit * >( sender()->parent() );
412 updateConstraintValue( constraint, lineEdit->text(), true );
415 void QgsAdvancedDigitizingDockWidget::lockAdditionalConstraint(
AdditionalConstraint constraint )
417 mAdditionalConstraint = constraint;
418 mPerpendicularButton->setChecked( constraint ==
Perpendicular );
419 mParallelButton->setChecked( constraint ==
Parallel );
422 void QgsAdvancedDigitizingDockWidget::updateCapacity(
bool updateUIwithoutChange )
424 CadCapacities newCapacities =
nullptr;
426 if ( mCadPointList.count() > 1 )
430 if ( mCadPointList.count() > 2 )
434 if ( !updateUIwithoutChange && newCapacities == mCapacities )
444 bool relativeAngle = mCadEnabled && newCapacities.testFlag(
RelativeAngle );
445 bool absoluteAngle = mCadEnabled && newCapacities.testFlag(
AbsoluteAngle );
448 mPerpendicularButton->setEnabled( absoluteAngle && snappingEnabled );
449 mParallelButton->setEnabled( absoluteAngle && snappingEnabled );
452 if ( !snappingEnabled )
454 mPerpendicularButton->setToolTip( tr(
"Snapping must be enabled to utilize perpendicular mode" ) );
455 mParallelButton->setToolTip( tr(
"Snapping must be enabled to utilize parallel mode" ) );
459 mPerpendicularButton->setToolTip(
"<b>" + tr(
"Perpendicular" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
460 mParallelButton->setToolTip(
"<b>" + tr(
"Parallel" ) +
"</b><br>(" + tr(
"press p to switch between perpendicular, parallel and normal mode" ) +
")" );
464 if ( !absoluteAngle )
470 mLockAngleButton->setEnabled( absoluteAngle );
471 mRelativeAngleButton->setEnabled( relativeAngle );
472 mAngleLineEdit->setEnabled( absoluteAngle );
473 if ( !absoluteAngle )
477 if ( !relativeAngle )
479 mAngleConstraint->setRelative(
false );
481 else if ( relativeAngle && !mCapacities.testFlag(
RelativeAngle ) )
484 mAngleConstraint->setRelative(
true );
488 mLockDistanceButton->setEnabled( relativeCoordinates );
489 mDistanceLineEdit->setEnabled( relativeCoordinates );
490 if ( !relativeCoordinates )
495 mRelativeXButton->setEnabled( relativeCoordinates );
496 mRelativeYButton->setEnabled( relativeCoordinates );
499 mCapacities = newCapacities;
517 context.
xConstraint = _constraint( mXConstraint.get() );
518 context.
yConstraint = _constraint( mYConstraint.get() );
529 bool res = output.
valid;
531 mSnappedSegment.clear();
536 mSnappedSegment << edgePt0 << edgePt1;
555 updateCurrentPoint( point );
557 updateUnlockedConstraintValues( point );
565 emit
pushWarning( tr(
"Some constraints are incompatible. Resulting point might be incorrect." ) );
572 void QgsAdvancedDigitizingDockWidget::updateUnlockedConstraintValues(
const QgsPointXY &point )
574 bool previousPointExist, penulPointExist;
579 if ( !mAngleConstraint->isLocked() && previousPointExist )
582 if ( penulPointExist && mAngleConstraint->relative() )
585 angle = std::atan2( previousPt.
y() - penultimatePt.
y(),
586 previousPt.
x() - penultimatePt.
x() );
588 angle = ( std::atan2( point.
y() - previousPt.
y(),
589 point.
x() - previousPt.
x()
590 ) - angle ) * 180 / M_PI;
592 angle = std::fmod( angle, 360.0 );
593 mAngleConstraint->setValue( angle );
596 if ( !mDistanceConstraint->isLocked() && previousPointExist )
598 mDistanceConstraint->setValue( std::sqrt( previousPt.
sqrDist( point ) ) );
601 if ( !mXConstraint->isLocked() )
603 if ( previousPointExist && mXConstraint->relative() )
605 mXConstraint->setValue( point.
x() - previousPt.
x() );
609 mXConstraint->setValue( point.
x() );
613 if ( !mYConstraint->isLocked() )
615 if ( previousPointExist && mYConstraint->relative() )
617 mYConstraint->setValue( point.
y() - previousPt.
y() );
621 mYConstraint->setValue( point.
y() );
627 QList<QgsPointXY> QgsAdvancedDigitizingDockWidget::snapSegmentToAllLayers(
const QgsPointXY &originalMapPoint,
bool *snapped )
const 629 QList<QgsPointXY> segment;
642 match = snappingUtils->
snapToMap( originalMapPoint );
644 snappingUtils->
setConfig( canvasConfig );
649 segment << pt1 << pt2;
654 *snapped = segment.count() == 2;
667 bool previousPointExist, penulPointExist, snappedSegmentExist;
670 mSnappedSegment = snapSegmentToAllLayers( e->
originalMapPoint(), &snappedSegmentExist );
672 if ( !previousPointExist || !snappedSegmentExist )
677 double angle = std::atan2( mSnappedSegment[0].y() - mSnappedSegment[1].y(), mSnappedSegment[0].x() - mSnappedSegment[1].x() );
679 if ( mAngleConstraint->relative() && penulPointExist )
681 angle -= std::atan2( previousPt.
y() - penultimatePt.
y(), previousPt.
x() - penultimatePt.
x() );
691 mAngleConstraint->setValue( angle );
692 mAngleConstraint->setLockMode( lockMode );
710 case Qt::Key_Backspace:
713 removePreviousPoint();
747 case Qt::Key_Backspace:
750 removePreviousPoint();
776 bool QgsAdvancedDigitizingDockWidget::eventFilter( QObject *obj, QEvent *event )
780 return QgsDockWidget::eventFilter( obj, event );
788 if ( event->type() == QEvent::ShortcutOverride ||
event->type() == QEvent::KeyPress )
790 if ( QKeyEvent *keyEvent = dynamic_cast<QKeyEvent *>( event ) )
792 return filterKeyPress( keyEvent );
795 return QgsDockWidget::eventFilter( obj, event );
798 bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e )
804 QEvent::Type type = e->type();
810 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
812 mXConstraint->toggleLocked();
816 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
820 mXConstraint->toggleRelative();
826 else if ( type == QEvent::KeyPress )
828 mXLineEdit->setFocus();
829 mXLineEdit->selectAll();
837 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
839 mYConstraint->toggleLocked();
843 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
847 mYConstraint->toggleRelative();
853 else if ( type == QEvent::KeyPress )
855 mYLineEdit->setFocus();
856 mYLineEdit->selectAll();
864 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
868 mAngleConstraint->toggleLocked();
873 else if ( type == QEvent::ShortcutOverride && e->modifiers() == Qt::ShiftModifier )
877 mAngleConstraint->toggleRelative();
883 else if ( type == QEvent::KeyPress )
885 mAngleLineEdit->setFocus();
886 mAngleLineEdit->selectAll();
894 if ( type == QEvent::ShortcutOverride && ( e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ControlModifier ) )
898 mDistanceConstraint->toggleLocked();
904 else if ( type == QEvent::KeyPress )
906 mDistanceLineEdit->setFocus();
907 mDistanceLineEdit->selectAll();
914 if ( type == QEvent::KeyPress )
916 setConstructionMode( !mConstructionMode );
923 if ( type == QEvent::KeyPress )
925 bool parallel = mParallelButton->isChecked();
926 bool perpendicular = mPerpendicularButton->isChecked();
928 if ( !parallel && !perpendicular )
932 else if ( perpendicular )
934 lockAdditionalConstraint(
Parallel );
949 return e->isAccepted();
957 mErrorLabel->setText( tr(
"CAD tools can not be used on geographic coordinates. Change the coordinates system in the project properties." ) );
959 mEnableAction->setEnabled(
false );
960 setCadEnabled(
false );
964 mEnableAction->setEnabled(
true );
967 setMaximumHeight( 220 );
969 mCurrentMapToolSupportsCad =
true;
971 if ( mSessionActive && !isVisible() )
975 setCadEnabled( mSessionActive );
983 mEnableAction->setEnabled(
false );
984 mErrorLabel->setText( tr(
"CAD tools are not enabled for the current map tool" ) );
987 setMaximumHeight( 80 );
989 mCurrentMapToolSupportsCad =
false;
991 setCadEnabled(
false );
996 mCadPaintItem->update();
1003 mCadPointList << point;
1007 mCadPointList.insert( 0, point );
1013 void QgsAdvancedDigitizingDockWidget::removePreviousPoint()
1019 mCadPointList.removeAt( i );
1025 mCadPointList.clear();
1026 mSnappedSegment.clear();
1027 mSnappedToVertex =
false;
1032 void QgsAdvancedDigitizingDockWidget::updateCurrentPoint(
const QgsPointXY &point )
1036 mCadPointList << point;
1041 mCadPointList[0] = point;
1049 mLockerButton->setChecked( mode == HardLock );
1050 if ( mRepeatingLockButton )
1052 if ( mode == HardLock )
1054 mRepeatingLockButton->setEnabled(
true );
1058 mRepeatingLockButton->setChecked(
false );
1059 mRepeatingLockButton->setEnabled(
false );
1063 if ( mode == NoLock )
1071 mRepeatingLock = repeating;
1072 if ( mRepeatingLockButton )
1073 mRepeatingLockButton->setChecked( repeating );
1078 mRelative = relative;
1079 if ( mRelativeButton )
1081 mRelativeButton->setChecked( relative );
1089 mLineEdit->setText( QString::number( value,
'f' ) );
1094 setLockMode( mLockMode == HardLock ? NoLock : HardLock );
1099 setRelative( !mRelative );
1107 return mCadPointList.value( 0 );
1117 return mCadPointList.value( 1 );
1127 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.
int softLockCommonAngle
Angle (in degrees) to which we have soft-locked ourselves (if not set it is -1)
QVariant evaluate()
Evaluate the feature and return the result.
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.
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.
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
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.