@@ -463,10 +463,25 @@ void QgsVertexTool::cadCanvasPressEvent( QgsMapMouseEvent *e )
463
463
if ( !mSelectionRect && !mDraggingVertex && !mDraggingEdge )
464
464
{
465
465
QgsPointLocator::Match m = snapToEditableLayer ( e );
466
+ if ( !m.isValid () )
467
+ {
468
+ // as the last resort check if we are on top of a feature if there is no vertex or edge snap
469
+ m = snapToPolygonInterior ( e );
470
+ }
471
+
466
472
if ( m.isValid () && m.layer () )
467
473
{
468
474
updateVertexEditor ( m.layer (), m.featureId () );
469
475
}
476
+ else
477
+ {
478
+ // there's really nothing under the cursor - let's deselect any feature we may have
479
+ mSelectedFeature .reset ();
480
+ if ( mVertexEditor )
481
+ {
482
+ mVertexEditor ->updateEditor ( nullptr );
483
+ }
484
+ }
470
485
}
471
486
}
472
487
}
@@ -782,6 +797,61 @@ QgsPointLocator::Match QgsVertexTool::snapToEditableLayer( QgsMapMouseEvent *e )
782
797
return m;
783
798
}
784
799
800
+
801
+ QgsPointLocator::Match QgsVertexTool::snapToPolygonInterior ( QgsMapMouseEvent *e )
802
+ {
803
+ QgsSnappingUtils *snapUtils = canvas ()->snappingUtils ();
804
+ QgsPointLocator::Match m;
805
+
806
+ QgsPointXY mapPoint = toMapCoordinates ( e->pos () );
807
+
808
+ // if there is a current layer, it should have priority over other layers
809
+ // because sometimes there may be match from multiple layers at one location
810
+ // and selecting current layer is an easy way for the user to prioritize a layer
811
+ if ( QgsVectorLayer *currentVlayer = currentVectorLayer () )
812
+ {
813
+ if ( currentVlayer->isEditable () && currentVlayer->geometryType () == QgsWkbTypes::PolygonGeometry )
814
+ {
815
+ QgsPointLocator::MatchList matchList = snapUtils->locatorForLayer ( currentVlayer )->pointInPolygon ( mapPoint );
816
+ if ( !matchList.isEmpty () )
817
+ {
818
+ m = matchList.first ();
819
+ }
820
+ }
821
+ }
822
+
823
+ // if there is no match from the current layer, try to use any editable vector layer
824
+ if ( !m.isValid () && mMode == AllLayers )
825
+ {
826
+ const auto layers = canvas ()->layers ();
827
+ for ( QgsMapLayer *layer : layers )
828
+ {
829
+ QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
830
+ if ( !vlayer )
831
+ continue ;
832
+
833
+ if ( vlayer->isEditable () && vlayer->geometryType () == QgsWkbTypes::PolygonGeometry )
834
+ {
835
+ QgsPointLocator::MatchList matchList = snapUtils->locatorForLayer ( vlayer )->pointInPolygon ( mapPoint );
836
+ if ( !matchList.isEmpty () )
837
+ {
838
+ m = matchList.first ();
839
+ break ;
840
+ }
841
+ }
842
+ }
843
+ }
844
+
845
+ // if we don't have anything in the last snap, keep the area match
846
+ if ( !mLastSnap && m.isValid () )
847
+ {
848
+ mLastSnap .reset ( new QgsPointLocator::Match ( m ) );
849
+ }
850
+
851
+ return m;
852
+ }
853
+
854
+
785
855
bool QgsVertexTool::isNearEndpointMarker ( const QgsPointXY &mapPoint )
786
856
{
787
857
if ( !mEndpointMarkerCenter )
@@ -934,6 +1004,12 @@ void QgsVertexTool::mouseMoveNotDragging( QgsMapMouseEvent *e )
934
1004
mEdgeBand ->setVisible ( false );
935
1005
}
936
1006
1007
+ if ( !m.isValid () )
1008
+ {
1009
+ // as the last resort check if we are on top of a feature if there is no vertex or edge snap
1010
+ m = snapToPolygonInterior ( e );
1011
+ }
1012
+
937
1013
updateFeatureBand ( m );
938
1014
}
939
1015
0 commit comments