From c592d9e9ef2a0c51575315999320f2e4437aadd5 Mon Sep 17 00:00:00 2001 From: Marco Hugentobler Date: Wed, 22 Jul 2015 10:30:46 +0200 Subject: [PATCH] Add rubberband again --- src/app/nodetool/qgsmaptoolnodetool.cpp | 118 +++++++++++++++++++++++- src/app/nodetool/qgsmaptoolnodetool.h | 14 +++ 2 files changed, 130 insertions(+), 2 deletions(-) diff --git a/src/app/nodetool/qgsmaptoolnodetool.cpp b/src/app/nodetool/qgsmaptoolnodetool.cpp index edfe5b497e3..a4bdc864dc0 100644 --- a/src/app/nodetool/qgsmaptoolnodetool.cpp +++ b/src/app/nodetool/qgsmaptoolnodetool.cpp @@ -49,6 +49,7 @@ QgsMapToolNodeTool::~QgsMapToolNodeTool() void QgsMapToolNodeTool::canvasMapPressEvent( QgsMapMouseEvent* e ) { + removeRubberBands(); QgsVectorLayer *vlayer = qobject_cast( mCanvas->currentLayer() ); if ( !vlayer ) { @@ -58,7 +59,7 @@ void QgsMapToolNodeTool::canvasMapPressEvent( QgsMapMouseEvent* e ) bool ctrlModifier = e->modifiers() & Qt::ControlModifier; QList snapResults; - QgsFeatureId bkFeatureId; + QgsFeatureId bkFeatureId = 0; if ( mSelectedFeature ) { bkFeatureId = mSelectedFeature->featureId(); @@ -117,7 +118,64 @@ void QgsMapToolNodeTool::canvasMapPressEvent( QgsMapMouseEvent* e ) QgsPoint closestLayerVertex = mSelectedFeature->geometry()->closestVertex( e->mapPoint(), atVertex, beforeVertex, afterVertex, dist ); mSelectedFeature->selectVertex( atVertex ); - //mClosestMapVertex = toMapCoordinates( vlayer, closestLayerVertex ); + } + } +} + +void QgsMapToolNodeTool::canvasMapMoveEvent( QgsMapMouseEvent* e ) +{ + if ( !mSelectedFeature || !mSelectedFeature->hasSelection() ) + { + return; + } + + QgsVectorLayer* vlayer = mSelectedFeature->vlayer(); + if ( !vlayer ) + { + return; + } + + if ( mMoveRubberBands.empty() ) + { + QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, mSelectedFeature->geometry()->type() ); + rb->setOutlineColor( Qt::blue ); + rb->setBrushStyle( Qt::NoBrush ); + rb->setOutlineWidth( 2 ); + QgsAbstractGeometryV2* rbGeom = mSelectedFeature->geometry()->geometry()->clone(); + if ( mCanvas->mapSettings().layerTransform( vlayer ) ) + rbGeom->transform( *mCanvas->mapSettings().layerTransform( vlayer ) ); + rb->setGeometry( rbGeom ); + mMoveRubberBands.insert( mSelectedFeature->featureId(), rb ); + foreach ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() ) + { + if ( vertexEntry->isSelected() ) + mMoveVertices[mSelectedFeature->featureId()].append( qMakePair( vertexEntry->vertexId(), toMapCoordinates( vlayer, vertexEntry->point() ) ) ); + } + if ( QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ) ) + { + createTopologyRubberBands(); + } + } + else + { + // move rubberband + QList snapResults; + mSnapper.snapToBackgroundLayers( e->pos(), snapResults, QList() << mClosestMapVertex ); + + QgsPoint curPos = snapPointFromResults( snapResults, e->pos() ); + double diffX = curPos.x() - mClosestMapVertex.x(); + double diffY = curPos.y() - mClosestMapVertex.y(); + + foreach ( const QgsFeatureId& fid, mMoveRubberBands.keys() ) + { + typedef QPair MoveVertex; + foreach ( const MoveVertex& pair, mMoveVertices[fid] ) + { + QgsPointV2 pos = pair.second; + pos.setX( pos.x() + diffX ); + pos.setY( pos.y() + diffY ); + mMoveRubberBands.value( fid )->moveVertex( pair.first, pos ); + } } } } @@ -149,6 +207,7 @@ void QgsMapToolNodeTool::deactivate() void QgsMapToolNodeTool::cleanTool( bool deleteSelectedFeature ) { + removeRubberBands(); if ( mSelectedFeature ) { QgsVectorLayer *vlayer = mSelectedFeature->vlayer(); @@ -318,3 +377,58 @@ void QgsMapToolNodeTool::changeLastVertex( const QgsPointV2& pt ) { mClosestMapVertex = toMapCoordinates( currentVectorLayer(), QgsPoint( pt.x(), pt.y() ) ); } + +void QgsMapToolNodeTool::removeRubberBands() +{ + qDeleteAll( mMoveRubberBands ); + mMoveRubberBands.clear(); + mMoveVertices.clear(); +} + +void QgsMapToolNodeTool::createTopologyRubberBands() +{ + QgsVectorLayer* vlayer = mSelectedFeature->vlayer(); + + foreach ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() ) + { + if ( !vertexEntry->isSelected() ) + { + continue; + } + + // Snap vertex + QMultiMap snapResults; + vlayer->snapWithContext( vertexEntry->pointV1(), ZERO_TOLERANCE, snapResults, QgsSnapper::SnapToVertex ); + foreach ( const QgsSnappingResult& snapResult, snapResults.values() ) + { + // Get geometry of snapped feature + QgsFeatureId snapFeatureId = snapResult.snappedAtGeometry; + QgsFeature feature; + if ( !vlayer->getFeatures( QgsFeatureRequest( snapFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( feature ) ) + { + continue; + } + // Get VertexId of snapped vertex + QgsVertexId vid; + if ( !feature.geometry()->vertexIdFromVertexNr( snapResult.snappedVertexNr, vid ) ) + { + continue; + } + // Add rubberband if not already added + if ( !mMoveRubberBands.contains( snapFeatureId ) ) + { + QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, feature.geometry()->type() ); + rb->setOutlineColor( Qt::blue ); + rb->setBrushStyle( Qt::NoBrush ); + rb->setOutlineWidth( 2 ); + QgsAbstractGeometryV2* rbGeom = feature.geometry()->geometry()->clone(); + if ( mCanvas->mapSettings().layerTransform( vlayer ) ) + rbGeom->transform( *mCanvas->mapSettings().layerTransform( vlayer ) ); + rb->setGeometry( rbGeom ); + mMoveRubberBands.insert( snapFeatureId, rb ); + } + // Add to list of vertices to be moved + mMoveVertices[snapFeatureId].append( qMakePair( vid, toMapCoordinates( vlayer, feature.geometry()->geometry()->vertexAt( vid ) ) ) ); + } + } +} diff --git a/src/app/nodetool/qgsmaptoolnodetool.h b/src/app/nodetool/qgsmaptoolnodetool.h index ac069e1a3c8..4c66f06dce4 100644 --- a/src/app/nodetool/qgsmaptoolnodetool.h +++ b/src/app/nodetool/qgsmaptoolnodetool.h @@ -39,6 +39,9 @@ class QgsMapToolNodeTool: public QgsMapToolEdit //! mouse press event in map coordinates (eventually filtered) to be redefined in subclass void canvasMapPressEvent( QgsMapMouseEvent* e ) override; + //! mouse move event in map coordinates (eventually filtered) to be redefined in subclass + void canvasMapMoveEvent( QgsMapMouseEvent* e ) override; + void keyPressEvent( QKeyEvent* e ); //! called when map tool is being deactivated @@ -65,6 +68,11 @@ class QgsMapToolNodeTool: public QgsMapToolEdit */ void removeRubberBands(); + /** + * Creates rubber bands for ther features when topology editing is enabled + */ + void createTopologyRubberBands(); + /** * Disconnects signals and clears objects */ @@ -126,6 +134,12 @@ class QgsMapToolNodeTool: public QgsMapToolEdit /** Flag to tell if edition points */ bool mIsPoint; + + /** Rubber bands during node move */ + QMap mMoveRubberBands; + + /** Vertices of features to move */ + QMap > > mMoveVertices; }; #endif