From 94e661747566349753dfe76618c56997107bf09b Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Sat, 25 May 2024 18:00:27 +0700 Subject: [PATCH] A panoply of tiny fixes and improvements after extensive testing --- .../core/auto_generated/qgscadutils.sip.in | 36 ------------- .../qgsadvanceddigitizingdockwidget.sip.in | 7 --- python/core/auto_generated/qgscadutils.sip.in | 36 ------------- .../qgsadvanceddigitizingdockwidget.sip.in | 7 --- src/core/qgscadutils.cpp | 20 +------ src/core/qgscadutils.h | 34 ------------ src/gui/qgsadvanceddigitizingcanvasitem.cpp | 50 ++++++++--------- src/gui/qgsadvanceddigitizingdockwidget.cpp | 54 +++++++++++++++---- src/gui/qgsadvanceddigitizingdockwidget.h | 7 --- 9 files changed, 72 insertions(+), 179 deletions(-) diff --git a/python/PyQt6/core/auto_generated/qgscadutils.sip.in b/python/PyQt6/core/auto_generated/qgscadutils.sip.in index 7002e0d8c7de..3c2c4438730b 100644 --- a/python/PyQt6/core/auto_generated/qgscadutils.sip.in +++ b/python/PyQt6/core/auto_generated/qgscadutils.sip.in @@ -132,42 +132,6 @@ Returns the recent CAD point at the specified ``index`` (in map coordinates). .. versionadded:: 3.22 %End - void setConstructionGuidesPointLocator( QgsPointLocator *pointLocator ); -%Docstring -Sets the point locator that will be used to snap point to construction guides - -.. seealso:: :py:func:`constructionGuidesPointLocator` - -.. versionadded:: 3.38 -%End - - QgsPointLocator *constructionGuidesPointLocator() const; -%Docstring -Returns the point locator that will be used to snap point to construction guides - -.. seealso:: :py:func:`constructionGuidesPointLocator` - -.. versionadded:: 3.38 -%End - - void setConstructionGuidesTolerance( double tolerance ); -%Docstring -Sets the tolarance within which points will be snapped to construction guides - -.. seealso:: :py:func:`constructionGuidesTolerance` - -.. versionadded:: 3.38 -%End - - double constructionGuidesTolerance() const; -%Docstring -Returns the tolarance within which points will be snapped to construction guides - -.. seealso:: :py:func:`constructionGuidesTolerance` - -.. versionadded:: 3.38 -%End - %Property( name = cadPointList, get = _cadPointList, set = _setCadPointList ) void _setCadPointList( const QList< QgsPointXY > &list ); QList< QgsPointXY > _cadPointList() const; diff --git a/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in b/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in index c73418ae8901..779eefd41c65 100644 --- a/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in +++ b/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in @@ -285,13 +285,6 @@ points that will not be part of a geometry being digitized. %Docstring Returns the vector layer within which construction guides are stored. -.. versionadded:: 3.38 -%End - - QgsPointLocator *constructionGuidesPointLocator() const; -%Docstring -Returns the point locator used to snap points to the construction guides. - .. versionadded:: 3.38 %End diff --git a/python/core/auto_generated/qgscadutils.sip.in b/python/core/auto_generated/qgscadutils.sip.in index 7002e0d8c7de..3c2c4438730b 100644 --- a/python/core/auto_generated/qgscadutils.sip.in +++ b/python/core/auto_generated/qgscadutils.sip.in @@ -132,42 +132,6 @@ Returns the recent CAD point at the specified ``index`` (in map coordinates). .. versionadded:: 3.22 %End - void setConstructionGuidesPointLocator( QgsPointLocator *pointLocator ); -%Docstring -Sets the point locator that will be used to snap point to construction guides - -.. seealso:: :py:func:`constructionGuidesPointLocator` - -.. versionadded:: 3.38 -%End - - QgsPointLocator *constructionGuidesPointLocator() const; -%Docstring -Returns the point locator that will be used to snap point to construction guides - -.. seealso:: :py:func:`constructionGuidesPointLocator` - -.. versionadded:: 3.38 -%End - - void setConstructionGuidesTolerance( double tolerance ); -%Docstring -Sets the tolarance within which points will be snapped to construction guides - -.. seealso:: :py:func:`constructionGuidesTolerance` - -.. versionadded:: 3.38 -%End - - double constructionGuidesTolerance() const; -%Docstring -Returns the tolarance within which points will be snapped to construction guides - -.. seealso:: :py:func:`constructionGuidesTolerance` - -.. versionadded:: 3.38 -%End - %Property( name = cadPointList, get = _cadPointList, set = _setCadPointList ) void _setCadPointList( const QList< QgsPointXY > &list ); QList< QgsPointXY > _cadPointList() const; diff --git a/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in b/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in index 220fe0719694..2995e16307ea 100644 --- a/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in +++ b/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in @@ -285,13 +285,6 @@ points that will not be part of a geometry being digitized. %Docstring Returns the vector layer within which construction guides are stored. -.. versionadded:: 3.38 -%End - - QgsPointLocator *constructionGuidesPointLocator() const; -%Docstring -Returns the point locator used to snap points to the construction guides. - .. versionadded:: 3.38 %End diff --git a/src/core/qgscadutils.cpp b/src/core/qgscadutils.cpp index e64280473e11..ba0b9969e06d 100644 --- a/src/core/qgscadutils.cpp +++ b/src/core/qgscadutils.cpp @@ -48,24 +48,8 @@ QgsCadUtils::AlignMapPointOutput QgsCadUtils::alignMapPoint( const QgsPointXY &o res.softLockX = std::numeric_limits::quiet_NaN(); res.softLockY = std::numeric_limits::quiet_NaN(); - // try to snap to construction guides - QgsPointLocator::Match snapMatch; - if ( ctx.constructionGuidesPointLocator() ) - { - snapMatch = ctx.constructionGuidesPointLocator()->nearestVertex( originalMapPoint, ctx.constructionGuidesTolerance() ); - if ( snapMatch.type() == QgsPointLocator::Invalid ) - { - snapMatch = ctx.constructionGuidesPointLocator()->nearestEdge( originalMapPoint, ctx.constructionGuidesTolerance() ); - } - } - - // try to snap to project layer(s) - const QgsPointLocator::Match layersSnapMatch = ctx.snappingUtils->snapToMap( originalMapPoint, nullptr, true ); - if ( layersSnapMatch.type() != QgsPointLocator::Invalid && layersSnapMatch.distance() < snapMatch.distance() ) - { - snapMatch = layersSnapMatch; - } - + // try to snap to project layer(s) as well as visible construction guides + QgsPointLocator::Match snapMatch = ctx.snappingUtils->snapToMap( originalMapPoint, nullptr, true ); res.snapMatch = snapMatch; QgsPointXY point = snapMatch.isValid() ? snapMatch.point() : originalMapPoint; QgsPointXY edgePt0, edgePt1; diff --git a/src/core/qgscadutils.h b/src/core/qgscadutils.h index 91d6fda6b525..f4783839369a 100644 --- a/src/core/qgscadutils.h +++ b/src/core/qgscadutils.h @@ -195,38 +195,6 @@ class CORE_EXPORT QgsCadUtils */ QQueue< QgsPointLocator::Match > lockedSnapVertices() const { return mLockedSnapVertices; } SIP_SKIP; - /** - * Sets the point locator that will be used to snap point to construction guides - * - * \see constructionGuidesPointLocator() - * \since QGIS 3.38 - */ - void setConstructionGuidesPointLocator( QgsPointLocator *pointLocator ) { mConstructionGuidesPointLocator = pointLocator; } - - /** - * Returns the point locator that will be used to snap point to construction guides - * - * \see constructionGuidesPointLocator() - * \since QGIS 3.38 - */ - QgsPointLocator *constructionGuidesPointLocator() const { return mConstructionGuidesPointLocator; } - - /** - * Sets the tolarance within which points will be snapped to construction guides - * - * \see constructionGuidesTolerance() - * \since QGIS 3.38 - */ - void setConstructionGuidesTolerance( double tolerance ) { mConstructionGuidesTolerance = tolerance; } - - /** - * Returns the tolarance within which points will be snapped to construction guides - * - * \see constructionGuidesTolerance() - * \since QGIS 3.38 - */ - double constructionGuidesTolerance() const { return mConstructionGuidesTolerance; } - #ifdef SIP_RUN SIP_PROPERTY( name = cadPointList, get = _cadPointList, set = _setCadPointList ) #endif @@ -244,8 +212,6 @@ class CORE_EXPORT QgsCadUtils */ QList mCadPointList; QQueue< QgsPointLocator::Match > mLockedSnapVertices; - QgsPointLocator *mConstructionGuidesPointLocator = nullptr; - double mConstructionGuidesTolerance = 0.0; }; diff --git a/src/gui/qgsadvanceddigitizingcanvasitem.cpp b/src/gui/qgsadvanceddigitizingcanvasitem.cpp index 9386553da76e..2f9114837c8e 100644 --- a/src/gui/qgsadvanceddigitizingcanvasitem.cpp +++ b/src/gui/qgsadvanceddigitizingcanvasitem.cpp @@ -38,6 +38,31 @@ void QgsAdvancedDigitizingCanvasItem::paint( QPainter *painter ) if ( !mAdvancedDigitizingDockWidget->cadEnabled() ) return; + painter->setRenderHint( QPainter::Antialiasing ); + painter->setCompositionMode( QPainter::CompositionMode_Difference ); + + // Draw construction guides + if ( mAdvancedDigitizingDockWidget->showConstructionGuides() ) + { + if ( QgsVectorLayer *constructionGuidesLayer = mAdvancedDigitizingDockWidget->constructionGuidesLayer() ) + { + QgsFeatureIterator it = constructionGuidesLayer->getFeatures( mMapCanvas->mapSettings().visibleExtent() ); + QgsFeature feature; + painter->setPen( mConstructionGuidesPen ); + while ( it.nextFeature( feature ) ) + { + QgsPolylineXY line = feature.geometry().asPolyline(); + QPolygonF polygon( line.size() ); + for ( int i = 0; i < line.size(); i++ ) + { + polygon[i] = toCanvasCoordinates( line[i] ); + } + + painter->drawPolyline( polygon ); + } + } + } + // Use visible polygon rather than extent to properly handle rotated maps QPolygonF mapPoly = mMapCanvas->mapSettings().visiblePolygon(); const double canvasWidth = QLineF( mapPoly[0], mapPoly[1] ).length(); @@ -84,31 +109,6 @@ void QgsAdvancedDigitizingCanvasItem::paint( QPainter *painter ) snapSegmentPix2 = toCanvasCoordinates( snappedSegment[1] ); } - painter->setRenderHint( QPainter::Antialiasing ); - painter->setCompositionMode( QPainter::CompositionMode_Difference ); - - // Draw construction guides - if ( mAdvancedDigitizingDockWidget->showConstructionGuides() ) - { - if ( QgsVectorLayer *constructionGuidesLayer = mAdvancedDigitizingDockWidget->constructionGuidesLayer() ) - { - QgsFeatureIterator it = constructionGuidesLayer->getFeatures( mMapCanvas->mapSettings().visibleExtent() ); - QgsFeature feature; - painter->setPen( mConstructionGuidesPen ); - while ( it.nextFeature( feature ) ) - { - QgsPolylineXY line = feature.geometry().asPolyline(); - QPolygonF polygon( line.size() ); - for ( int i = 0; i < line.size(); i++ ) - { - polygon[i] = toCanvasCoordinates( line[i] ); - } - - painter->drawPolyline( polygon ); - } - } - } - // Draw point snap if ( curPointExist && snappedToVertex ) { diff --git a/src/gui/qgsadvanceddigitizingdockwidget.cpp b/src/gui/qgsadvanceddigitizingdockwidget.cpp index 6f1c2f3f721c..fa89b8117b7f 100644 --- a/src/gui/qgsadvanceddigitizingdockwidget.cpp +++ b/src/gui/qgsadvanceddigitizingdockwidget.cpp @@ -410,10 +410,12 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas * updateCapacity( true ); connect( QgsProject::instance(), &QgsProject::snappingConfigChanged, this, [ = ] { updateCapacity( true ); } ); - connect( QgsProject::instance(), &QgsProject::cleared, this, [ = ]() { resetConstructionGuides(); } ); - connect( mMapCanvas, &QgsMapCanvas::destinationCrsChanged, this, [ = ] { updateConstructionGuidesCrs(); } ); - resetConstructionGuides(); + connect( QgsProject::instance(), &QgsProject::cleared, this, [ = ]() + { + mConstructionGuidesLayer.reset(); + } ); + connect( mMapCanvas, &QgsMapCanvas::destinationCrsChanged, this, [ = ] { updateConstructionGuidesCrs(); } ); disable(); } @@ -1252,8 +1254,7 @@ bool QgsAdvancedDigitizingDockWidget::applyConstraints( QgsMapMouseEvent *e ) if ( snapToConstructionGuides() ) { - context.setConstructionGuidesTolerance( QgsTolerance::toleranceInProjectUnits( mMapCanvas->snappingUtils()->config().tolerance(), mConstructionGuidesLayer.get(), mMapCanvas->mapSettings(), mMapCanvas->snappingUtils()->config().units() ) ); - context.setConstructionGuidesPointLocator( mConstructionGuidesPointLocator.get() ); + context.snappingUtils->addExtraSnapLayer( mConstructionGuidesLayer.get() ); } context.commonAngleConstraint.locked = !mMapCanvas->mapSettings().destinationCrs().isGeographic(); @@ -1315,6 +1316,7 @@ bool QgsAdvancedDigitizingDockWidget::applyConstraints( QgsMapMouseEvent *e ) * the point is not linked to a layer. */ e->setMapPoint( point ); + mSnapMatch = context.snappingUtils->snapToMap( point, nullptr, true ); if ( mSnapMatch.layer() ) { @@ -1326,6 +1328,8 @@ bool QgsAdvancedDigitizingDockWidget::applyConstraints( QgsMapMouseEvent *e ) } } + context.snappingUtils->removeExtraSnapLayer( mConstructionGuidesLayer.get() ); + if ( mSnapMatch.hasVertex() || mSnapMatch.hasLineEndpoint() ) { toggleLockedSnapVertex( mSnapMatch, mLastSnapMatch ); @@ -1590,6 +1594,13 @@ void QgsAdvancedDigitizingDockWidget::keyPressEvent( QKeyEvent *e ) case Qt::Key_Escape: { releaseLocks(); + + if ( mConstructionGuideLine.numPoints() >= 2 ) + { + mConstructionGuidesLayer->deleteFeature( mConstructionGuideId ); + mConstructionGuideLine.clear(); + } + break; } default: @@ -1641,6 +1652,22 @@ bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e ) const QEvent::Type type = e->type(); switch ( e->key() ) { + case Qt::Key_Escape: + { + if ( mConstructionMode && mConstructionGuideLine.numPoints() >= 2 ) + { + mConstructionGuidesLayer->deleteFeature( mConstructionGuideId ); + mConstructionGuideLine.clear(); + + if ( mCadPointList.size() > 1 ) + { + mConstructionGuideLine.addVertex( mCadPointList.at( 1 ) ); + } + + updateCadPaintItem(); + } + break; + } case Qt::Key_X: { // modifier+x ONLY caught for ShortcutOverride events... @@ -1925,10 +1952,17 @@ void QgsAdvancedDigitizingDockWidget::enable() setCadEnabled( mSessionActive ); + if ( !mConstructionGuidesLayer ) + { + resetConstructionGuides(); + } + if ( mDeferedUpdateConstructionGuidesCrs ) { updateConstructionGuidesCrs(); } + + updateCadPaintItem(); } void QgsAdvancedDigitizingDockWidget::disable() @@ -2259,7 +2293,7 @@ bool QgsAdvancedDigitizingDockWidget::showConstructionGuides() const bool QgsAdvancedDigitizingDockWidget::snapToConstructionGuides() const { - return mSnapToConstructionGuides ? mSnapToConstructionGuides->isChecked() : false; + return mSnapToConstructionGuides ? mShowConstructionGuides->isChecked() && mSnapToConstructionGuides->isChecked() : false; } bool QgsAdvancedDigitizingDockWidget::recordConstructionGuides() const @@ -2269,6 +2303,11 @@ bool QgsAdvancedDigitizingDockWidget::recordConstructionGuides() const void QgsAdvancedDigitizingDockWidget::updateConstructionGuidesCrs() { + if ( !mConstructionGuidesLayer ) + { + return; + } + if ( !cadEnabled() ) { mDeferedUpdateConstructionGuidesCrs = true; @@ -2292,7 +2331,6 @@ void QgsAdvancedDigitizingDockWidget::resetConstructionGuides() { if ( mConstructionGuidesLayer ) { - mConstructionGuidesPointLocator.reset(); mConstructionGuidesLayer.reset(); } @@ -2302,6 +2340,4 @@ void QgsAdvancedDigitizingDockWidget::resetConstructionGuides() QStringLiteral( "memory" ), options ); mConstructionGuidesLayer->startEditing(); - mConstructionGuidesPointLocator = std::make_unique( mConstructionGuidesLayer.get() ); - mConstructionGuidesPointLocator->init(); } diff --git a/src/gui/qgsadvanceddigitizingdockwidget.h b/src/gui/qgsadvanceddigitizingdockwidget.h index 1a58ba497c97..f4c441c14784 100644 --- a/src/gui/qgsadvanceddigitizingdockwidget.h +++ b/src/gui/qgsadvanceddigitizingdockwidget.h @@ -317,12 +317,6 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private */ QgsVectorLayer *constructionGuidesLayer() const { return mConstructionGuidesLayer.get(); } - /** - * Returns the point locator used to snap points to the construction guides. - * \since QGIS 3.38 - */ - QgsPointLocator *constructionGuidesPointLocator() const { return mConstructionGuidesPointLocator.get(); } - /** * Returns whether the construction guides are visible. * \since QGIS 3.38 @@ -1104,7 +1098,6 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private // Construction path history std::unique_ptr mConstructionGuidesLayer; - std::unique_ptr mConstructionGuidesPointLocator; QgsFeatureId mConstructionGuideId; QgsLineString mConstructionGuideLine; bool mDeferedUpdateConstructionGuidesCrs = false;