From bee64cd5577bd3a1173570e6e26f3297d8cccc37 Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Sat, 1 Jun 2024 15:58:58 +0700 Subject: [PATCH] Address review, add tests --- .../qgsadvanceddigitizingdockwidget.sip.in | 8 +-- .../qgsadvanceddigitizingdockwidget.sip.in | 8 +-- src/gui/qgsadvanceddigitizingcanvasitem.cpp | 10 ++-- src/gui/qgsadvanceddigitizingdockwidget.cpp | 29 +++++------ src/gui/qgsadvanceddigitizingdockwidget.h | 10 ++-- tests/src/app/testqgsadvanceddigitizing.cpp | 52 +++++++++++++++++++ 6 files changed, 82 insertions(+), 35 deletions(-) diff --git a/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in b/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in index 779eefd41c65..874873f94a2c 100644 --- a/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in +++ b/python/PyQt6/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in @@ -285,28 +285,28 @@ 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 +.. versionadded:: 3.40 %End bool showConstructionGuides() const; %Docstring Returns whether the construction guides are visible. -.. versionadded:: 3.38 +.. versionadded:: 3.40 %End bool snapToConstructionGuides() const; %Docstring Returns whether points should snap to construction guides. -.. versionadded:: 3.38 +.. versionadded:: 3.40 %End bool recordConstructionGuides() const; %Docstring Returns whether construction guides are being recorded. -.. versionadded:: 3.38 +.. versionadded:: 3.40 %End Qgis::BetweenLineConstraint betweenLineConstraint() const; diff --git a/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in b/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in index 2995e16307ea..bb6476e19a17 100644 --- a/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in +++ b/python/gui/auto_generated/qgsadvanceddigitizingdockwidget.sip.in @@ -285,28 +285,28 @@ 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 +.. versionadded:: 3.40 %End bool showConstructionGuides() const; %Docstring Returns whether the construction guides are visible. -.. versionadded:: 3.38 +.. versionadded:: 3.40 %End bool snapToConstructionGuides() const; %Docstring Returns whether points should snap to construction guides. -.. versionadded:: 3.38 +.. versionadded:: 3.40 %End bool recordConstructionGuides() const; %Docstring Returns whether construction guides are being recorded. -.. versionadded:: 3.38 +.. versionadded:: 3.40 %End Qgis::BetweenLineConstraint betweenLineConstraint() const; diff --git a/src/gui/qgsadvanceddigitizingcanvasitem.cpp b/src/gui/qgsadvanceddigitizingcanvasitem.cpp index 8cf8447ebf50..72c7277955b9 100644 --- a/src/gui/qgsadvanceddigitizingcanvasitem.cpp +++ b/src/gui/qgsadvanceddigitizingcanvasitem.cpp @@ -51,13 +51,9 @@ void QgsAdvancedDigitizingCanvasItem::paint( QPainter *painter ) 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] ); - } - + QgsGeometry geom = feature.geometry(); + geom.mapToPixel( *mMapCanvas->getCoordinateTransform() ); + const QPolygonF polygon = geom.asQPolygonF(); painter->drawPolyline( polygon ); } } diff --git a/src/gui/qgsadvanceddigitizingdockwidget.cpp b/src/gui/qgsadvanceddigitizingdockwidget.cpp index fa89b8117b7f..05db8214b083 100644 --- a/src/gui/qgsadvanceddigitizingdockwidget.cpp +++ b/src/gui/qgsadvanceddigitizingdockwidget.cpp @@ -200,13 +200,13 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas * // Construction modes QMenu *constructionSettingsMenu = new QMenu( this ); - mRecordConstructionGuides = new QAction( tr( "Record construction guides" ), constructionSettingsMenu ); + mRecordConstructionGuides = new QAction( tr( "Record Construction Guides" ), constructionSettingsMenu ); mRecordConstructionGuides->setCheckable( true ); mRecordConstructionGuides->setChecked( settingsCadRecordConstructionGuides->value() ); constructionSettingsMenu->addAction( mRecordConstructionGuides ); connect( mRecordConstructionGuides, &QAction::triggered, this, [ = ]() { settingsCadRecordConstructionGuides->setValue( mRecordConstructionGuides->isChecked() ); } ); - mShowConstructionGuides = new QAction( tr( "Show construction guides" ), constructionSettingsMenu ); + mShowConstructionGuides = new QAction( tr( "Show Construction Guides" ), constructionSettingsMenu ); mShowConstructionGuides->setCheckable( true ); mShowConstructionGuides->setChecked( settingsCadShowConstructionGuides->value() ); constructionSettingsMenu->addAction( mShowConstructionGuides ); @@ -216,7 +216,7 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas * updateCadPaintItem(); } ); - mSnapToConstructionGuides = new QAction( tr( "Snap to visible construction guides" ), constructionSettingsMenu ); + mSnapToConstructionGuides = new QAction( tr( "Snap to Visible Construction Guides" ), constructionSettingsMenu ); mSnapToConstructionGuides->setCheckable( true ); mSnapToConstructionGuides->setChecked( settingsCadSnapToConstructionGuides->value() ); constructionSettingsMenu->addAction( mSnapToConstructionGuides ); @@ -224,7 +224,7 @@ QgsAdvancedDigitizingDockWidget::QgsAdvancedDigitizingDockWidget( QgsMapCanvas * constructionSettingsMenu->addSeparator(); - mClearConstructionGuides = new QAction( tr( "Clear construction guides" ), constructionSettingsMenu ); + mClearConstructionGuides = new QAction( tr( "Clear Construction Guides" ), constructionSettingsMenu ); constructionSettingsMenu->addAction( mClearConstructionGuides ); connect( mClearConstructionGuides, &QAction::triggered, this, [ = ]() { @@ -1597,7 +1597,7 @@ void QgsAdvancedDigitizingDockWidget::keyPressEvent( QKeyEvent *e ) if ( mConstructionGuideLine.numPoints() >= 2 ) { - mConstructionGuidesLayer->deleteFeature( mConstructionGuideId ); + mConstructionGuidesLayer->dataProvider()->deleteFeatures( QgsFeatureIds() << mConstructionGuideId ); mConstructionGuideLine.clear(); } @@ -1656,7 +1656,7 @@ bool QgsAdvancedDigitizingDockWidget::filterKeyPress( QKeyEvent *e ) { if ( mConstructionMode && mConstructionGuideLine.numPoints() >= 2 ) { - mConstructionGuidesLayer->deleteFeature( mConstructionGuideId ); + mConstructionGuidesLayer->dataProvider()->deleteFeatures( QgsFeatureIds() << mConstructionGuideId ); mConstructionGuideLine.clear(); if ( mCadPointList.size() > 1 ) @@ -1957,7 +1957,7 @@ void QgsAdvancedDigitizingDockWidget::enable() resetConstructionGuides(); } - if ( mDeferedUpdateConstructionGuidesCrs ) + if ( mDeferredUpdateConstructionGuidesCrs ) { updateConstructionGuidesCrs(); } @@ -2020,13 +2020,13 @@ void QgsAdvancedDigitizingDockWidget::addPoint( const QgsPointXY &point ) QgsFeature feature; QgsGeometry geom( mConstructionGuideLine.clone() ); feature.setGeometry( geom ); - mConstructionGuidesLayer->addFeature( feature, QgsFeatureSink::FastInsert ); + mConstructionGuidesLayer->dataProvider()->addFeature( feature ); mConstructionGuideId = feature.id(); } else if ( mConstructionGuideLine.numPoints() > 2 ) { QgsGeometry geom( mConstructionGuideLine.clone() ); - mConstructionGuidesLayer->changeGeometry( mConstructionGuideId, geom ); + mConstructionGuidesLayer->dataProvider()->changeGeometryValues( { { mConstructionGuideId, geom } } ); } } else @@ -2036,7 +2036,7 @@ void QgsAdvancedDigitizingDockWidget::addPoint( const QgsPointXY &point ) mConstructionGuideLine.addVertex( pt ); QgsGeometry geom( mConstructionGuideLine.clone() ); - mConstructionGuidesLayer->changeGeometry( mConstructionGuideId, geom ); + mConstructionGuidesLayer->dataProvider()->changeGeometryValues( { { mConstructionGuideId, geom } } ); mConstructionGuideLine.clear(); } } @@ -2310,21 +2310,21 @@ void QgsAdvancedDigitizingDockWidget::updateConstructionGuidesCrs() if ( !cadEnabled() ) { - mDeferedUpdateConstructionGuidesCrs = true; + mDeferredUpdateConstructionGuidesCrs = true; } QgsCoordinateTransform transform = QgsCoordinateTransform( mConstructionGuidesLayer->crs(), mMapCanvas->mapSettings().destinationCrs(), QgsProject::instance()->transformContext() ); mConstructionGuidesLayer->setCrs( mMapCanvas->mapSettings().destinationCrs() ); - QgsFeatureIterator it = mConstructionGuidesLayer->getFeatures(); + QgsFeatureIterator it = mConstructionGuidesLayer->getFeatures( QgsFeatureRequest().setNoAttributes() ); QgsFeature feature; while ( it.nextFeature( feature ) ) { QgsGeometry geom = feature.geometry(); geom.transform( transform ); - mConstructionGuidesLayer->changeGeometry( feature.id(), geom ); + mConstructionGuidesLayer->dataProvider()->changeGeometryValues( { { feature.id(), geom } } ); } - mDeferedUpdateConstructionGuidesCrs = false; + mDeferredUpdateConstructionGuidesCrs = false; } void QgsAdvancedDigitizingDockWidget::resetConstructionGuides() @@ -2339,5 +2339,4 @@ void QgsAdvancedDigitizingDockWidget::resetConstructionGuides() QStringLiteral( "constructionGuides" ), QStringLiteral( "memory" ), options ); - mConstructionGuidesLayer->startEditing(); } diff --git a/src/gui/qgsadvanceddigitizingdockwidget.h b/src/gui/qgsadvanceddigitizingdockwidget.h index f4c441c14784..13d3d7ecc3ed 100644 --- a/src/gui/qgsadvanceddigitizingdockwidget.h +++ b/src/gui/qgsadvanceddigitizingdockwidget.h @@ -313,25 +313,25 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private /** * Returns the vector layer within which construction guides are stored. - * \since QGIS 3.38 + * \since QGIS 3.40 */ QgsVectorLayer *constructionGuidesLayer() const { return mConstructionGuidesLayer.get(); } /** * Returns whether the construction guides are visible. - * \since QGIS 3.38 + * \since QGIS 3.40 */ bool showConstructionGuides() const; /** * Returns whether points should snap to construction guides. - * \since QGIS 3.38 + * \since QGIS 3.40 */ bool snapToConstructionGuides() const; /** * Returns whether construction guides are being recorded. - * \since QGIS 3.38 + * \since QGIS 3.40 */ bool recordConstructionGuides() const; @@ -1100,7 +1100,7 @@ class GUI_EXPORT QgsAdvancedDigitizingDockWidget : public QgsDockWidget, private std::unique_ptr mConstructionGuidesLayer; QgsFeatureId mConstructionGuideId; QgsLineString mConstructionGuideLine; - bool mDeferedUpdateConstructionGuidesCrs = false; + bool mDeferredUpdateConstructionGuidesCrs = false; // Error message std::unique_ptr mErrorMessage; diff --git a/tests/src/app/testqgsadvanceddigitizing.cpp b/tests/src/app/testqgsadvanceddigitizing.cpp index 8480f611cb83..8589ce67d79b 100644 --- a/tests/src/app/testqgsadvanceddigitizing.cpp +++ b/tests/src/app/testqgsadvanceddigitizing.cpp @@ -60,6 +60,8 @@ class TestQgsAdvancedDigitizing: public QObject void releaseLockAfterDisable(); + void constructionGuides(); + private: TestQgsMapToolAdvancedDigitizingUtils getMapToolDigitizingUtils( QgsVectorLayer *layer ); QString getWktFromLastAddedFeature( TestQgsMapToolAdvancedDigitizingUtils utils, QSet oldFeatures ); @@ -1163,5 +1165,55 @@ void TestQgsAdvancedDigitizing::releaseLockAfterDisable() mAdvancedDigitizingDockWidget->enableAction()->trigger(); } +void TestQgsAdvancedDigitizing::constructionGuides() +{ + auto utils = getMapToolDigitizingUtils( mLayer3950 ); + + QVERIFY( mAdvancedDigitizingDockWidget->cadEnabled() ); + + QCOMPARE( mAdvancedDigitizingDockWidget->constructionGuidesLayer()->featureCount(), 0 ); + + mAdvancedDigitizingDockWidget->mRecordConstructionGuides->setChecked( true ); + mAdvancedDigitizingDockWidget->setConstructionMode( true ); + + // enter a few construction steps while guide recording is on + utils.mouseClick( 10, 10, Qt::LeftButton ); + utils.mouseClick( 10, 11, Qt::LeftButton ); + utils.mouseClick( 10, 12, Qt::LeftButton ); + utils.mouseClick( 10, 13, Qt::LeftButton ); + utils.mouseClick( 10, 14, Qt::LeftButton ); + utils.mouseClick( 20, 01, Qt::RightButton ); + + QCOMPARE( mAdvancedDigitizingDockWidget->constructionGuidesLayer()->featureCount(), 1 ); + + mAdvancedDigitizingDockWidget->mRecordConstructionGuides->setChecked( false ); + + // enter a few construction steps while guide recording is off + utils.mouseClick( 10, 10, Qt::LeftButton ); + utils.mouseClick( 10, 11, Qt::LeftButton ); + utils.mouseClick( 10, 12, Qt::LeftButton ); + utils.mouseClick( 10, 13, Qt::LeftButton ); + utils.mouseClick( 10, 14, Qt::LeftButton ); + utils.mouseClick( 20, 01, Qt::RightButton ); + + QCOMPARE( mAdvancedDigitizingDockWidget->constructionGuidesLayer()->featureCount(), 1 ); + + QgsSnappingConfig snapConfig = mCanvas->snappingUtils()->config(); + snapConfig.setEnabled( true ); + mCanvas->snappingUtils()->setConfig( snapConfig ); + + mAdvancedDigitizingDockWidget->mSnapToConstructionGuides->setChecked( true ); + + // snap on an existing constructio guide vertex + utils.mouseMove( 10.1, 10 ); + QCOMPARE( mAdvancedDigitizingDockWidget->currentPointV2(), QgsPoint( 10, 10 ) ); + + mAdvancedDigitizingDockWidget->mSnapToConstructionGuides->setChecked( false ); + + // do not snap on an existing construction guide vertex + utils.mouseMove( 10.5, 14.5 ); + QGSCOMPARENEARPOINT( mAdvancedDigitizingDockWidget->currentPointV2(), QgsPoint( 10.5, 14.5 ), 0.1 ); +} + QGSTEST_MAIN( TestQgsAdvancedDigitizing ) #include "testqgsadvanceddigitizing.moc"