18
18
#include " qgsadvanceddigitizingdockwidget.h"
19
19
#include " qgscurve.h"
20
20
#include " qgscurvepolygon.h"
21
+ #include " qgsgeometryutils.h"
21
22
#include " qgslogger.h"
22
23
#include " qgsmapcanvas.h"
23
24
#include " qgsmulticurve.h"
@@ -236,6 +237,24 @@ void QgsNodeTool2::addDragMiddleBand( const QgsPoint &v1, const QgsPoint &v2, co
236
237
mDragMiddleBandsOffset << qMakePair ( offset1, offset2 );
237
238
}
238
239
240
+ void QgsNodeTool2::addDragCircularBand ( const QgsPoint &v0, const QgsPoint &v1, const QgsPoint &v2, bool moving0, bool moving1, bool moving2, const QgsPoint &mapPoint )
241
+ {
242
+ CircularBand b;
243
+ b.band = createRubberBand ( QgsWkbTypes::LineGeometry, true );
244
+ b.p0 = v0;
245
+ b.p1 = v1;
246
+ b.p2 = v2;
247
+ b.moving0 = moving0;
248
+ b.moving1 = moving1;
249
+ b.moving2 = moving2;
250
+ b.offset0 = v0 - mapPoint;
251
+ b.offset1 = v1 - mapPoint;
252
+ b.offset2 = v2 - mapPoint;
253
+ b.updateRubberBand ( mapPoint );
254
+
255
+ mDragCircularBands << b;
256
+ }
257
+
239
258
void QgsNodeTool2::clearDragBands ()
240
259
{
241
260
qDeleteAll ( mDragBands );
@@ -249,6 +268,10 @@ void QgsNodeTool2::clearDragBands()
249
268
qDeleteAll ( mDragPointMarkers );
250
269
mDragPointMarkers .clear ();
251
270
mDragPointMarkersOffset .clear ();
271
+
272
+ Q_FOREACH ( const CircularBand &b, mDragCircularBands )
273
+ delete b.band ;
274
+ mDragCircularBands .clear ();
252
275
}
253
276
254
277
void QgsNodeTool2::cadCanvasPressEvent ( QgsMapMouseEvent *e )
@@ -445,6 +468,12 @@ void QgsNodeTool2::mouseMoveDraggingVertex( QgsMapMouseEvent *e )
445
468
band->movePoint ( 1 , e->mapPoint () + offset.second );
446
469
}
447
470
471
+ for ( int i = 0 ; i < mDragCircularBands .count (); ++i )
472
+ {
473
+ CircularBand &b = mDragCircularBands [i];
474
+ b.updateRubberBand ( e->mapPoint () );
475
+ }
476
+
448
477
// in case of moving of standalone point geometry
449
478
for ( int i = 0 ; i < mDragPointMarkers .count (); ++i )
450
479
{
@@ -867,44 +896,117 @@ void QgsNodeTool2::startDraggingMoveVertex( const QgsPoint &mapPoint, const QgsP
867
896
868
897
QgsPoint dragVertexMapPoint = m.point ();
869
898
899
+ // set of middle vertices that are already in a circular rubber band
900
+ // i.e. every circular band is defined by its middle circular vertex
901
+ QSet<Vertex> verticesInCircularBands;
902
+
870
903
Q_FOREACH ( const Vertex &v, movingVertices )
871
904
{
872
905
int v0idx, v1idx;
873
906
QgsGeometry geom = cachedGeometry ( v.layer , v.fid );
874
907
QgsPoint pt = geom.vertexAt ( v.vertexId );
908
+
875
909
geom.adjacentVertices ( v.vertexId , v0idx, v1idx );
910
+
911
+ QgsVertexId vid;
912
+ if ( v0idx != -1 && v1idx != -1 && geom.vertexIdFromVertexNr ( v.vertexId , vid ) && vid.type == QgsVertexId::CurveVertex )
913
+ {
914
+ // the vertex is in the middle of a curved segment
915
+ qDebug ( " middle point curve vertex" );
916
+ if ( !verticesInCircularBands.contains ( v ) )
917
+ {
918
+ addDragCircularBand ( geom.vertexAt ( v0idx ),
919
+ pt,
920
+ geom.vertexAt ( v1idx ),
921
+ movingVertices.contains ( Vertex ( v.layer , v.fid , v0idx ) ),
922
+ true ,
923
+ movingVertices.contains ( Vertex ( v.layer , v.fid , v1idx ) ),
924
+ dragVertexMapPoint );
925
+ verticesInCircularBands << v;
926
+ }
927
+
928
+ // skip the rest - no need for further straight of circular bands for this vertex
929
+ // because our circular rubber band spans both towards left and right
930
+ continue ;
931
+ }
932
+
876
933
if ( v0idx != -1 )
877
934
{
878
- Vertex v0 ( v.layer , v.fid , v0idx );
879
- QgsPoint otherPoint0 = geom.vertexAt ( v0idx );
880
- QgsPoint otherMapPoint0 = toMapCoordinates ( v.layer , otherPoint0 );
881
- if ( !movingVertices.contains ( v0 ) )
935
+ // there is another vertex to the left - let's build a rubber band for it
936
+ QgsVertexId v0id;
937
+ if ( geom.vertexIdFromVertexNr ( v0idx, v0id ) && v0id.type == QgsVertexId::CurveVertex )
882
938
{
883
- // rubber band that is fixed on one side and moving with mouse cursor on the other
884
- addDragBand ( otherMapPoint0, pt, pt - dragVertexMapPoint );
939
+ // circular segment to the left
940
+ Vertex v0 ( v.layer , v.fid , v0idx );
941
+ if ( !verticesInCircularBands.contains ( v0 ) )
942
+ {
943
+ addDragCircularBand ( geom.vertexAt ( v0idx - 1 ),
944
+ geom.vertexAt ( v0idx ),
945
+ pt,
946
+ movingVertices.contains ( Vertex ( v.layer , v.fid , v0idx - 1 ) ),
947
+ movingVertices.contains ( Vertex ( v.layer , v.fid , v0idx ) ),
948
+ true ,
949
+ dragVertexMapPoint );
950
+ verticesInCircularBands << v0;
951
+ }
885
952
}
886
953
else
887
954
{
888
- // rubber band that has both endpoints moving with mouse cursor
889
- if ( v0idx > v.vertexId )
890
- addDragMiddleBand ( otherMapPoint0, pt, otherMapPoint0 - dragVertexMapPoint, pt - dragVertexMapPoint );
955
+ // straight segment to the left
956
+ Vertex v0 ( v.layer , v.fid , v0idx );
957
+ QgsPoint otherPoint0 = geom.vertexAt ( v0idx );
958
+ QgsPoint otherMapPoint0 = toMapCoordinates ( v.layer , otherPoint0 );
959
+ if ( !movingVertices.contains ( v0 ) )
960
+ {
961
+ // rubber band that is fixed on one side and moving with mouse cursor on the other
962
+ addDragBand ( otherMapPoint0, pt, pt - dragVertexMapPoint );
963
+ }
964
+ else
965
+ {
966
+ // rubber band that has both endpoints moving with mouse cursor
967
+ if ( v0idx > v.vertexId )
968
+ addDragMiddleBand ( otherMapPoint0, pt, otherMapPoint0 - dragVertexMapPoint, pt - dragVertexMapPoint );
969
+ }
891
970
}
892
971
}
972
+
893
973
if ( v1idx != -1 )
894
974
{
895
- Vertex v1 ( v.layer , v.fid , v1idx );
896
- QgsPoint otherPoint1 = geom.vertexAt ( v1idx );
897
- QgsPoint otherMapPoint1 = toMapCoordinates ( v.layer , otherPoint1 );
898
- if ( !movingVertices.contains ( v1 ) )
975
+ // there is another vertex to the right - let's build a rubber band for it
976
+ QgsVertexId v1id;
977
+ if ( geom.vertexIdFromVertexNr ( v1idx, v1id ) && v1id.type == QgsVertexId::CurveVertex )
899
978
{
900
- // rubber band that is fixed on one side and moving with mouse cursor on the other
901
- addDragBand ( otherMapPoint1, pt, pt - dragVertexMapPoint );
979
+ // circular segment to the right
980
+ Vertex v1 ( v.layer , v.fid , v1idx );
981
+ if ( !verticesInCircularBands.contains ( v1 ) )
982
+ {
983
+ addDragCircularBand ( pt,
984
+ geom.vertexAt ( v1idx ),
985
+ geom.vertexAt ( v1idx + 1 ),
986
+ true ,
987
+ movingVertices.contains ( Vertex ( v.layer , v.fid , v1idx ) ),
988
+ movingVertices.contains ( Vertex ( v.layer , v.fid , v1idx + 1 ) ),
989
+ dragVertexMapPoint );
990
+ verticesInCircularBands << v1;
991
+ }
902
992
}
903
993
else
904
994
{
905
- // rubber band that has both endpoints moving with mouse cursor
906
- if ( v1idx > v.vertexId )
907
- addDragMiddleBand ( otherMapPoint1, pt, otherMapPoint1 - dragVertexMapPoint, pt - dragVertexMapPoint );
995
+ // straight segment to the right
996
+ Vertex v1 ( v.layer , v.fid , v1idx );
997
+ QgsPoint otherPoint1 = geom.vertexAt ( v1idx );
998
+ QgsPoint otherMapPoint1 = toMapCoordinates ( v.layer , otherPoint1 );
999
+ if ( !movingVertices.contains ( v1 ) )
1000
+ {
1001
+ // rubber band that is fixed on one side and moving with mouse cursor on the other
1002
+ addDragBand ( otherMapPoint1, pt, pt - dragVertexMapPoint );
1003
+ }
1004
+ else
1005
+ {
1006
+ // rubber band that has both endpoints moving with mouse cursor
1007
+ if ( v1idx > v.vertexId )
1008
+ addDragMiddleBand ( otherMapPoint1, pt, otherMapPoint1 - dragVertexMapPoint, pt - dragVertexMapPoint );
1009
+ }
908
1010
}
909
1011
}
910
1012
@@ -1385,3 +1487,16 @@ bool QgsNodeTool2::matchEdgeCenterTest( const QgsPointLocator::Match &m, const Q
1385
1487
bool isNearCenter = distFromEdgeCenter < tol;
1386
1488
return isNearCenter;
1387
1489
}
1490
+
1491
+ void QgsNodeTool2::CircularBand::updateRubberBand ( const QgsPoint &mapPoint )
1492
+ {
1493
+ QgsPointSequence points;
1494
+ QgsPoint v0 = moving0 ? mapPoint + offset0 : p0;
1495
+ QgsPoint v1 = moving1 ? mapPoint + offset1 : p1;
1496
+ QgsPoint v2 = moving2 ? mapPoint + offset2 : p2;
1497
+ QgsGeometryUtils::segmentizeArc ( QgsPointV2 ( v0 ), QgsPointV2 ( v1 ), QgsPointV2 ( v2 ), points );
1498
+ // it would be useful to have QgsRubberBand::setPoints() call
1499
+ band->reset ();
1500
+ Q_FOREACH ( const QgsPointV2 &p, points )
1501
+ band->addPoint ( p );
1502
+ }
0 commit comments