Skip to content

Commit 1192b63

Browse files
authored
Merge pull request #7892 from PeterPetrik/identify_by_feature
[feature] Identify/Select polygon from existing feature geometry (#19064)
2 parents 6058e66 + 1d22006 commit 1192b63

7 files changed

+53
-7
lines changed

python/gui/auto_generated/qgsidentifymenu.sip.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ define if the menu executed can return multiple results (e.g. all results or all
6464

6565
void setExecWithSingleResult( bool execWithSingleResult );
6666
%Docstring
67-
define if the menu will be shown with a single idetify result
67+
define if the menu will be shown with a single identify result
6868
%End
6969
bool execWithSingleResult();
7070

src/app/qgsmaptoolselect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***************************************************************************
2-
qgsmaptoolselect.cpp - map tool for selecting features by single click
2+
qgsmaptoolselect.cpp - map tool for selecting features
33
----------------------
44
begin : January 2006
55
copyright : (C) 2006 by Martin Dobias

src/app/qgsmaptoolselect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***************************************************************************
2-
qgsmaptoolselect.h - map tool for selecting features by single click
2+
qgsmaptoolselect.h - map tool for selecting features
33
---------------------
44
begin : May 2010
55
copyright : (C) 2010 by Jeremy Palmer

src/app/qgsmaptoolselectionhandler.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "qgsmapmouseevent.h"
2626
#include "qgsrubberband.h"
2727
#include "qgssnapindicator.h"
28-
28+
#include "qgsidentifymenu.h"
2929

3030
/// @cond private
3131

@@ -101,7 +101,10 @@ QgsMapToolSelectionHandler::QgsMapToolSelectionHandler( QgsMapCanvas *canvas, Qg
101101
: mCanvas( canvas )
102102
, mSelectionMode( selectionMode )
103103
, mSnapIndicator( qgis::make_unique< QgsSnapIndicator >( canvas ) )
104+
, mIdentifyMenu( new QgsIdentifyMenu( mCanvas ) )
104105
{
106+
mIdentifyMenu->setAllowMultipleReturn( false );
107+
mIdentifyMenu->setExecWithSingleResult( true );
105108
}
106109

107110
QgsMapToolSelectionHandler::~QgsMapToolSelectionHandler()
@@ -243,6 +246,44 @@ void QgsMapToolSelectionHandler::selectPolygonMoveEvent( QgsMapMouseEvent *e )
243246

244247
void QgsMapToolSelectionHandler::selectPolygonPressEvent( QgsMapMouseEvent *e )
245248
{
249+
// Handle immediate right-click on feature to show context menu
250+
if ( !mSelectionRubberBand && ( e->button() == Qt::RightButton ) )
251+
{
252+
QList<QgsMapToolIdentify::IdentifyResult> results;
253+
QMap< QString, QString > derivedAttributes;
254+
255+
const QgsPointXY mapPoint = toMapCoordinates( e->pos() );
256+
double x = mapPoint.x(), y = mapPoint.y();
257+
double sr = QgsMapTool::searchRadiusMU( mCanvas );
258+
259+
const QList<QgsMapLayer *> layers = mCanvas->layers();
260+
for ( auto layer : layers )
261+
{
262+
if ( layer->type() == QgsMapLayer::VectorLayer )
263+
{
264+
auto vectorLayer = static_cast<QgsVectorLayer *>( layer );
265+
if ( vectorLayer->geometryType() == QgsWkbTypes::PolygonGeometry )
266+
{
267+
QgsRectangle r = mCanvas->mapSettings().mapToLayerCoordinates( layer, QgsRectangle( x - sr, y - sr, x + sr, y + sr ) );
268+
QgsFeatureIterator fit = vectorLayer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) );
269+
QgsFeature f;
270+
while ( fit.nextFeature( f ) )
271+
{
272+
results << QgsMapToolIdentify::IdentifyResult( vectorLayer, f, derivedAttributes );
273+
}
274+
}
275+
}
276+
}
277+
278+
QPoint globalPos = mCanvas->mapToGlobal( QPoint( e->pos().x() + 5, e->pos().y() + 5 ) );
279+
const QList<QgsMapToolIdentify::IdentifyResult> selectedFeatures = mIdentifyMenu->exec( results, globalPos );
280+
if ( !selectedFeatures.empty() && selectedFeatures[0].mFeature.hasGeometry() )
281+
setSelectedGeometry( selectedFeatures[0].mFeature.geometry(), e->modifiers() );
282+
283+
return;
284+
}
285+
286+
// Handle definition of polygon by clicking points on cancas
246287
if ( !mSelectionRubberBand )
247288
initRubberBand();
248289

src/app/qgsmaptoolselectionhandler.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class QgsMapCanvas;
2929
class QgsMapMouseEvent;
3030
class QgsRubberBand;
3131
class QgsSnapIndicator;
32+
class QgsIdentifyMenu;
3233

3334
/// @cond private
3435

@@ -88,7 +89,7 @@ class QgsMapToolSelectionHandler : public QObject
8889
{
8990
//! SelectSimple - single click or drawing a rectangle, default option
9091
SelectSimple,
91-
//! SelectPolygon - drawing a polygon
92+
//! SelectPolygon - drawing a polygon or right-click on existing polygon feature
9293
SelectPolygon,
9394
//! SelectFreehand - free hand selection
9495
SelectFreehand,
@@ -119,7 +120,7 @@ class QgsMapToolSelectionHandler : public QObject
119120
void canvasMoveEvent( QgsMapMouseEvent *e );
120121
//! Handles mouse press event from map tool
121122
void canvasPressEvent( QgsMapMouseEvent *e );
122-
//! Handles mouse releasae event from map tool
123+
//! Handles mouse release event from map tool
123124
void canvasReleaseEvent( QgsMapMouseEvent *e );
124125
//! Handles escape press event - returns true if the even has been processed
125126
bool keyReleaseEvent( QKeyEvent *e );
@@ -196,6 +197,9 @@ class QgsMapToolSelectionHandler : public QObject
196197

197198
QColor mFillColor = QColor( 254, 178, 76, 63 );
198199
QColor mStrokeColor = QColor( 254, 58, 29, 100 );
200+
201+
//! Shows features to select polygon from existing features
202+
QgsIdentifyMenu *mIdentifyMenu = nullptr; // owned by canvas
199203
};
200204

201205
#endif

src/gui/qgsidentifymenu.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "qgssettings.h"
2727
#include "qgsgui.h"
2828

29+
//TODO 4.0 add explicitly qobject parent to constructor
2930
QgsIdentifyMenu::QgsIdentifyMenu( QgsMapCanvas *canvas )
3031
: QMenu( canvas )
3132
, mCanvas( canvas )

src/gui/qgsidentifymenu.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ class GUI_EXPORT QgsIdentifyMenu : public QMenu
9999
void setAllowMultipleReturn( bool multipleReturn ) { mAllowMultipleReturn = multipleReturn;}
100100
bool allowMultipleReturn() { return mAllowMultipleReturn;}
101101

102-
//! define if the menu will be shown with a single idetify result
102+
//! define if the menu will be shown with a single identify result
103103
void setExecWithSingleResult( bool execWithSingleResult ) { mExecWithSingleResult = execWithSingleResult;}
104104
bool execWithSingleResult() { return mExecWithSingleResult;}
105105

0 commit comments

Comments
 (0)