mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Support for moving of multiple vertices at the same time
Just use selection rectangle to select vertices and then click one vertex from selection to move the whole group.
This commit is contained in:
parent
95eada5777
commit
d0a36d35be
@ -30,6 +30,10 @@
|
||||
|
||||
#include <QRubberBand>
|
||||
|
||||
uint qHash( const Vertex &v )
|
||||
{
|
||||
return qHash( v.layer ) ^ qHash( v.fid ) ^ qHash( v.vertexId );
|
||||
}
|
||||
|
||||
//
|
||||
// geomutils - may get moved elsewhere
|
||||
@ -173,12 +177,6 @@ QgsNodeTool2::QgsNodeTool2( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidge
|
||||
mEdgeCenterMarker->setPenWidth( 3 );
|
||||
mEdgeCenterMarker->setVisible( false );
|
||||
|
||||
mDragPointMarker = new QgsVertexMarker( canvas );
|
||||
mDragPointMarker->setIconType( QgsVertexMarker::ICON_X );
|
||||
mDragPointMarker->setColor( Qt::red );
|
||||
mDragPointMarker->setPenWidth( 3 );
|
||||
mDragPointMarker->setVisible( false );
|
||||
|
||||
mFeatureBand = createRubberBand( QgsWkbTypes::LineGeometry );
|
||||
mFeatureBand->setVisible( false );
|
||||
|
||||
@ -207,7 +205,6 @@ QgsNodeTool2::~QgsNodeTool2()
|
||||
{
|
||||
delete mSnapMarker;
|
||||
delete mEdgeCenterMarker;
|
||||
delete mDragPointMarker;
|
||||
delete mFeatureBand;
|
||||
delete mVertexBand;
|
||||
delete mEdgeBand;
|
||||
@ -221,26 +218,61 @@ void QgsNodeTool2::deactivate()
|
||||
QgsMapToolAdvancedDigitizing::deactivate();
|
||||
}
|
||||
|
||||
void QgsNodeTool2::addDragBand( const QgsPoint &v1, const QgsPoint &v2 )
|
||||
void QgsNodeTool2::addDragBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset )
|
||||
{
|
||||
QgsRubberBand *dragBand = createRubberBand( QgsWkbTypes::LineGeometry, true );
|
||||
dragBand->addPoint( v1 );
|
||||
dragBand->addPoint( v2 );
|
||||
mDragBands << dragBand;
|
||||
mDragBandsOffset << offset;
|
||||
}
|
||||
|
||||
void QgsNodeTool2::addDragMiddleBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset1, const QgsVector &offset2 )
|
||||
{
|
||||
QgsRubberBand *dragBand = createRubberBand( QgsWkbTypes::LineGeometry, true );
|
||||
dragBand->addPoint( v1 );
|
||||
dragBand->addPoint( v2 );
|
||||
mDragMiddleBands << dragBand;
|
||||
mDragMiddleBandsOffset << qMakePair( offset1, offset2 );
|
||||
}
|
||||
|
||||
void QgsNodeTool2::clearDragBands()
|
||||
{
|
||||
qDeleteAll( mDragBands );
|
||||
mDragBands.clear();
|
||||
mDragBandsOffset.clear();
|
||||
|
||||
// for the case when standalone point geometry is being dragged
|
||||
mDragPointMarker->setVisible( false );
|
||||
qDeleteAll( mDragMiddleBands );
|
||||
mDragMiddleBands.clear();
|
||||
mDragMiddleBandsOffset.clear();
|
||||
|
||||
qDeleteAll( mDragPointMarkers );
|
||||
mDragPointMarkers.clear();
|
||||
mDragPointMarkersOffset.clear();
|
||||
}
|
||||
|
||||
void QgsNodeTool2::cadCanvasPressEvent( QgsMapMouseEvent *e )
|
||||
{
|
||||
setHighlightedNodes( QList<Vertex>() ); // reset selection
|
||||
if ( !mDraggingVertex && !mSelectedNodes.isEmpty() )
|
||||
{
|
||||
// only remove highlight if not clicked on one of highlighted nodes
|
||||
bool clickedOnHighlightedNode = false;
|
||||
QgsPointLocator::Match m = snapToEditableLayer( e );
|
||||
if ( m.hasVertex() )
|
||||
{
|
||||
Q_FOREACH ( const Vertex &selectedNode, mSelectedNodes )
|
||||
{
|
||||
if ( selectedNode.layer == m.layer() && selectedNode.fid == m.featureId() && selectedNode.vertexId == m.vertexIndex() )
|
||||
{
|
||||
clickedOnHighlightedNode = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !clickedOnHighlightedNode )
|
||||
setHighlightedNodes( QList<Vertex>() ); // reset selection
|
||||
}
|
||||
|
||||
if ( e->button() == Qt::LeftButton )
|
||||
{
|
||||
@ -396,13 +428,29 @@ void QgsNodeTool2::mouseMoveDraggingVertex( QgsMapMouseEvent *e )
|
||||
|
||||
mEdgeCenterMarker->setVisible( false );
|
||||
|
||||
Q_FOREACH ( QgsRubberBand *band, mDragBands )
|
||||
band->movePoint( 1, e->mapPoint() );
|
||||
// rubber bands with one end moving
|
||||
for ( int i = 0; i < mDragBands.count(); ++i )
|
||||
{
|
||||
QgsRubberBand *band = mDragBands[i];
|
||||
const QgsVector &offset = mDragBandsOffset[i];
|
||||
band->movePoint( 1, e->mapPoint() + offset );
|
||||
}
|
||||
|
||||
// rubber bands with both ends moving
|
||||
for ( int i = 0; i < mDragMiddleBands.count(); ++i )
|
||||
{
|
||||
QgsRubberBand *band = mDragMiddleBands[i];
|
||||
const QPair<QgsVector, QgsVector> &offset = mDragMiddleBandsOffset[i];
|
||||
band->movePoint( 0, e->mapPoint() + offset.first );
|
||||
band->movePoint( 1, e->mapPoint() + offset.second );
|
||||
}
|
||||
|
||||
// in case of moving of standalone point geometry
|
||||
if ( mDragPointMarker->isVisible() )
|
||||
for ( int i = 0; i < mDragPointMarkers.count(); ++i )
|
||||
{
|
||||
mDragPointMarker->setCenter( e->mapPoint() );
|
||||
QgsVertexMarker *marker = mDragPointMarkers[i];
|
||||
QgsVector offset = mDragPointMarkersOffset[i];
|
||||
marker->setCenter( e->mapPoint() + offset );
|
||||
}
|
||||
|
||||
// make sure the temporary feature rubber band is not visible
|
||||
@ -762,67 +810,117 @@ void QgsNodeTool2::startDraggingMoveVertex( const QgsPoint &mapPoint, const QgsP
|
||||
// start dragging of snapped point of current layer
|
||||
mDraggingVertex.reset( new Vertex( m.layer(), m.featureId(), m.vertexIndex() ) );
|
||||
mDraggingVertexType = MovingVertex;
|
||||
mDraggingTopo.clear();
|
||||
mDraggingExtraVertices.clear();
|
||||
mDraggingExtraVerticesOffset.clear();
|
||||
|
||||
int v0idx, v1idx;
|
||||
geom.adjacentVertices( m.vertexIndex(), v0idx, v1idx );
|
||||
if ( v0idx != -1 )
|
||||
{
|
||||
QgsPoint layerPoint0 = geom.vertexAt( v0idx );
|
||||
QgsPoint mapPoint0 = toMapCoordinates( m.layer(), layerPoint0 );
|
||||
addDragBand( mapPoint0, m.point() );
|
||||
}
|
||||
if ( v1idx != -1 )
|
||||
{
|
||||
QgsPoint layerPoint1 = geom.vertexAt( v1idx );
|
||||
QgsPoint mapPoint1 = toMapCoordinates( m.layer(), layerPoint1 );
|
||||
addDragBand( mapPoint1, m.point() );
|
||||
}
|
||||
setHighlightedNodesVisible( false ); // hide any extra highlight of vertices until we are done with moving
|
||||
|
||||
if ( v0idx == -1 && v1idx == -1 )
|
||||
QgsPoint origDraggingVertexPoint = geom.vertexAt( mDraggingVertex->vertexId );
|
||||
|
||||
// if there are other highlighted nodes, they should be dragged as well with their offset
|
||||
Q_FOREACH ( const Vertex &v, mSelectedNodes )
|
||||
{
|
||||
// this is a standalone point - we need to use a marker for it
|
||||
// to give some feedback to the user
|
||||
mDragPointMarker->setCenter( mapPoint );
|
||||
mDragPointMarker->setVisible( true );
|
||||
if ( v != *mDraggingVertex )
|
||||
{
|
||||
// TODO: convert offset to destination layer's CRS
|
||||
QgsPoint origPointV = cachedGeometryForVertex( v ).vertexAt( v.vertexId );
|
||||
QgsVector offset( origPointV.x() - origDraggingVertexPoint.x(), origPointV.y() - origDraggingVertexPoint.y() );
|
||||
|
||||
mDraggingExtraVertices << v;
|
||||
mDraggingExtraVerticesOffset << offset;
|
||||
}
|
||||
}
|
||||
|
||||
mOverrideCadPoints.clear();
|
||||
mOverrideCadPoints << m.point() << m.point();
|
||||
|
||||
if ( !QgsProject::instance()->topologicalEditing() )
|
||||
return; // we are done now
|
||||
|
||||
// support for topo editing - find extra features
|
||||
Q_FOREACH ( QgsMapLayer *layer, canvas()->layers() )
|
||||
if ( QgsProject::instance()->topologicalEditing() )
|
||||
{
|
||||
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
|
||||
if ( !vlayer || !vlayer->isEditable() )
|
||||
continue;
|
||||
|
||||
Q_FOREACH ( const QgsPointLocator::Match &otherMatch, layerVerticesSnappedToPoint( vlayer, mapPoint ) )
|
||||
// support for topo editing - find extra features
|
||||
// that have coincident point with the vertex being dragged
|
||||
Q_FOREACH ( QgsMapLayer *layer, canvas()->layers() )
|
||||
{
|
||||
if ( otherMatch == m )
|
||||
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
|
||||
if ( !vlayer || !vlayer->isEditable() )
|
||||
continue;
|
||||
|
||||
QgsGeometry otherGeom = cachedGeometry( otherMatch.layer(), otherMatch.featureId() );
|
||||
|
||||
// start dragging of snapped point of current layer
|
||||
mDraggingTopo << Vertex( otherMatch.layer(), otherMatch.featureId(), otherMatch.vertexIndex() );
|
||||
|
||||
otherGeom.adjacentVertices( otherMatch.vertexIndex(), v0idx, v1idx );
|
||||
if ( v0idx != -1 )
|
||||
Q_FOREACH ( const QgsPointLocator::Match &otherMatch, layerVerticesSnappedToPoint( vlayer, mapPoint ) )
|
||||
{
|
||||
QgsPoint otherPoint0 = otherGeom.vertexAt( v0idx );
|
||||
QgsPoint otherMapPoint0 = toMapCoordinates( otherMatch.layer(), otherPoint0 );
|
||||
addDragBand( otherMapPoint0, otherMatch.point() );
|
||||
if ( otherMatch.layer() == m.layer() &&
|
||||
otherMatch.featureId() == m.featureId() &&
|
||||
otherMatch.vertexIndex() == m.vertexIndex() )
|
||||
continue;
|
||||
|
||||
// start dragging of snapped point of current layer
|
||||
mDraggingExtraVertices << Vertex( otherMatch.layer(), otherMatch.featureId(), otherMatch.vertexIndex() );
|
||||
mDraggingExtraVerticesOffset << QgsVector(); // topo vertices have the same position
|
||||
}
|
||||
if ( v1idx != -1 )
|
||||
}
|
||||
}
|
||||
|
||||
// now build drag rubber bands for extra vertices
|
||||
|
||||
QSet<Vertex> movingVertices;
|
||||
movingVertices << *mDraggingVertex;
|
||||
Q_FOREACH ( const Vertex &v, mDraggingExtraVertices )
|
||||
movingVertices << v;
|
||||
|
||||
QgsPoint dragVertexMapPoint = m.point();
|
||||
|
||||
Q_FOREACH ( const Vertex &v, movingVertices )
|
||||
{
|
||||
int v0idx, v1idx;
|
||||
QgsGeometry geom = cachedGeometry( v.layer, v.fid );
|
||||
QgsPoint pt = geom.vertexAt( v.vertexId );
|
||||
geom.adjacentVertices( v.vertexId, v0idx, v1idx );
|
||||
if ( v0idx != -1 )
|
||||
{
|
||||
Vertex v0( v.layer, v.fid, v0idx );
|
||||
QgsPoint otherPoint0 = geom.vertexAt( v0idx );
|
||||
QgsPoint otherMapPoint0 = toMapCoordinates( v.layer, otherPoint0 );
|
||||
if ( !movingVertices.contains( v0 ) )
|
||||
{
|
||||
QgsPoint otherPoint1 = otherGeom.vertexAt( v1idx );
|
||||
QgsPoint otherMapPoint1 = toMapCoordinates( otherMatch.layer(), otherPoint1 );
|
||||
addDragBand( otherMapPoint1, otherMatch.point() );
|
||||
// rubber band that is fixed on one side and moving with mouse cursor on the other
|
||||
addDragBand( otherMapPoint0, pt, pt - dragVertexMapPoint );
|
||||
}
|
||||
else
|
||||
{
|
||||
// rubber band that has both endpoints moving with mouse cursor
|
||||
if ( v0idx > v.vertexId )
|
||||
addDragMiddleBand( otherMapPoint0, pt, otherMapPoint0 - dragVertexMapPoint, pt - dragVertexMapPoint );
|
||||
}
|
||||
}
|
||||
if ( v1idx != -1 )
|
||||
{
|
||||
Vertex v1( v.layer, v.fid, v1idx );
|
||||
QgsPoint otherPoint1 = geom.vertexAt( v1idx );
|
||||
QgsPoint otherMapPoint1 = toMapCoordinates( v.layer, otherPoint1 );
|
||||
if ( !movingVertices.contains( v1 ) )
|
||||
{
|
||||
// rubber band that is fixed on one side and moving with mouse cursor on the other
|
||||
addDragBand( otherMapPoint1, pt, pt - dragVertexMapPoint );
|
||||
}
|
||||
else
|
||||
{
|
||||
// rubber band that has both endpoints moving with mouse cursor
|
||||
if ( v1idx > v.vertexId )
|
||||
addDragMiddleBand( otherMapPoint1, pt, otherMapPoint1 - dragVertexMapPoint, pt - dragVertexMapPoint );
|
||||
}
|
||||
}
|
||||
|
||||
if ( v0idx == -1 && v1idx == -1 )
|
||||
{
|
||||
// this is a standalone point - we need to use a marker for it
|
||||
// to give some feedback to the user
|
||||
|
||||
QgsVertexMarker *marker = new QgsVertexMarker( mCanvas );
|
||||
marker->setIconType( QgsVertexMarker::ICON_X );
|
||||
marker->setColor( Qt::red );
|
||||
marker->setPenWidth( 3 );
|
||||
marker->setVisible( true );
|
||||
marker->setCenter( toMapCoordinates( v.layer, pt ) );
|
||||
mDragPointMarkers << marker;
|
||||
mDragPointMarkersOffset << ( pt - dragVertexMapPoint );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -844,7 +942,8 @@ void QgsNodeTool2::startDraggingAddVertex( const QgsPointLocator::Match &m )
|
||||
|
||||
mDraggingVertex.reset( new Vertex( m.layer(), m.featureId(), m.vertexIndex() + 1 ) );
|
||||
mDraggingVertexType = AddingVertex;
|
||||
mDraggingTopo.clear();
|
||||
mDraggingExtraVertices.clear();
|
||||
mDraggingExtraVerticesOffset.clear();
|
||||
|
||||
QgsGeometry geom = cachedGeometry( m.layer(), m.featureId() );
|
||||
|
||||
@ -873,7 +972,8 @@ void QgsNodeTool2::startDraggingAddVertexAtEndpoint( const QgsPoint &mapPoint )
|
||||
|
||||
mDraggingVertex.reset( new Vertex( mMouseAtEndpoint->layer, mMouseAtEndpoint->fid, mMouseAtEndpoint->vertexId ) );
|
||||
mDraggingVertexType = AddingEndpoint;
|
||||
mDraggingTopo.clear();
|
||||
mDraggingExtraVertices.clear();
|
||||
mDraggingExtraVerticesOffset.clear();
|
||||
|
||||
QgsGeometry geom = cachedGeometry( mMouseAtEndpoint->layer, mMouseAtEndpoint->fid );
|
||||
QgsPoint v0 = geom.vertexAt( mMouseAtEndpoint->vertexId );
|
||||
@ -896,7 +996,8 @@ void QgsNodeTool2::startDraggingEdge( const QgsPointLocator::Match &m, const Qgs
|
||||
setMode( CaptureLine );
|
||||
|
||||
mDraggingEdge.reset( new Edge( m.layer(), m.featureId(), m.vertexIndex(), mapPoint ) );
|
||||
mDraggingTopo.clear();
|
||||
mDraggingExtraVertices.clear();
|
||||
mDraggingExtraVerticesOffset.clear();
|
||||
|
||||
QgsPoint edge_p0, edge_p1;
|
||||
m.edgePoints( edge_p0, edge_p1 );
|
||||
@ -946,6 +1047,8 @@ void QgsNodeTool2::stopDragging()
|
||||
mDraggingVertexType = NotDragging;
|
||||
mDraggingEdge.reset();
|
||||
clearDragBands();
|
||||
|
||||
setHighlightedNodesVisible( true ); // highlight can be shown again
|
||||
}
|
||||
|
||||
QgsPoint QgsNodeTool2::matchToLayerPoint( const QgsVectorLayer *destLayer, const QgsPoint &mapPoint, const QgsPointLocator::Match *match )
|
||||
@ -1048,9 +1151,13 @@ void QgsNodeTool2::moveVertex( const QgsPoint &mapPoint, const QgsPointLocator::
|
||||
QHash<QgsVectorLayer *, QHash<QgsFeatureId, QgsGeometry> > edits; // dict { layer : { fid : geom } }
|
||||
edits[dragLayer][dragFid] = geom;
|
||||
|
||||
Q_ASSERT( mDraggingExtraVertices.count() == mDraggingExtraVerticesOffset.count() );
|
||||
// add moved vertices from other layers
|
||||
Q_FOREACH ( const Vertex &topo, mDraggingTopo )
|
||||
for ( int i = 0; i < mDraggingExtraVertices.count(); ++i )
|
||||
{
|
||||
const Vertex &topo = mDraggingExtraVertices[i];
|
||||
const QgsVector &offset = mDraggingExtraVerticesOffset[i];
|
||||
|
||||
QHash<QgsFeatureId, QgsGeometry> &layerEdits = edits[topo.layer];
|
||||
QgsGeometry topoGeom;
|
||||
if ( layerEdits.contains( topo.fid ) )
|
||||
@ -1064,6 +1171,11 @@ void QgsNodeTool2::moveVertex( const QgsPoint &mapPoint, const QgsPointLocator::
|
||||
else
|
||||
point = toLayerCoordinates( topo.layer, mapPoint );
|
||||
|
||||
if ( offset.x() || offset.y() )
|
||||
{
|
||||
point += offset;
|
||||
}
|
||||
|
||||
if ( !topoGeom.moveVertex( point.x(), point.y(), topo.vertexId ) )
|
||||
{
|
||||
QgsDebugMsg( "[topo] move vertex failed!" );
|
||||
@ -1089,6 +1201,9 @@ void QgsNodeTool2::moveVertex( const QgsPoint &mapPoint, const QgsPointLocator::
|
||||
layer->endEditCommand();
|
||||
layer->triggerRepaint();
|
||||
}
|
||||
|
||||
setHighlightedNodes( mSelectedNodes ); // update positions of existing highlighted nodes
|
||||
setHighlightedNodesVisible( true ); // time to show highlighted nodes again
|
||||
}
|
||||
|
||||
void QgsNodeTool2::deleteVertex()
|
||||
@ -1102,7 +1217,7 @@ void QgsNodeTool2::deleteVertex()
|
||||
{
|
||||
bool addingVertex = mDraggingVertexType == AddingVertex || mDraggingVertexType == AddingEndpoint;
|
||||
toDelete << *mDraggingVertex;
|
||||
toDelete += mDraggingTopo;
|
||||
toDelete += mDraggingExtraVertices;
|
||||
stopDragging();
|
||||
|
||||
if ( addingVertex )
|
||||
@ -1199,6 +1314,12 @@ void QgsNodeTool2::setHighlightedNodes( const QList<Vertex> &listNodes )
|
||||
mSelectedNodes = listNodes;
|
||||
}
|
||||
|
||||
void QgsNodeTool2::setHighlightedNodesVisible( bool visible )
|
||||
{
|
||||
Q_FOREACH ( QgsVertexMarker *marker, mSelectedNodesMarkers )
|
||||
marker->setVisible( visible );
|
||||
}
|
||||
|
||||
void QgsNodeTool2::highlightAdjacentVertex( double offset )
|
||||
{
|
||||
if ( mSelectedNodes.isEmpty() )
|
||||
|
@ -34,11 +34,22 @@ struct Vertex
|
||||
, fid( fid )
|
||||
, vertexId( vertexId ) {}
|
||||
|
||||
bool operator==( const Vertex &other ) const
|
||||
{
|
||||
return layer == other.layer && fid == other.fid && vertexId == other.vertexId;
|
||||
}
|
||||
bool operator!=( const Vertex &other ) const
|
||||
{
|
||||
return !operator==( other );
|
||||
}
|
||||
|
||||
QgsVectorLayer *layer;
|
||||
QgsFeatureId fid;
|
||||
int vertexId;
|
||||
};
|
||||
|
||||
//! qHash implementation - we use Vertex in QSet
|
||||
uint qHash( const Vertex &v );
|
||||
|
||||
//! helper structure for an edge being dragged
|
||||
struct Edge
|
||||
@ -97,7 +108,9 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
|
||||
|
||||
private:
|
||||
|
||||
void addDragBand( const QgsPoint &v1, const QgsPoint &v2 );
|
||||
void addDragBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset = QgsVector() );
|
||||
|
||||
void addDragMiddleBand( const QgsPoint &v1, const QgsPoint &v2, const QgsVector &offset1, const QgsVector &offset2 );
|
||||
|
||||
void clearDragBands();
|
||||
|
||||
@ -150,6 +163,8 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
|
||||
|
||||
void setHighlightedNodes( const QList<Vertex> &listNodes );
|
||||
|
||||
void setHighlightedNodesVisible( bool visible );
|
||||
|
||||
//! Allow moving back and forth selected vertex within a feature
|
||||
void highlightAdjacentVertex( double offset );
|
||||
|
||||
@ -198,20 +213,38 @@ class APP_EXPORT QgsNodeTool2 : public QgsMapToolAdvancedDigitizing
|
||||
AddingEndpoint,
|
||||
};
|
||||
|
||||
//! marker for a point used only for moving standalone point geoetry
|
||||
//! (there are no adjacent vertices so mDragBands is empty in that case)
|
||||
QgsVertexMarker *mDragPointMarker = nullptr;
|
||||
//! list of QgsRubberBand instances used when dragging
|
||||
//! markers for points used only for moving standalone point geoetry
|
||||
//! (there are no adjacent vertices so it is not used in mDragBands)
|
||||
QList<QgsVertexMarker *> mDragPointMarkers;
|
||||
//! companion array to mDragPointMarkers: for each marker it keeps offset
|
||||
//! (in map units) from the position of the main vertex
|
||||
QList<QgsVector> mDragPointMarkersOffset;
|
||||
//! list of QgsRubberBand instances used when dragging. All rubber bands
|
||||
//! have two points: first point is fixed, the other one is moved as mouse moves
|
||||
QList<QgsRubberBand *> mDragBands;
|
||||
//! companion array to mDragBands: for each rubber band it keeps offset of the second
|
||||
//! point (in map units) from the position of the main vertex (mDraggingVertex)
|
||||
QList<QgsVector> mDragBandsOffset;
|
||||
//! list of QgsRubberBand instances used when dragging multiple vertices - these rubber bands
|
||||
//! compared to mDragBands have both points moving together with mouse cursor
|
||||
QList<QgsRubberBand *> mDragMiddleBands;
|
||||
//! companion array to mDragMiddleBands: for each rubber band it keeps offset of both
|
||||
//! first and second point (in map units) from the position of the main vertex (mDraggingVertex)
|
||||
QList< QPair<QgsVector, QgsVector> > mDragMiddleBandsOffset;
|
||||
//! instance of Vertex that is being currently moved or nothing
|
||||
std::unique_ptr<Vertex> mDraggingVertex;
|
||||
//! whether moving a vertex or adding one
|
||||
DraggingVertexType mDraggingVertexType = NotDragging;
|
||||
//! instance of Edge that is being currently moved or nothing
|
||||
std::unique_ptr<Edge> mDraggingEdge;
|
||||
//! list of Vertex instances of other vertices that are topologically
|
||||
//! connected to the vertex being currently dragged
|
||||
QList<Vertex> mDraggingTopo;
|
||||
//! list of Vertex instances of further vertices that are dragged together with
|
||||
//! the main vertex (mDraggingVertex) - either topologically connected points
|
||||
//! (if topo editing is allowed) or the ones coming from the highlight
|
||||
QList<Vertex> mDraggingExtraVertices;
|
||||
//! companion array to mDraggingExtraVertices: for each vertex in mDraggingExtraVertices
|
||||
//! this is offset (in units of the layer) of the vertex from the position of the main
|
||||
//! vertex (mDraggingVertex)
|
||||
QList<QgsVector> mDraggingExtraVerticesOffset;
|
||||
|
||||
// members for selection handling
|
||||
|
||||
|
@ -60,6 +60,7 @@ class TestQgsNodeTool : public QObject
|
||||
void testAddVertex();
|
||||
void testAddVertexAtEndpoint();
|
||||
void testDeleteVertex();
|
||||
void testMoveMultipleVertices();
|
||||
|
||||
private:
|
||||
QPoint mapToScreen( double mapX, double mapY )
|
||||
@ -451,5 +452,25 @@ void TestQgsNodeTool::testDeleteVertex()
|
||||
QCOMPARE( mLayerPoint->undoStack()->index(), 1 );
|
||||
}
|
||||
|
||||
void TestQgsNodeTool::testMoveMultipleVertices()
|
||||
{
|
||||
// select two vertices
|
||||
mousePress( 0.5, 0.5, Qt::LeftButton );
|
||||
mouseMove( 1.5, 3.5 );
|
||||
mouseRelease( 1.5, 3.5, Qt::LeftButton );
|
||||
|
||||
// move them by -1,-1
|
||||
mouseClick( 1, 1, Qt::LeftButton );
|
||||
mouseClick( 0, 0, Qt::LeftButton );
|
||||
|
||||
QCOMPARE( mLayerLine->undoStack()->index(), 2 );
|
||||
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 0 0, 0 2)" ) );
|
||||
|
||||
mLayerLine->undoStack()->undo();
|
||||
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
|
||||
|
||||
QCOMPARE( mLayerLine->getFeature( mFidLineF1 ).geometry(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 3)" ) );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsNodeTool )
|
||||
#include "testqgsnodetool.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user