From 580f70a912b722973c879df9f3230497745d5de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Wed, 21 Oct 2015 17:08:53 +0200 Subject: [PATCH 1/2] When we use the node tool we able to select a feature --- src/app/nodetool/qgsmaptoolnodetool.cpp | 49 +++++++++++++++++++++---- src/app/nodetool/qgsmaptoolnodetool.h | 5 +++ src/gui/qgsmapcanvassnapper.cpp | 9 ++++- src/gui/qgsmapcanvassnapper.h | 6 ++- 4 files changed, 58 insertions(+), 11 deletions(-) diff --git a/src/app/nodetool/qgsmaptoolnodetool.cpp b/src/app/nodetool/qgsmaptoolnodetool.cpp index ebb483e6784..6602dfca6c4 100644 --- a/src/app/nodetool/qgsmaptoolnodetool.cpp +++ b/src/app/nodetool/qgsmaptoolnodetool.cpp @@ -26,6 +26,7 @@ #include "qgsproject.h" #include "qgsgeometryrubberband.h" #include "qgsvectorlayer.h" +#include "qgsvectordataprovider.h" #include #include @@ -168,6 +169,22 @@ void QgsMapToolNodeTool::canvasMoveEvent( QgsMapMouseEvent* e ) } } +QgsFeature QgsMapToolNodeTool::getFeatureAtPoint( QgsMapMouseEvent* e ) +{ + QgsFeature feature; + QgsVectorLayer* vlayer = qobject_cast( mCanvas->currentLayer() ); + if ( vlayer == NULL ) { + return feature; + } + + QgsFeatureRequest request; + request.setFilterRect( QgsRectangle( e->mapPoint().x(), e->mapPoint().y(), e->mapPoint().x(), e->mapPoint().y() ) ); + QgsFeatureIterator features = vlayer->getFeatures( request ); + features.nextFeature( feature ); + + return feature; +} + void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) { QgsDebugCall; @@ -186,14 +203,23 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) if ( snapResults.size() < 1 ) { - emit messageEmitted( tr( "could not snap to a segment on the current layer." ) ); - return; + QgsFeature feature = getFeatureAtPoint( e ); + if ( feature.geometry() == NULL ) { + emit messageEmitted(tr( "could not snap to a segment on the current layer." ) ); + return; + } + else { + // remove previous warning + emit messageDiscarded(); + mSelectedFeature = new QgsSelectedFeature( feature.id(), vlayer, mCanvas ); + } } + else { + // remove previous warning + emit messageDiscarded(); - // remove previous warning - emit messageDiscarded(); - - mSelectedFeature = new QgsSelectedFeature( snapResults[0].snappedAtGeometry, vlayer, mCanvas ); + mSelectedFeature = new QgsSelectedFeature( snapResults[0].snappedAtGeometry, vlayer, mCanvas ); + } connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) ); connect( mSelectedFeature, SIGNAL( destroyed() ), this, SLOT( selectedFeatureDestroyed() ) ); connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) ); @@ -254,7 +280,7 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) // no near vertex to snap // unless point layer, try segment if ( !mIsPoint ) - mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToSegment, tol ); + mSnapper.snapToCurrentLayer( e->pos(), snapResults, QgsSnapper::SnapToSegment, tol, QList(), true ); if ( snapResults.size() > 0 ) { @@ -310,6 +336,15 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) else if ( !ctrlModifier ) { mSelectedFeature->deselectAllVertexes(); + + QgsFeature feature = getFeatureAtPoint( e ); + if ( feature.geometry() == NULL ) { + return; + } + else { + mAnother = feature.id(); + mSelectAnother = true; + } } } } diff --git a/src/app/nodetool/qgsmaptoolnodetool.h b/src/app/nodetool/qgsmaptoolnodetool.h index e44de10d918..9ffc142015a 100644 --- a/src/app/nodetool/qgsmaptoolnodetool.h +++ b/src/app/nodetool/qgsmaptoolnodetool.h @@ -61,6 +61,11 @@ class QgsMapToolNodeTool: public QgsMapToolEdit void editingToggled(); private: + /** + * Get the feature on the mouse click + */ + QgsFeature getFeatureAtPoint( QgsMapMouseEvent* e ); + /** * Deletes the rubber band pointers and clears mRubberBands */ diff --git a/src/gui/qgsmapcanvassnapper.cpp b/src/gui/qgsmapcanvassnapper.cpp index 1d70d32a1d7..3d531e25561 100644 --- a/src/gui/qgsmapcanvassnapper.cpp +++ b/src/gui/qgsmapcanvassnapper.cpp @@ -62,7 +62,8 @@ void QgsMapCanvasSnapper::setMapCanvas( QgsMapCanvas* canvas ) int QgsMapCanvasSnapper::snapToCurrentLayer( const QPoint& p, QList& results, QgsSnapper::SnappingType snap_to, double snappingTol, - const QList& excludePoints ) + const QList& excludePoints, + bool allResutInTolerance ) { results.clear(); @@ -71,7 +72,11 @@ int QgsMapCanvasSnapper::snapToCurrentLayer( const QPoint& p, QListreadNumEntry( "Digitizing", "/TopologicalEditing", 0 ); - if ( topologicalEditing == 0 ) + if ( allResutInTolerance ) + { + mSnapper->setSnapMode( QgsSnapper::SnapWithResultsWithinTolerances); + } + else if ( topologicalEditing == 0 ) { mSnapper->setSnapMode( QgsSnapper::SnapWithOneResult ); } diff --git a/src/gui/qgsmapcanvassnapper.h b/src/gui/qgsmapcanvassnapper.h index fd39c2d9201..9eae1cb3460 100644 --- a/src/gui/qgsmapcanvassnapper.h +++ b/src/gui/qgsmapcanvassnapper.h @@ -50,8 +50,10 @@ class GUI_EXPORT QgsMapCanvasSnapper @param results list to which the results are appended @param snap_to snap to vertex or to segment @param snappingTol snapping tolerance. -1 means that the search radius for vertex edits is taken - @param excludePoints a list with (map coordinate) points that should be excluded in the snapping result. Useful e.g. for vertex moves where a vertex should not be snapped to its original position*/ - int snapToCurrentLayer( const QPoint& p, QList& results, QgsSnapper::SnappingType snap_to, double snappingTol = -1, const QList& excludePoints = QList() ); + @param excludePoints a list with (map coordinate) points that should be excluded in the snapping result. Useful e.g. for vertex moves where a vertex should not be snapped to its original position + @param allResutInTolerance return all thew results in the tollerance + */ + int snapToCurrentLayer( const QPoint& p, QList& results, QgsSnapper::SnappingType snap_to, double snappingTol = -1, const QList& excludePoints = QList(), bool allResutInTolerance = false ); /** Snaps to the background layers. This method is useful to align the features of the edited layers to those of other layers (as described in the project properties). Uses snap mode QgsSnapper::SnapWithOneResult. Therefore, only the From d73ef5b189bc0dd355a90b48cdc53b8aa996a025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Brunner?= Date: Sat, 7 Nov 2015 11:53:13 +0100 Subject: [PATCH 2/2] Highlight the selected feature --- src/app/nodetool/qgsmaptoolnodetool.cpp | 24 +++++++++++++++++++++++- src/app/nodetool/qgsmaptoolnodetool.h | 8 ++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/app/nodetool/qgsmaptoolnodetool.cpp b/src/app/nodetool/qgsmaptoolnodetool.cpp index 6602dfca6c4..9893e1aa595 100644 --- a/src/app/nodetool/qgsmaptoolnodetool.cpp +++ b/src/app/nodetool/qgsmaptoolnodetool.cpp @@ -212,6 +212,7 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) // remove previous warning emit messageDiscarded(); mSelectedFeature = new QgsSelectedFeature( feature.id(), vlayer, mCanvas ); + updateSelectFeature(); } } else { @@ -219,6 +220,7 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) emit messageDiscarded(); mSelectedFeature = new QgsSelectedFeature( snapResults[0].snappedAtGeometry, vlayer, mCanvas ); + updateSelectFeature(); } connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) ); connect( mSelectedFeature, SIGNAL( destroyed() ), this, SLOT( selectedFeatureDestroyed() ) ); @@ -350,6 +352,21 @@ void QgsMapToolNodeTool::canvasPressEvent( QgsMapMouseEvent* e ) } } +void QgsMapToolNodeTool::updateSelectFeature() +{ + if (mSelectRubberBand != NULL) { + delete mSelectRubberBand; + } + mSelectRubberBand = new QgsGeometryRubberBand( mCanvas, mSelectedFeature->geometry()->type() ); + mSelectRubberBand->setBrushStyle( Qt::SolidPattern ); + mSelectRubberBand->setFillColor( QColor( 255, 0, 0, 50 ) ); + QgsAbstractGeometryV2* rbGeom = mSelectedFeature->geometry()->geometry()->clone(); + QgsVectorLayer *vlayer = mSelectedFeature->vlayer(); + if ( mCanvas->mapSettings().layerTransform( vlayer ) ) + rbGeom->transform( *mCanvas->mapSettings().layerTransform( vlayer ) ); + mSelectRubberBand->setGeometry( rbGeom ); +} + void QgsMapToolNodeTool::selectedFeatureDestroyed() { QgsDebugCall; @@ -396,6 +413,7 @@ void QgsMapToolNodeTool::canvasReleaseEvent( QgsMapMouseEvent* e ) { // select another feature mSelectedFeature->setSelectedFeature( mAnother, vlayer, mCanvas ); + updateSelectFeature(); mIsPoint = vlayer->geometryType() == QGis::Point; mSelectAnother = false; } @@ -494,6 +512,10 @@ void QgsMapToolNodeTool::cleanTool( bool deleteSelectedFeature ) { removeRubberBands(); + if ( mSelectRubberBand != NULL ) { + delete mSelectRubberBand; + mSelectRubberBand = NULL; + } if ( mSelectedFeature ) { QgsVectorLayer *vlayer = mSelectedFeature->vlayer(); @@ -504,7 +526,7 @@ void QgsMapToolNodeTool::cleanTool( bool deleteSelectedFeature ) disconnect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) ); if ( deleteSelectedFeature ) delete mSelectedFeature; - mSelectedFeature = 0; + mSelectedFeature = NULL; } if ( mNodeEditor ) { diff --git a/src/app/nodetool/qgsmaptoolnodetool.h b/src/app/nodetool/qgsmaptoolnodetool.h index 9ffc142015a..a7a08316e41 100644 --- a/src/app/nodetool/qgsmaptoolnodetool.h +++ b/src/app/nodetool/qgsmaptoolnodetool.h @@ -66,6 +66,11 @@ class QgsMapToolNodeTool: public QgsMapToolEdit */ QgsFeature getFeatureAtPoint( QgsMapMouseEvent* e ); + /** + * Update select feature rubber band + */ + void updateSelectFeature(); + /** * Deletes the rubber band pointers and clears mRubberBands */ @@ -121,6 +126,9 @@ class QgsMapToolNodeTool: public QgsMapToolEdit /** Rubber bands during node move */ QMap mMoveRubberBands; + /** Rubber band for selected feature */ + QgsGeometryRubberBand* mSelectRubberBand; + /** Vertices of features to move */ QMap > > mMoveVertices;