41 Q_ASSERT( segment.
count() == 2 );
45 const double x1 = segment[0].x() - center.
x();
46 const double y1 = segment[0].y() - center.
y();
47 const double x2 = segment[1].x() - center.
x();
48 const double y2 = segment[1].y() - center.
y();
49 const double dx = x2 - x1;
50 const double dy = y2 - y1;
52 const double dr = sqrt( pow( dx, 2 ) + pow( dy, 2 ) );
53 const double d = x1 * y2 - x2 * y1;
55 const double disc = pow( radius, 2 ) * pow( dr, 2 ) - pow( d, 2 );
65 const int sgnDy = dy < 0 ? -1 : 1;
67 const double ax = center.
x() + ( d * dy + sgnDy * dx * sqrt( pow( radius, 2 ) * pow( dr, 2 ) - pow( d, 2 ) ) ) / ( pow( dr, 2 ) );
68 const double ay = center.
y() + ( -d * dx + qAbs( dy ) * sqrt( pow( radius, 2 ) * pow( dr, 2 ) - pow( d, 2 ) ) ) / ( pow( dr, 2 ) );
71 const double bx = center.
x() + ( d * dy - sgnDy * dx * sqrt( pow( radius, 2 ) * pow( dr, 2 ) - pow( d, 2 ) ) ) / ( pow( dr, 2 ) );
72 const double by = center.
y() + ( -d * dx - qAbs( dy ) * sqrt( pow( radius, 2 ) * pow( dr, 2 ) - pow( d, 2 ) ) ) / ( pow( dr, 2 ) );
79 intersection.
set( p1.
x(), p1.
y() );
83 intersection.
set( p2.
x(), p2.
y() );
92 , mMapCanvas( canvas )
93 , mCurrentMapToolSupportsCad( false )
94 , mCadEnabled( false )
95 , mConstructionMode( false )
97 , mCommonAngleConstraint(
QSettings().value(
"/Cad/CommonAngle", 90 ).toInt() )
98 , mSnappedToVertex( false )
99 , mSessionActive( false )
100 , mErrorMessage( nullptr )
106 mAngleConstraint.reset(
new CadConstraint( mAngleLineEdit, mLockAngleButton, mRelativeAngleButton, mRepeatingLockAngleButton ) );
107 mDistanceConstraint.reset(
new CadConstraint( mDistanceLineEdit, mLockDistanceButton,
nullptr, mRepeatingLockDistanceButton ) );
108 mXConstraint.reset(
new CadConstraint( mXLineEdit, mLockXButton, mRelativeXButton, mRepeatingLockXButton ) );
109 mYConstraint.reset(
new CadConstraint( mYLineEdit, mLockYButton, mRelativeYButton, mRepeatingLockYButton ) );
113 mAngleLineEdit->installEventFilter(
this );
114 mDistanceLineEdit->installEventFilter(
this );
115 mXLineEdit->installEventFilter(
this );
116 mYLineEdit->installEventFilter(
this );
119 mEnableAction =
new QAction(
this );
120 mEnableAction->
setText(
tr(
"Enable advanced digitizing tools" ) );
123 mEnabledButton->addAction( mEnableAction );
124 mEnabledButton->setDefaultAction( mEnableAction );
127 connect( mEnableAction, SIGNAL( triggered(
bool ) ),
this, SLOT( activateCad(
bool ) ) );
128 connect( mConstructionModeButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstructionMode(
bool ) ) );
129 connect( mParallelButton, SIGNAL( clicked(
bool ) ),
this, SLOT( addtionalConstraintClicked(
bool ) ) );
130 connect( mPerpendicularButton, SIGNAL( clicked(
bool ) ),
this, SLOT( addtionalConstraintClicked(
bool ) ) );
131 connect( mLockAngleButton, SIGNAL( clicked(
bool ) ),
this, SLOT( lockConstraint(
bool ) ) );
132 connect( mLockDistanceButton, SIGNAL( clicked(
bool ) ),
this, SLOT( lockConstraint(
bool ) ) );
133 connect( mLockXButton, SIGNAL( clicked(
bool ) ),
this, SLOT( lockConstraint(
bool ) ) );
134 connect( mLockYButton, SIGNAL( clicked(
bool ) ),
this, SLOT( lockConstraint(
bool ) ) );
135 connect( mRelativeAngleButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstraintRelative(
bool ) ) );
136 connect( mRelativeXButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstraintRelative(
bool ) ) );
137 connect( mRelativeYButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstraintRelative(
bool ) ) );
138 connect( mRepeatingLockDistanceButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstraintRepeatingLock(
bool ) ) );
139 connect( mRepeatingLockAngleButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstraintRepeatingLock(
bool ) ) );
140 connect( mRepeatingLockXButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstraintRepeatingLock(
bool ) ) );
141 connect( mRepeatingLockYButton, SIGNAL( clicked(
bool ) ),
this, SLOT( setConstraintRepeatingLock(
bool ) ) );
142 connect( mAngleLineEdit, SIGNAL( returnPressed() ),
this, SLOT( lockConstraint() ) );
143 connect( mDistanceLineEdit, SIGNAL( returnPressed() ),
this, SLOT( lockConstraint() ) );
144 connect( mXLineEdit, SIGNAL( returnPressed() ),
this, SLOT( lockConstraint() ) );
145 connect( mYLineEdit, SIGNAL( returnPressed() ),
this, SLOT( lockConstraint() ) );
146 connect( mAngleLineEdit, SIGNAL( textEdited(
QString ) ),
this, SLOT( constraintTextEdited(
QString ) ) );
147 connect( mDistanceLineEdit, SIGNAL( textEdited(
QString ) ),
this, SLOT( constraintTextEdited(
QString ) ) );
148 connect( mXLineEdit, SIGNAL( textEdited(
QString ) ),
this, SLOT( constraintTextEdited(
QString ) ) );
149 connect( mYLineEdit, SIGNAL( textEdited(
QString ) ),
this, SLOT( constraintTextEdited(
QString ) ) );
152 connect( angleWatcher, SIGNAL( focusOut() ),
this, SLOT( constraintFocusOut() ) );
154 connect( distanceWatcher, SIGNAL( focusOut() ),
this, SLOT( constraintFocusOut() ) );
156 connect( xWatcher, SIGNAL( focusOut() ),
this, SLOT( constraintFocusOut() ) );
158 connect( yWatcher, SIGNAL( focusOut() ),
this, SLOT( constraintFocusOut() ) );
166 commonAngles << QPair<int, QString>( 0,
tr(
"Do not snap to common angles" ) );
174 action->
setChecked( it->first == mCommonAngleConstraint );
177 mCommonAngleActions.
insert( action, it->first );
191 action->
setChecked( it->first == mSnappingMode );
194 mSnappingActions.
insert( action, it->first );
197 mSettingsButton->setMenu( menu );
198 connect( mSettingsButton, SIGNAL( triggered(
QAction* ) ),
this, SLOT( settingsButtonTriggered(
QAction* ) ) );
200 updateCapacity(
true );
208 setCadEnabled(
false );
211 void QgsAdvancedDigitizingDockWidget::setCadEnabled(
bool enabled )
215 mCadButtons->setEnabled( enabled );
216 mInputWidgets->setEnabled( enabled );
220 setConstructionMode(
false );
223 void QgsAdvancedDigitizingDockWidget::activateCad(
bool enabled )
225 enabled &= mCurrentMapToolSupportsCad;
234 setCadEnabled( enabled );
237 void QgsAdvancedDigitizingDockWidget::addtionalConstraintClicked(
bool activated )
243 if (
sender() == mParallelButton )
245 lockAdditionalConstraint(
Parallel );
247 else if (
sender() == mPerpendicularButton )
254 void QgsAdvancedDigitizingDockWidget::setConstraintRelative(
bool activate )
256 if (
sender() == mRelativeAngleButton )
258 mAngleConstraint->setRelative( activate );
260 else if (
sender() == mRelativeXButton )
262 mXConstraint->setRelative( activate );
264 else if (
sender() == mRelativeYButton )
266 mYConstraint->setRelative( activate );
270 void QgsAdvancedDigitizingDockWidget::setConstraintRepeatingLock(
bool activate )
272 if (
sender() == mRepeatingLockDistanceButton )
274 mDistanceConstraint->setRepeatingLock( activate );
276 else if (
sender() == mRepeatingLockAngleButton )
278 mAngleConstraint->setRepeatingLock( activate );
280 else if (
sender() == mRepeatingLockXButton )
282 mXConstraint->setRepeatingLock( activate );
284 else if (
sender() == mRepeatingLockYButton )
286 mYConstraint->setRepeatingLock( activate );
290 void QgsAdvancedDigitizingDockWidget::setConstructionMode(
bool enabled )
293 mConstructionModeButton->setChecked( enabled );
296 void QgsAdvancedDigitizingDockWidget::settingsButtonTriggered(
QAction* action )
300 if ( isn != mSnappingActions.
constEnd() )
302 isn.
key()->setChecked(
true );
303 mSnappingMode = isn.
value();
310 if ( ica != mCommonAngleActions.
constEnd() )
312 ica.
key()->setChecked(
true );
313 mCommonAngleConstraint = ica.
value();
319 void QgsAdvancedDigitizingDockWidget::releaseLocks(
bool releaseRepeatingLocks )
325 if ( releaseRepeatingLocks || !mAngleConstraint->isRepeatingLock() )
327 if ( releaseRepeatingLocks || !mDistanceConstraint->isRepeatingLock() )
329 if ( releaseRepeatingLocks || !mXConstraint->isRepeatingLock() )
331 if ( releaseRepeatingLocks || !mYConstraint->isRepeatingLock() )
336 void QgsAdvancedDigitizingDockWidget::emit
pointChanged()
341 QMouseEvent* e =
new QMouseEvent( QEvent::MouseMove, pos, globalPos, Qt::NoButton, Qt::NoButton, Qt::NoModifier );
342 mCurrentMapTool->canvasMoveEvent( e );
349 if ( obj == mAngleLineEdit || obj == mLockAngleButton )
351 constraint = mAngleConstraint.data();
353 else if ( obj == mDistanceLineEdit || obj == mLockDistanceButton )
355 constraint = mDistanceConstraint.data();
357 else if ( obj == mXLineEdit || obj == mLockXButton )
359 constraint = mXConstraint.data();
361 else if ( obj == mYLineEdit || obj == mLockYButton )
363 constraint = mYConstraint.data();
368 double QgsAdvancedDigitizingDockWidget::parseUserInput(
const QString& inputValue,
bool& ok )
const 371 double value = inputValue.
toDouble( &ok );
389 void QgsAdvancedDigitizingDockWidget::updateConstraintValue(
CadConstraint* constraint,
const QString& textValue,
bool convertExpression )
391 if ( !constraint || textValue.
isEmpty() )
400 double value = parseUserInput( textValue, ok );
404 constraint->
setValue( value, convertExpression );
409 void QgsAdvancedDigitizingDockWidget::lockConstraint(
bool activate )
423 double value = parseUserInput( textValue, ok );
443 if ( constraint == mAngleConstraint.data() )
453 void QgsAdvancedDigitizingDockWidget::constraintTextEdited(
const QString& textValue )
461 updateConstraintValue( constraint, textValue,
false );
464 void QgsAdvancedDigitizingDockWidget::constraintFocusOut()
476 updateConstraintValue( constraint, lineEdit->
text(), true );
479 void QgsAdvancedDigitizingDockWidget::lockAdditionalConstraint(
AdditionalConstraint constraint )
481 mAdditionalConstraint = constraint;
482 mPerpendicularButton->setChecked( constraint ==
Perpendicular );
483 mParallelButton->setChecked( constraint ==
Parallel );
486 void QgsAdvancedDigitizingDockWidget::updateCapacity(
bool updateUIwithoutChange )
488 CadCapacities newCapacities =
nullptr;
490 if ( mCadPointList.
count() > 1 )
494 if ( mCadPointList.
count() > 2 )
498 if ( !updateUIwithoutChange && newCapacities == mCapacities )
506 bool relativeAngle = mCadEnabled && newCapacities.testFlag(
RelativeAngle );
507 bool absoluteAngle = mCadEnabled && newCapacities.testFlag(
AbsoluteAngle );
510 mPerpendicularButton->setEnabled( absoluteAngle );
511 mParallelButton->setEnabled( absoluteAngle );
512 if ( !absoluteAngle )
518 mLockAngleButton->setEnabled( absoluteAngle );
519 mRelativeAngleButton->setEnabled( relativeAngle );
520 mAngleLineEdit->setEnabled( absoluteAngle );
521 if ( !absoluteAngle )
525 if ( !relativeAngle )
527 mAngleConstraint->setRelative(
false );
529 else if ( relativeAngle && !mCapacities.testFlag(
RelativeAngle ) )
532 mAngleConstraint->setRelative(
true );
536 mLockDistanceButton->setEnabled( relativeCoordinates );
537 mDistanceLineEdit->setEnabled( relativeCoordinates );
538 if ( !relativeCoordinates )
543 mRelativeXButton->setEnabled( relativeCoordinates );
544 mRelativeYButton->setEnabled( relativeCoordinates );
547 mCapacities = newCapacities;
555 QgsDebugMsg(
"Constraints (locked / relative / value" );
556 QgsDebugMsg(
QString(
"Angle: %1 %2 %3" ).arg( mAngleConstraint->isLocked() ).arg( mAngleConstraint->relative() ).arg( mAngleConstraint->value() ) );
557 QgsDebugMsg(
QString(
"Distance: %1 %2 %3" ).arg( mDistanceConstraint->isLocked() ).arg( mDistanceConstraint->relative() ).arg( mDistanceConstraint->value() ) );
558 QgsDebugMsg(
QString(
"X: %1 %2 %3" ).arg( mXConstraint->isLocked() ).arg( mXConstraint->relative() ).arg( mXConstraint->value() ) );
559 QgsDebugMsg(
QString(
"Y: %1 %2 %3" ).arg( mYConstraint->isLocked() ).arg( mYConstraint->relative() ).arg( mYConstraint->value() ) );
565 bool previousPointExist, penulPointExist;
571 if ( mXConstraint->isLocked() )
573 if ( !mXConstraint->relative() )
575 point.
setX( mXConstraint->value() );
579 point.
setX( previousPt.
x() + mXConstraint->value() );
581 if ( !mSnappedSegment.
isEmpty() && !mYConstraint->isLocked() )
584 const double dx = mSnappedSegment.
at( 1 ).x() - mSnappedSegment.
at( 0 ).x();
587 point.
setY( mSnappedSegment.
at( 0 ).y() );
591 const double dy = mSnappedSegment.
at( 1 ).y() - mSnappedSegment.
at( 0 ).y();
592 point.
setY( mSnappedSegment.
at( 0 ).y() + ( dy * ( point.
x() - mSnappedSegment.
at( 0 ).x() ) ) / dx );
598 if ( mYConstraint->isLocked() )
600 if ( !mYConstraint->relative() )
602 point.
setY( mYConstraint->value() );
606 point.
setY( previousPt.
y() + mYConstraint->value() );
608 if ( !mSnappedSegment.
isEmpty() && !mXConstraint->isLocked() )
611 const double dy = mSnappedSegment.
at( 1 ).y() - mSnappedSegment.
at( 0 ).y();
614 point.
setX( mSnappedSegment.
at( 0 ).x() );
618 const double dx = mSnappedSegment.
at( 1 ).x() - mSnappedSegment.
at( 0 ).x();
619 point.
setX( mSnappedSegment.
at( 0 ).x() + ( dx * ( point.
y() - mSnappedSegment.
at( 0 ).y() ) ) / dy );
631 if ( !mAngleConstraint->isLocked() && mCapacities.testFlag(
AbsoluteAngle ) && mCommonAngleConstraint != 0 )
633 double commonAngle = mCommonAngleConstraint *
M_PI / 180;
636 double softAngle = qAtan2( point.
y() - previousPt.
y(),
637 point.
x() - previousPt.
x() );
638 double deltaAngle = 0;
639 if ( mAngleConstraint->relative() && mCapacities.testFlag(
RelativeAngle ) )
642 deltaAngle = qAtan2( previousPt.
y() - penultimatePt.
y(),
643 previousPt.
x() - penultimatePt.
x() );
644 softAngle -= deltaAngle;
646 int quo = qRound( softAngle / commonAngle );
650 softAngle = quo * commonAngle ;
653 const double dist = qAbs( qCos( softAngle + deltaAngle ) * ( previousPt.
y() - point.
y() )
654 - qSin( softAngle + deltaAngle ) * ( previousPt.
x() - point.
x() ) );
658 mAngleConstraint->setValue( 180.0 /
M_PI * softAngle );
662 if ( mAngleConstraint->isLocked() )
664 double angleValue = mAngleConstraint->value() *
M_PI / 180;
665 if ( mAngleConstraint->relative() && mCapacities.testFlag(
RelativeAngle ) )
668 angleValue += qAtan2( previousPt.
y() - penultimatePt.
y(),
669 previousPt.
x() - penultimatePt.
x() );
672 double cosa = qCos( angleValue );
673 double sina = qSin( angleValue );
674 double v = ( point.
x() - previousPt.
x() ) * cosa + ( point.
y() - previousPt.
y() ) * sina ;
675 if ( mXConstraint->isLocked() && mYConstraint->isLocked() )
679 else if ( mXConstraint->isLocked() )
687 double x = mXConstraint->value();
688 if ( !mXConstraint->relative() )
692 point.
setY( previousPt.
y() + x * sina / cosa );
695 else if ( mYConstraint->isLocked() )
703 double y = mYConstraint->value();
704 if ( !mYConstraint->relative() )
708 point.
setX( previousPt.
x() + y * cosa / sina );
713 point.
setX( previousPt.
x() + cosa * v );
714 point.
setY( previousPt.
y() + sina * v );
717 if ( !mSnappedSegment.
isEmpty() && !mDistanceConstraint->isLocked() )
722 const double x1 = previousPt.
x();
723 const double y1 = previousPt.
y();
724 const double x2 = previousPt.
x() + cosa;
725 const double y2 = previousPt.
y() + sina;
727 const double x3 = mSnappedSegment.
at( 0 ).x();
728 const double y3 = mSnappedSegment.
at( 0 ).y();
729 const double x4 = mSnappedSegment.
at( 1 ).x();
730 const double y4 = mSnappedSegment.
at( 1 ).y();
732 const double d = ( x1 - x2 ) * ( y3 - y4 ) - ( y1 - y2 ) * ( x3 - x4 );
736 if ( qAbs( d ) > 0.01 )
738 point.
setX((( x3 - x4 )*( x1*y2 - y1*x2 ) - ( x1 - x2 )*( x3*y4 - y3*x4 ) ) / d );
739 point.
setY((( y3 - y4 )*( x1*y2 - y1*x2 ) - ( y1 - y2 )*( x3*y4 - y3*x4 ) ) / d );
745 if ( mDistanceConstraint->isLocked() && previousPointExist )
747 if ( mXConstraint->isLocked() || mYConstraint->isLocked() )
750 if ( mXConstraint->isLocked() )
753 <<
QgsPoint( mXConstraint->value(), point.
y() )
754 <<
QgsPoint( mXConstraint->value(), point.
y() + 1 );
757 if ( mYConstraint->isLocked() )
760 <<
QgsPoint( point.
x(), mYConstraint->value() )
761 <<
QgsPoint( point.
x() + 1, mYConstraint->value() );
767 const double dist = sqrt( point.
sqrDist( previousPt ) );
772 point.
set( previousPt.
x() + mDistanceConstraint->value(), previousPt.
y() );
776 const double vP = mDistanceConstraint->value() / dist;
777 point.
set( previousPt.
x() + ( point.
x() - previousPt.
x() ) * vP,
778 previousPt.
y() + ( point.
y() - previousPt.
y() ) * vP );
781 if ( !mSnappedSegment.
isEmpty() && !mAngleConstraint->isLocked() )
793 QgsDebugMsg(
QString(
"penultimate point: %1 %2" ).arg( penultimatePt.
x() ).arg( penultimatePt.
y() ) );
801 updateCurrentPoint( point );
806 if ( !mAngleConstraint->isLocked() && previousPointExist )
809 if ( penulPointExist && mAngleConstraint->relative() )
812 angle = qAtan2( previousPt.
y() - penultimatePt.
y(),
813 previousPt.
x() - penultimatePt.
x() );
815 angle = ( qAtan2( point.
y() - previousPt.
y(),
816 point.
x() - previousPt.
x()
817 ) - angle ) * 180 /
M_PI;
819 angle = fmod( angle, 360.0 );
820 mAngleConstraint->setValue( angle );
823 if ( !mDistanceConstraint->isLocked() && previousPointExist )
825 mDistanceConstraint->setValue( sqrt( previousPt.
sqrDist( point ) ) );
828 if ( !mXConstraint->isLocked() )
830 if ( previousPointExist && mXConstraint->relative() )
832 mXConstraint->setValue( point.
x() - previousPt.
x() );
836 mXConstraint->setValue( point.
x() );
840 if ( !mYConstraint->isLocked() )
842 if ( previousPointExist && mYConstraint->relative() )
844 mYConstraint->setValue( point.
y() - previousPt.
y() );
848 mYConstraint->setValue( point.
y() );
863 bool previousPointExist, penulPointExist, mSnappedSegmentExist;
868 if ( !previousPointExist || !mSnappedSegmentExist )
873 double angle = qAtan2( mSnappedSegment[0].
y() - mSnappedSegment[1].
y(), mSnappedSegment[0].
x() - mSnappedSegment[1].
x() );
875 if ( mAngleConstraint->relative() && penulPointExist )
877 angle -= qAtan2( previousPt.
y() - penultimatePt.
y(), previousPt.
x() - penultimatePt.
x() );
887 mAngleConstraint->setValue( angle );
888 mAngleConstraint->setLockMode( lockMode );
900 return mCadEnabled && mConstructionMode;
910 if ( e->
button() == Qt::RightButton )
919 if ( alignToSegment( e ) )
931 releaseLocks(
false );
933 if ( e->
button() == Qt::LeftButton )
936 if ( !mConstructionMode && !captureSegment )
941 return mConstructionMode;
951 emit
pushWarning(
tr(
"Some constraints are incompatible. Resulting point might be incorrect." ) );
975 case Qt::Key_Backspace:
978 removePreviousPoint();
979 releaseLocks(
false );
1012 case Qt::Key_Backspace:
1013 case Qt::Key_Delete:
1015 removePreviousPoint();
1016 releaseLocks(
false );
1019 case Qt::Key_Escape:
1026 filterKeyPress( e );
1036 if ( event->
type() != QEvent::KeyPress )
1045 return filterKeyPress( keyEvent ) ;
1048 bool QgsAdvancedDigitizingDockWidget::filterKeyPress(
QKeyEvent* e )
1056 mXConstraint->toggleLocked();
1059 else if ( e->
modifiers() == Qt::ShiftModifier )
1063 mXConstraint->toggleRelative();
1069 mXLineEdit->setFocus();
1070 mXLineEdit->selectAll();
1078 mYConstraint->toggleLocked();
1081 else if ( e->
modifiers() == Qt::ShiftModifier )
1085 mYConstraint->toggleRelative();
1091 mYLineEdit->setFocus();
1092 mYLineEdit->selectAll();
1102 mAngleConstraint->toggleLocked();
1106 else if ( e->
modifiers() == Qt::ShiftModifier )
1110 mAngleConstraint->toggleRelative();
1116 mAngleLineEdit->setFocus();
1117 mAngleLineEdit->selectAll();
1127 mDistanceConstraint->toggleLocked();
1133 mDistanceLineEdit->setFocus();
1134 mDistanceLineEdit->selectAll();
1140 setConstructionMode( !mConstructionMode );
1145 bool parallel = mParallelButton->isChecked();
1146 bool perpendicular = mPerpendicularButton->isChecked();
1148 if ( !parallel && !perpendicular )
1152 else if ( perpendicular )
1154 lockAdditionalConstraint(
Parallel );
1174 mErrorLabel->setText(
tr(
"CAD tools can not be used on geographic coordinates. Change the coordinates system in the project properties." ) );
1175 mErrorLabel->show();
1177 setCadEnabled(
false );
1182 mErrorLabel->hide();
1186 mCurrentMapToolSupportsCad =
true;
1192 setCadEnabled( mSessionActive );
1199 mErrorLabel->setText(
tr(
"CAD tools are not enabled for the current map tool" ) );
1200 mErrorLabel->show();
1204 mCurrentMapToolSupportsCad =
false;
1206 setCadEnabled(
false );
1209 void QgsAdvancedDigitizingDockWidget::addPoint(
const QgsPoint& point )
1213 mCadPointList << point;
1217 mCadPointList.
insert( 0, point );
1223 void QgsAdvancedDigitizingDockWidget::removePreviousPoint()
1233 void QgsAdvancedDigitizingDockWidget::clearPoints()
1235 mCadPointList.
clear();
1236 mSnappedSegment.
clear();
1237 mSnappedToVertex =
false;
1242 void QgsAdvancedDigitizingDockWidget::updateCurrentPoint(
const QgsPoint& point )
1246 mCadPointList << point;
1251 mCadPointList[0] = point ;
1259 mLockerButton->setChecked( mode == HardLock );
1260 if ( mRepeatingLockButton )
1262 if ( mode == HardLock )
1264 mRepeatingLockButton->setEnabled(
true );
1268 mRepeatingLockButton->setChecked(
false );
1269 mRepeatingLockButton->setEnabled(
false );
1273 if ( mode == NoLock )
1281 mRepeatingLock = repeating;
1282 if ( mRepeatingLockButton )
1283 mRepeatingLockButton->setChecked( repeating );
1288 mRelative = relative;
1289 if ( mRelativeButton )
1291 mRelativeButton->setChecked( relative );
1304 setLockMode( mLockMode == HardLock ? NoLock : HardLock );
1309 setRelative( mRelative ?
false :
true );
1317 return mCadPointList.
value( 0 );
1327 return mCadPointList.
value( 1 );
1337 return mCadPointList.
value( 2 );
void setText(const QString &text)
Class for parsing and evaluation of expressions (formerly called "search strings").
Qt::KeyboardModifiers modifiers() const
A event filter for watching for focus events on a parent object.
Q_DECL_DEPRECATED QVariant evaluate(const QgsFeature *f)
Evaluate the feature and return the result.
snap to all rendered layers (tolerance and type from defaultSettings())
QgsPoint mapPoint() const
mapPoint returns the point in coordinates
bool acceptMatch(const QgsPointLocator::Match &m) override
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
void setIcon(const QIcon &icon)
const T & at(int i) const
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
QAction * addAction(QAction *action)
const_iterator constFind(const Key &key) const
Interface that allows rejection of some matches in intersection queries (e.g.
double toDouble(bool *ok) const
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
void update(const QRectF &rect)
double y() const
Get the y value of the point.
void setValue(const QString &key, const QVariant &value)
QString number(int n, int base)
int count(const T &value) const
snap according to the configuration set in the snapping settings
QString fromUtf8(const char *str, int size)
void installEventFilter(QObject *filterObj)
QList< QgsPoint > snapSegment(SnappingMode snappingMode, bool *snapped=nullptr, bool allLayers=false) const
Returns the first snapped segment.
double mapUnitsPerPixel() const
Return the distance in geographical coordinates that equals to one pixel in the map.
const_iterator constEnd() const
void set(double x, double y)
Sets the x and y value of the point.
A class to represent a point.
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
void setX(double x)
Sets the x value of the point.
void setMapPoint(const QgsPoint &point)
Set the (snapped) point this event points to in map coordinates.
void setY(double y)
Sets the y value of the point.
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
const Key key(const T &value) const
void insert(int i, const T &value)
double toDouble(bool *ok) const
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
iterator insert(const Key &key, const T &value)
QgsPoint snapPoint(SnappingMode snappingMode)
snapPoint will snap the points using the map canvas snapping utils configuration
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
The QgsAdvancedDigitizingCanvasItem class draws the graphical elements of the CAD tools (...
double x() const
Get the x value of the point.
bool geographicFlag() const
Returns whether the CRS is a geographic CRS.
const T value(const Key &key) const