Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Improvements to the right-click behavior to pick locked feature
- unlock feature on right-click in an empty area
- allow selection of locked feature by right-click on polygon interior
  (in addition to polygon rings)
- highlight polygons when mouse moves in their interior - this should also
  decrease the blinking effect as the highlight is more consistent
  • Loading branch information
wonder-sk committed Feb 1, 2019
1 parent 39887e7 commit cfa40ed
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/app/vertextool/qgsvertextool.cpp
Expand Up @@ -460,10 +460,25 @@ void QgsVertexTool::cadCanvasPressEvent( QgsMapMouseEvent *e )
if ( !mSelectionRect && !mDraggingVertex && !mDraggingEdge )
{
QgsPointLocator::Match m = snapToEditableLayer( e );
if ( !m.isValid() )
{
// as the last resort check if we are on top of a feature if there is no vertex or edge snap
m = snapToPolygonInterior( e );
}

if ( m.isValid() && m.layer() )
{
updateVertexEditor( m.layer(), m.featureId() );
}
else
{
// there's really nothing under the cursor - let's deselect any feature we may have
mSelectedFeature.reset();
if ( mVertexEditor )
{
mVertexEditor->updateEditor( nullptr );
}
}
}
}
}
Expand Down Expand Up @@ -779,6 +794,61 @@ QgsPointLocator::Match QgsVertexTool::snapToEditableLayer( QgsMapMouseEvent *e )
return m;
}


QgsPointLocator::Match QgsVertexTool::snapToPolygonInterior( QgsMapMouseEvent *e )
{
QgsSnappingUtils *snapUtils = canvas()->snappingUtils();
QgsPointLocator::Match m;

QgsPointXY mapPoint = toMapCoordinates( e->pos() );

// if there is a current layer, it should have priority over other layers
// because sometimes there may be match from multiple layers at one location
// and selecting current layer is an easy way for the user to prioritize a layer
if ( QgsVectorLayer *currentVlayer = currentVectorLayer() )
{
if ( currentVlayer->isEditable() && currentVlayer->geometryType() == QgsWkbTypes::PolygonGeometry )
{
QgsPointLocator::MatchList matchList = snapUtils->locatorForLayer( currentVlayer )->pointInPolygon( mapPoint );
if ( !matchList.isEmpty() )
{
m = matchList.first();
}
}
}

// if there is no match from the current layer, try to use any editable vector layer
if ( !m.isValid() && mMode == AllLayers )
{
const auto layers = canvas()->layers();
for ( QgsMapLayer *layer : layers )
{
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
if ( !vlayer )
continue;

if ( vlayer->isEditable() && vlayer->geometryType() == QgsWkbTypes::PolygonGeometry )
{
QgsPointLocator::MatchList matchList = snapUtils->locatorForLayer( vlayer )->pointInPolygon( mapPoint );
if ( !matchList.isEmpty() )
{
m = matchList.first();
break;
}
}
}
}

// if we don't have anything in the last snap, keep the area match
if ( !mLastSnap && m.isValid() )
{
mLastSnap.reset( new QgsPointLocator::Match( m ) );
}

return m;
}


bool QgsVertexTool::isNearEndpointMarker( const QgsPointXY &mapPoint )
{
if ( !mEndpointMarkerCenter )
Expand Down Expand Up @@ -931,6 +1001,12 @@ void QgsVertexTool::mouseMoveNotDragging( QgsMapMouseEvent *e )
mEdgeBand->setVisible( false );
}

if ( !m.isValid() )
{
// as the last resort check if we are on top of a feature if there is no vertex or edge snap
m = snapToPolygonInterior( e );
}

updateFeatureBand( m );
}

Expand Down
2 changes: 2 additions & 0 deletions src/app/vertextool/qgsvertextool.h
Expand Up @@ -146,6 +146,8 @@ class APP_EXPORT QgsVertexTool : public QgsMapToolAdvancedDigitizing
*/
QgsPointLocator::Match snapToEditableLayer( QgsMapMouseEvent *e );

QgsPointLocator::Match snapToPolygonInterior( QgsMapMouseEvent *e );

//! check whether we are still close to the mEndpointMarker
bool isNearEndpointMarker( const QgsPointXY &mapPoint );

Expand Down

0 comments on commit cfa40ed

Please sign in to comment.