Skip to content

Commit 29fa6f2

Browse files
author
jef
committedAug 12, 2010
add advanced selection tools from Jeremy Palmer. Thanks. (apply #2938)
git-svn-id: http://svn.osgeo.org/qgis/trunk@14071 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 2843a93 commit 29fa6f2

31 files changed

+1350
-156
lines changed
 

‎images/images.qrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@
194194
<file>themes/default/mActionSaveMapAsImage.png</file>
195195
<file>themes/default/mActionScaleBar.png</file>
196196
<file>themes/default/mActionSelect.png</file>
197+
<file>themes/default/mActionSelectRectangle.png</file>
198+
<file>themes/default/mActionSelectFreehand.png</file>
199+
<file>themes/default/mActionSelectPolygon.png</file>
200+
<file>themes/default/mActionSelectRadius.png</file>
197201
<file>themes/default/mActionSelectedToTop.png</file>
198202
<file>themes/default/mActionSelectPan.png</file>
199203
<file>themes/default/mActionShowAllLayers.png</file>
224 Bytes
Loading
302 Bytes
Loading
2.01 KB
Loading
1.93 KB
Loading
1.92 KB
Loading
1.84 KB
Loading

‎images/themes/default/selectTools.svg

Lines changed: 220 additions & 0 deletions
Loading

‎python/gui/qgisinterface.sip

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,10 @@ class QgisInterface : QObject
193193
virtual QAction *actionZoomIn() = 0;
194194
virtual QAction *actionZoomOut() = 0;
195195
virtual QAction *actionSelect() = 0;
196+
virtual QAction *actionSelectRectangle() = 0;
197+
virtual QAction *actionSelectPolygon() = 0;
198+
virtual QAction *actionSelectFreehand() = 0;
199+
virtual QAction *actionSelectRadius() = 0;
196200
virtual QAction *actionIdentify() = 0;
197201
virtual QAction *actionMeasure() = 0;
198202
virtual QAction *actionMeasureArea() = 0;

‎python/gui/qgsrubberband.sip

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ class QgsRubberBand: QgsMapCanvasItem
5757

5858
/**Return vertex*/
5959
const QgsPoint *getPoint(int i, int j=0) const;
60+
61+
/**Returns the rubberband as a Geometry.
62+
* added in 1.6 */
63+
QgsGeometry* asGeometry();
6064

6165
protected:
6266
virtual void paint(QPainter* p);

‎src/app/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ SET(QGIS_APP_SRCS
4949
qgsmaptoolreshape.cpp
5050
qgsmaptoolrotatepointsymbols.cpp
5151
qgsmaptoolselect.cpp
52+
qgsmaptoolselectrectangle.cpp
53+
qgsmaptoolselectfreehand.cpp
54+
qgsmaptoolselectpolygon.cpp
55+
qgsmaptoolselectradius.cpp
56+
qgsmaptoolselectutils.cpp
5257
qgsmaptoolsimplify.cpp
5358
qgsmaptoolsplitfeatures.cpp
5459
qgsmaptooltextannotation.cpp
@@ -163,6 +168,10 @@ SET (QGIS_APP_MOC_HDRS
163168
qgsmaptoolreshape.h
164169
qgsmaptoolrotatepointsymbols.h
165170
qgsmaptoolselect.h
171+
qgsmaptoolselectrectangle.h
172+
qgsmaptoolselectfreehand.h
173+
qgsmaptoolselectpolygon.h
174+
qgsmaptoolselectradius.h
166175
qgsmaptooladdvertex.h
167176
qgsmaptooldeletering.h
168177
qgsmaptooldeletepart.h

‎src/app/qgisapp.cpp

Lines changed: 108 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@
201201
#include "qgsmaptoolnodetool.h"
202202
#include "qgsmaptoolpan.h"
203203
#include "qgsmaptoolselect.h"
204+
#include "qgsmaptoolselectrectangle.h"
205+
#include "qgsmaptoolselectfreehand.h"
206+
#include "qgsmaptoolselectpolygon.h"
207+
#include "qgsmaptoolselectradius.h"
204208
#include "qgsmaptoolreshape.h"
205209
#include "qgsmaptoolrotatepointsymbols.h"
206210
#include "qgsmaptoolsplitfeatures.h"
@@ -559,6 +563,10 @@ QgisApp::~QgisApp()
559563
delete mMapTools.mReshapeFeatures;
560564
delete mMapTools.mSplitFeatures;
561565
delete mMapTools.mSelect;
566+
delete mMapTools.mSelectRectangle;
567+
delete mMapTools.mSelectPolygon;
568+
delete mMapTools.mSelectFreehand;
569+
delete mMapTools.mSelectRadius;
562570

563571
#if 0 //these three tools to be deprecated - use node tool rather
564572
delete mMapTools.mVertexAdd;
@@ -877,6 +885,30 @@ void QgisApp::createActions()
877885
connect( mActionSelect, SIGNAL( triggered() ), this, SLOT( select() ) );
878886
mActionSelect->setEnabled( false );
879887

888+
mActionSelectRectangle = new QAction( getThemeIcon( "mActionSelectRectangle.png" ), tr( "Select features by rectangle" ), this );
889+
shortcuts->registerAction( mActionSelectRectangle );
890+
mActionSelectRectangle->setStatusTip( tr( "Select features by rectangle" ) );
891+
connect( mActionSelectRectangle, SIGNAL( triggered() ), this, SLOT( selectByRectangle() ) );
892+
mActionSelectRectangle->setEnabled( false );
893+
894+
mActionSelectPolygon = new QAction( getThemeIcon( "mActionSelectPolygon.png" ), tr( "Select features by polygon" ), this );
895+
shortcuts->registerAction( mActionSelectPolygon );
896+
mActionSelectPolygon->setStatusTip( tr( "Select features by polygon" ) );
897+
connect( mActionSelectPolygon, SIGNAL( triggered() ), this, SLOT( selectByPolygon() ) );
898+
mActionSelectPolygon->setEnabled( false );
899+
900+
mActionSelectFreehand = new QAction( getThemeIcon( "mActionSelectFreehand.png" ), tr( "Select features by freehand" ), this );
901+
shortcuts->registerAction( mActionSelectFreehand );
902+
mActionSelectFreehand->setStatusTip( tr( "Select features by freehand" ) );
903+
connect( mActionSelectFreehand, SIGNAL( triggered() ), this, SLOT( selectByFreehand() ) );
904+
mActionSelectFreehand->setEnabled( false );
905+
906+
mActionSelectRadius = new QAction( getThemeIcon( "mActionSelectRadius.png" ), tr( "Select features by radius" ), this );
907+
shortcuts->registerAction( mActionSelectRadius );
908+
mActionSelectRadius->setStatusTip( tr( "Select features by radius" ) );
909+
connect( mActionSelectRadius, SIGNAL( triggered() ), this, SLOT( selectByRadius() ) );
910+
mActionSelectRadius->setEnabled( false );
911+
880912
mActionDeselectAll = new QAction( getThemeIcon( "mActionDeselectAll.png" ), tr( "Deselect features from all layers" ), this );
881913
shortcuts->registerAction( mActionDeselectAll );
882914
mActionDeselectAll->setStatusTip( tr( "Deselect features from all layers" ) );
@@ -1254,6 +1286,14 @@ void QgisApp::createActionGroups()
12541286
mMapToolGroup->addAction( mActionIdentify );
12551287
mActionSelect->setCheckable( true );
12561288
mMapToolGroup->addAction( mActionSelect );
1289+
mActionSelectRectangle->setCheckable( true );
1290+
mMapToolGroup->addAction( mActionSelectRectangle );
1291+
mActionSelectPolygon->setCheckable( true );
1292+
mMapToolGroup->addAction( mActionSelectPolygon );
1293+
mActionSelectFreehand->setCheckable( true );
1294+
mMapToolGroup->addAction( mActionSelectFreehand );
1295+
mActionSelectRadius->setCheckable( true );
1296+
mMapToolGroup->addAction( mActionSelectRadius );
12571297
mActionDeselectAll->setCheckable( false );
12581298
mMapToolGroup->addAction( mActionDeselectAll );
12591299
mActionMeasure->setCheckable( true );
@@ -1419,21 +1459,27 @@ void QgisApp::createMenus()
14191459
mViewMenu->addAction( mActionPan );
14201460
mViewMenu->addAction( mActionZoomIn );
14211461
mViewMenu->addAction( mActionZoomOut );
1462+
mActionViewSeparator1 = mViewMenu->addSeparator();
14221463
mViewMenu->addAction( mActionSelect );
1464+
mViewMenu->addAction( mActionSelectRectangle );
1465+
mViewMenu->addAction( mActionSelectPolygon );
1466+
mViewMenu->addAction( mActionSelectFreehand );
1467+
mViewMenu->addAction( mActionSelectRadius );
14231468
mViewMenu->addAction( mActionDeselectAll );
1469+
mActionViewSeparator2 = mViewMenu->addSeparator();
14241470
mViewMenu->addAction( mActionIdentify );
14251471
mViewMenu->addAction( mActionMeasure );
14261472
mViewMenu->addAction( mActionMeasureArea );
14271473
mViewMenu->addAction( mActionMeasureAngle );
1428-
mActionViewSeparator1 = mViewMenu->addSeparator();
1474+
mActionViewSeparator3 = mViewMenu->addSeparator();
14291475

14301476
mViewMenu->addAction( mActionZoomFullExtent );
14311477
mViewMenu->addAction( mActionZoomToLayer );
14321478
mViewMenu->addAction( mActionZoomToSelected );
14331479
mViewMenu->addAction( mActionZoomLast );
14341480
mViewMenu->addAction( mActionZoomNext );
14351481
mViewMenu->addAction( mActionZoomActualSize );
1436-
mActionViewSeparator2 = mViewMenu->addSeparator();
1482+
mActionViewSeparator4 = mViewMenu->addSeparator();
14371483

14381484
mViewMenu->addAction( mActionMapTips );
14391485
mViewMenu->addAction( mActionNewBookmark );
@@ -1442,7 +1488,7 @@ void QgisApp::createMenus()
14421488

14431489
if ( layout != QDialogButtonBox::KdeLayout )
14441490
{
1445-
mActionViewSeparator3 = mViewMenu->addSeparator();
1491+
mActionViewSeparator5 = mViewMenu->addSeparator();
14461492
mViewMenu->addMenu( mPanelMenu );
14471493
mViewMenu->addMenu( mToolbarMenu );
14481494
mViewMenu->addAction( mActionToggleFullScreen );
@@ -1650,14 +1696,25 @@ void QgisApp::createToolBars()
16501696
mMapNavToolBar->addAction( mActionZoomNext );
16511697
mMapNavToolBar->addAction( mActionDraw );
16521698
mToolbarMenu->addAction( mMapNavToolBar->toggleViewAction() );
1699+
1700+
//
1701+
// Feature Select Toolbar
1702+
mFeatureSelectToolBar = addToolBar( tr( "Select Tools" ) );
1703+
mFeatureSelectToolBar->setIconSize( myIconSize );
1704+
mFeatureSelectToolBar->setObjectName( "Select Tools" );
1705+
mFeatureSelectToolBar->addAction( mActionIdentify );
1706+
mFeatureSelectToolBar->addAction( mActionSelect );
1707+
mFeatureSelectToolBar->addAction( mActionSelectRectangle );
1708+
mFeatureSelectToolBar->addAction( mActionSelectPolygon );
1709+
mFeatureSelectToolBar->addAction( mActionSelectFreehand );
1710+
mFeatureSelectToolBar->addAction( mActionSelectRadius );
1711+
mFeatureSelectToolBar->addAction( mActionDeselectAll );
1712+
16531713
//
16541714
// Attributes Toolbar
16551715
mAttributesToolBar = addToolBar( tr( "Attributes" ) );
16561716
mAttributesToolBar->setIconSize( myIconSize );
16571717
mAttributesToolBar->setObjectName( "Attributes" );
1658-
mAttributesToolBar->addAction( mActionIdentify );
1659-
mAttributesToolBar->addAction( mActionSelect );
1660-
mAttributesToolBar->addAction( mActionDeselectAll );
16611718
mAttributesToolBar->addAction( mActionOpenTable );
16621719
mAttributesToolBar->addAction( mActionMeasure );
16631720
mAttributesToolBar->addAction( mActionMeasureArea );
@@ -1918,6 +1975,10 @@ void QgisApp::setTheme( QString theThemeName )
19181975
mActionZoomToLayer->setIcon( getThemeIcon( "/mActionZoomToLayer.png" ) );
19191976
mActionIdentify->setIcon( getThemeIcon( "/mActionIdentify.png" ) );
19201977
mActionSelect->setIcon( getThemeIcon( "/mActionSelect.png" ) );
1978+
mActionSelectRectangle->setIcon( getThemeIcon( "/mActionSelectRectangle.png" ) );
1979+
mActionSelectPolygon->setIcon( getThemeIcon( "/mActionSelectPolygon.png" ) );
1980+
mActionSelectFreehand->setIcon( getThemeIcon( "/mActionSelectFreehand.png" ) );
1981+
mActionSelectRadius->setIcon( getThemeIcon( "/mActionSelectRadius.png" ) );
19211982
mActionDeselectAll->setIcon( getThemeIcon( "/mActionDeselectAll.png" ) );
19221983
mActionOpenTable->setIcon( getThemeIcon( "/mActionOpenTable.png" ) );
19231984
mActionMeasure->setIcon( getThemeIcon( "/mActionMeasure.png" ) );
@@ -2058,6 +2119,15 @@ void QgisApp::createCanvasTools()
20582119
mMapTools.mSplitFeatures->setAction( mActionSplitFeatures );
20592120
mMapTools.mSelect = new QgsMapToolSelect( mMapCanvas );
20602121
mMapTools.mSelect->setAction( mActionSelect );
2122+
mMapTools.mSelectRectangle = new QgsMapToolSelectRectangle( mMapCanvas );
2123+
mMapTools.mSelectRectangle->setAction( mActionSelectRectangle );
2124+
mMapTools.mSelectPolygon = new QgsMapToolSelectPolygon( mMapCanvas );
2125+
mMapTools.mSelectPolygon->setAction( mActionSelectPolygon );
2126+
mMapTools.mSelectFreehand = new QgsMapToolSelectFreehand( mMapCanvas );
2127+
mMapTools.mSelectFreehand->setAction( mActionSelectFreehand );
2128+
mMapTools.mSelectRadius = new QgsMapToolSelectRadius( mMapCanvas );
2129+
mMapTools.mSelectRadius->setAction( mActionSelectRadius );
2130+
20612131
#if 0 //these three tools to be deprecated - use node tool rather
20622132
mMapTools.mVertexAdd = new QgsMapToolAddVertex( mMapCanvas );
20632133
mMapTools.mVertexAdd->setAction( mActionAddVertex );
@@ -4399,6 +4469,26 @@ void QgisApp::select()
43994469
mMapCanvas->setMapTool( mMapTools.mSelect );
44004470
}
44014471

4472+
void QgisApp::selectByRectangle()
4473+
{
4474+
mMapCanvas->setMapTool( mMapTools.mSelectRectangle );
4475+
}
4476+
4477+
void QgisApp::selectByPolygon()
4478+
{
4479+
mMapCanvas->setMapTool( mMapTools.mSelectPolygon );
4480+
}
4481+
4482+
void QgisApp::selectByFreehand()
4483+
{
4484+
mMapCanvas->setMapTool( mMapTools.mSelectFreehand );
4485+
}
4486+
4487+
void QgisApp::selectByRadius()
4488+
{
4489+
mMapCanvas->setMapTool( mMapTools.mSelectRadius );
4490+
}
4491+
44024492
void QgisApp::deselectAll()
44034493
{
44044494
if ( !mMapCanvas || mMapCanvas->isDrawing() )
@@ -5793,6 +5883,10 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
57935883
if ( !layer )
57945884
{
57955885
mActionSelect->setEnabled( false );
5886+
mActionSelectRectangle->setEnabled( false );
5887+
mActionSelectPolygon->setEnabled( false );
5888+
mActionSelectFreehand->setEnabled( false );
5889+
mActionSelectRadius->setEnabled( false );
57965890
mActionIdentify->setEnabled( QSettings().value( "/Map/identifyMode", 0 ).toInt() != 0 );
57975891
mActionZoomActualSize->setEnabled( false );
57985892
mActionOpenTable->setEnabled( false );
@@ -5846,6 +5940,10 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
58465940
bool layerHasSelection = vlayer->selectedFeatureCount() != 0;
58475941

58485942
mActionSelect->setEnabled( true );
5943+
mActionSelectRectangle->setEnabled( true );
5944+
mActionSelectPolygon->setEnabled( true );
5945+
mActionSelectFreehand->setEnabled( true );
5946+
mActionSelectRadius->setEnabled( true );
58495947
mActionIdentify->setEnabled( true );
58505948
mActionZoomActualSize->setEnabled( false );
58515949
mActionOpenTable->setEnabled( true );
@@ -6065,6 +6163,10 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
60656163
{
60666164
mActionLayerSubsetString->setEnabled( false );
60676165
mActionSelect->setEnabled( false );
6166+
mActionSelectRectangle->setEnabled( false );
6167+
mActionSelectPolygon->setEnabled( false );
6168+
mActionSelectFreehand->setEnabled( false );
6169+
mActionSelectRadius->setEnabled( false );
60686170
mActionZoomActualSize->setEnabled( true );
60696171
mActionOpenTable->setEnabled( false );
60706172
mActionToggleEditing->setEnabled( false );

‎src/app/qgisapp.h

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ class QgisApp : public QMainWindow
249249
QAction *actionZoomIn() { return mActionZoomIn; }
250250
QAction *actionZoomOut() { return mActionZoomOut; }
251251
QAction *actionSelect() { return mActionSelect; }
252+
QAction *actionSelectRectangle() { return mActionSelectRectangle; }
253+
QAction *actionSelectPolygon() { return mActionSelectPolygon; }
254+
QAction *actionSelectFreehand() { return mActionSelectFreehand; }
255+
QAction *actionSelectRadius() { return mActionSelectRadius; }
252256
QAction *actionIdentify() { return mActionIdentify; }
253257
QAction *actionMeasure() { return mActionMeasure; }
254258
QAction *actionMeasureArea() { return mActionMeasureArea; }
@@ -611,6 +615,18 @@ class QgisApp : public QMainWindow
611615
//! activates the selection tool
612616
void select();
613617

618+
//! activates the rectangle selection tool
619+
void selectByRectangle();
620+
621+
//! activates the polygon selection tool
622+
void selectByPolygon();
623+
624+
//! activates the freehand selection tool
625+
void selectByFreehand();
626+
627+
//! activates the radius selection tool
628+
void selectByRadius();
629+
614630
//! deselect features from all layers
615631
void deselectAll();
616632

@@ -828,6 +844,7 @@ class QgisApp : public QMainWindow
828844
QToolBar *mDigitizeToolBar;
829845
QToolBar *mAdvancedDigitizeToolBar;
830846
QToolBar *mAttributesToolBar;
847+
QToolBar *mFeatureSelectToolBar;
831848
QToolBar *mPluginToolBar;
832849
QToolBar *mHelpToolBar;
833850

@@ -880,25 +897,31 @@ class QgisApp : public QMainWindow
880897
QAction *mActionPan;
881898
QAction *mActionZoomIn;
882899
QAction *mActionZoomOut;
900+
QAction *mActionViewSeparator1;
883901
QAction *mActionSelect;
902+
QAction *mActionSelectRectangle;
903+
QAction *mActionSelectPolygon;
904+
QAction *mActionSelectFreehand;
905+
QAction *mActionSelectRadius;
884906
QAction *mActionDeselectAll;
907+
QAction *mActionViewSeparator2;
885908
QAction *mActionIdentify;
886909
QAction *mActionMeasure;
887910
QAction *mActionMeasureAngle;
888911
QAction *mActionMeasureArea;
889-
QAction *mActionViewSeparator1;
912+
QAction *mActionViewSeparator3;
890913
QAction *mActionZoomFullExtent;
891914
QAction *mActionZoomToLayer;
892915
QAction *mActionZoomToSelected;
893916
QAction *mActionZoomLast;
894917
QAction *mActionZoomNext;
895918
QAction *mActionZoomActualSize;
896-
QAction *mActionViewSeparator2;
919+
QAction *mActionViewSeparator4;
897920
QAction *mActionMapTips;
898921
QAction *mActionNewBookmark;
899922
QAction *mActionShowBookmarks;
900923
QAction *mActionDraw;
901-
QAction *mActionViewSeparator3;
924+
QAction *mActionViewSeparator5;
902925
QAction *mActionTextAnnotation;
903926
QAction *mActionFormAnnotation;
904927
QAction *mActionAnnotation;
@@ -1010,6 +1033,10 @@ class QgisApp : public QMainWindow
10101033
QgsMapTool* mReshapeFeatures;
10111034
QgsMapTool* mSplitFeatures;
10121035
QgsMapTool* mSelect;
1036+
QgsMapTool* mSelectRectangle;
1037+
QgsMapTool* mSelectPolygon;
1038+
QgsMapTool* mSelectFreehand;
1039+
QgsMapTool* mSelectRadius;
10131040
QgsMapTool* mVertexAdd;
10141041
QgsMapTool* mVertexMove;
10151042
QgsMapTool* mVertexDelete;

‎src/app/qgisappinterface.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,10 @@ QAction *QgisAppInterface::actionPan() { return qgis->actionPan(); }
289289
QAction *QgisAppInterface::actionZoomIn() { return qgis->actionZoomIn(); }
290290
QAction *QgisAppInterface::actionZoomOut() { return qgis->actionZoomOut(); }
291291
QAction *QgisAppInterface::actionSelect() { return qgis->actionSelect(); }
292+
QAction *QgisAppInterface::actionSelectRectangle() { return qgis->actionSelectRectangle(); }
293+
QAction *QgisAppInterface::actionSelectPolygon() { return qgis->actionSelectPolygon(); }
294+
QAction *QgisAppInterface::actionSelectFreehand() { return qgis->actionSelectFreehand(); }
295+
QAction *QgisAppInterface::actionSelectRadius() { return qgis->actionSelectRadius(); }
292296
QAction *QgisAppInterface::actionIdentify() { return qgis->actionIdentify(); }
293297
QAction *QgisAppInterface::actionMeasure() { return qgis->actionMeasure(); }
294298
QAction *QgisAppInterface::actionMeasureArea() { return qgis->actionMeasureArea(); }

‎src/app/qgisappinterface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ class QgisAppInterface : public QgisInterface
198198
virtual QAction *actionZoomIn();
199199
virtual QAction *actionZoomOut();
200200
virtual QAction *actionSelect();
201+
virtual QAction *actionSelectRectangle();
202+
virtual QAction *actionSelectPolygon();
203+
virtual QAction *actionSelectFreehand();
204+
virtual QAction *actionSelectRadius();
201205
virtual QAction *actionIdentify();
202206
virtual QAction *actionMeasure();
203207
virtual QAction *actionMeasureArea();

‎src/app/qgsmaptoolselect.cpp

Lines changed: 20 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/***************************************************************************
2-
qgsmaptoolselect.cpp - map tool for selecting features
2+
qgsmaptoolselect.cpp - map tool for selecting features by single click
33
----------------------
44
begin : January 2006
55
copyright : (C) 2006 by Martin Dobias
@@ -14,142 +14,41 @@
1414
***************************************************************************/
1515
/* $Id$ */
1616

17+
1718
#include "qgsmaptoolselect.h"
19+
#include "qgsmaptoolselectutils.h"
20+
#include "qgsrubberband.h"
1821
#include "qgsmapcanvas.h"
19-
#include "qgsmaptopixel.h"
2022
#include "qgsvectorlayer.h"
21-
#include "qgscsexception.h"
22-
#include "qgscursors.h"
23-
#include "qgslogger.h"
23+
#include "qgsgeometry.h"
24+
#include "qgspoint.h"
2425
#include "qgis.h"
2526

26-
#include <QApplication>
27-
#include <QMessageBox>
2827
#include <QMouseEvent>
29-
#include <QRubberBand>
3028
#include <QRect>
3129

3230

3331
QgsMapToolSelect::QgsMapToolSelect( QgsMapCanvas* canvas )
34-
: QgsMapTool( canvas ), mDragging( false )
35-
{
36-
QPixmap mySelectQPixmap = QPixmap(( const char ** ) select_cursor );
37-
mCursor = QCursor( mySelectQPixmap, 1, 1 );
38-
mRubberBand = 0;
39-
}
40-
41-
42-
void QgsMapToolSelect::canvasPressEvent( QMouseEvent * e )
43-
{
44-
mSelectRect.setRect( 0, 0, 0, 0 );
45-
}
46-
47-
48-
void QgsMapToolSelect::canvasMoveEvent( QMouseEvent * e )
32+
: QgsMapTool( canvas )
4933
{
50-
if ( e->buttons() != Qt::LeftButton )
51-
return;
52-
53-
if ( !mDragging )
54-
{
55-
mDragging = true;
56-
mRubberBand = new QRubberBand( QRubberBand::Rectangle, mCanvas );
57-
mSelectRect.setTopLeft( e->pos() );
58-
}
59-
60-
mSelectRect.setBottomRight( e->pos() );
61-
mRubberBand->setGeometry( mSelectRect.normalized() );
62-
mRubberBand->show();
34+
mCursor = Qt::ArrowCursor;
6335
}
6436

65-
6637
void QgsMapToolSelect::canvasReleaseEvent( QMouseEvent * e )
6738
{
68-
if ( !mCanvas->currentLayer() ||
69-
qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ) == NULL )
39+
QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( mCanvas );
40+
if ( vlayer == NULL )
7041
{
71-
QMessageBox::warning( mCanvas, tr( "No active layer" ),
72-
tr( "To select features, you must choose a "
73-
"vector layer by clicking on its name in the legend"
74-
) );
7542
return;
7643
}
77-
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
78-
//if the user simply clicked without dragging a rect
79-
//we will fabricate a small 1x1 pix rect and then continue
80-
//as if they had dragged a rect
81-
if ( !mDragging )
82-
{
83-
int boxSize = 0;
84-
if ( vlayer->geometryType() != QGis::Polygon )
85-
{
86-
//if point or line use an artificial bounding box of 10x10 pixels
87-
//to aid the user to click on a feature accurately
88-
boxSize = 5;
89-
}
90-
else
91-
{
92-
//otherwise just use the click point for polys
93-
boxSize = 1;
94-
}
95-
mSelectRect.setLeft( e->pos().x() - boxSize );
96-
mSelectRect.setRight( e->pos().x() + boxSize );
97-
mSelectRect.setTop( e->pos().y() - boxSize );
98-
mSelectRect.setBottom( e->pos().y() + boxSize );
99-
}
100-
else
101-
{
102-
delete mRubberBand;
103-
mRubberBand = 0;
104-
105-
// Set valid values for rectangle's width and height
106-
if ( mSelectRect.width() == 1 )
107-
{
108-
mSelectRect.setLeft( mSelectRect.left() + 1 );
109-
}
110-
if ( mSelectRect.height() == 1 )
111-
{
112-
mSelectRect.setBottom( mSelectRect.bottom() + 1 );
113-
}
114-
}
115-
116-
mDragging = false;
117-
118-
const QgsMapToPixel* transform = mCanvas->getCoordinateTransform();
119-
QgsPoint ll = transform->toMapCoordinates( mSelectRect.left(), mSelectRect.bottom() );
120-
QgsPoint ur = transform->toMapCoordinates( mSelectRect.right(), mSelectRect.top() );
121-
122-
QgsRectangle search( ll.x(), ll.y(), ur.x(), ur.y() );
123-
124-
// if Ctrl key is pressed, selected features will be flipped in selection
125-
// instead of removing old selection
126-
bool flip = ( e->modifiers() & Qt::ControlModifier );
127-
128-
// toLayerCoordinates will throw an exception for an 'invalid' rectangle.
129-
// For example, if you project a world map onto a globe using EPSG 2163
130-
// and then click somewhere off the globe, an exception will be thrown.
131-
try
132-
{
133-
search = toLayerCoordinates( vlayer, search );
134-
}
135-
catch ( QgsCsException &cse )
136-
{
137-
Q_UNUSED( cse );
138-
// catch exception for 'invalid' rectangle and leave existing selection unchanged
139-
QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) );
140-
QMessageBox::warning( mCanvas, tr( "CRS Exception" ),
141-
tr( "Selection extends beyond layer's coordinate system." ) );
142-
return;
143-
}
144-
145-
QApplication::setOverrideCursor( Qt::WaitCursor );
146-
if ( flip )
147-
{
148-
vlayer->invertSelectionInRectangle( search );
149-
}
150-
else
151-
{
152-
vlayer->select( search, false );
153-
}
154-
QApplication::restoreOverrideCursor();
44+
QgsRubberBand rubberBand( mCanvas, true );
45+
QRect selectRect( 0, 0, 0, 0 );
46+
QgsMapToolSelectUtils::expandSelectRectangle( selectRect, vlayer, e->pos() );
47+
QgsMapToolSelectUtils::setRubberBand( mCanvas, selectRect, &rubberBand );
48+
QgsGeometry* selectGeom = rubberBand.asGeometry();
49+
bool addSelection = e->modifiers() & Qt::ControlModifier ? true : false;
50+
bool substractSelection = e->modifiers() & Qt::ShiftModifier ? true : false;
51+
QgsMapToolSelectUtils::setSelectFeatures( mCanvas, selectGeom, false, addSelection, substractSelection, true );
52+
delete selectGeom;
53+
rubberBand.reset( true );
15554
}

‎src/app/qgsmaptoolselect.h

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
/***************************************************************************
2-
qgsmaptoolselect.h - map tool for selecting features
2+
qgsmaptoolselect.h - map tool for selecting features by single click
33
---------------------
4-
begin : January 2006
5-
copyright : (C) 2006 by Martin Dobias
6-
email : wonder.sk at gmail dot com
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
77
***************************************************************************
88
* *
99
* This program is free software; you can redistribute it and/or modify *
@@ -18,39 +18,20 @@
1818
#define QGSMAPTOOLSELECT_H
1919

2020
#include "qgsmaptool.h"
21-
#include <QRect>
2221

23-
24-
class QRubberBand;
2522
class QgsMapCanvas;
26-
23+
class QMouseEvent;
2724

2825
class QgsMapToolSelect : public QgsMapTool
2926
{
3027
Q_OBJECT
3128
public:
3229
QgsMapToolSelect( QgsMapCanvas* canvas );
3330

34-
//! Overridden mouse move event
35-
virtual void canvasMoveEvent( QMouseEvent * e );
36-
37-
//! Overridden mouse press event
38-
virtual void canvasPressEvent( QMouseEvent * e );
39-
4031
//! Overridden mouse release event
4132
virtual void canvasReleaseEvent( QMouseEvent * e );
4233

43-
44-
protected:
45-
46-
//! stores actual select rect
47-
QRect mSelectRect;
48-
49-
//! Flag to indicate a map canvas drag operation is taking place
50-
bool mDragging;
51-
52-
//! rubber band for select rect
53-
QRubberBand* mRubberBand;
34+
private:
5435
};
5536

5637
#endif

‎src/app/qgsmaptoolselectfreehand.cpp

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/***************************************************************************
2+
qgsmaptoolselectfreehand.cpp - map tool for selecting features by freehand
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#include "qgsmaptoolselectfreehand.h"
18+
#include "qgsmaptoolselectutils.h"
19+
#include "qgsgeometry.h"
20+
#include "qgsrubberband.h"
21+
#include "qgsmapcanvas.h"
22+
#include "qgis.h"
23+
24+
#include <QMouseEvent>
25+
26+
27+
QgsMapToolSelectFreehand::QgsMapToolSelectFreehand( QgsMapCanvas* canvas )
28+
: QgsMapTool( canvas )
29+
{
30+
mRubberBand = 0;
31+
mCursor = Qt::ArrowCursor;
32+
}
33+
34+
QgsMapToolSelectFreehand::~QgsMapToolSelectFreehand()
35+
{
36+
delete mRubberBand;
37+
}
38+
39+
void QgsMapToolSelectFreehand::canvasPressEvent( QMouseEvent * e )
40+
{
41+
if ( e->button() != Qt::LeftButton )
42+
{
43+
return;
44+
}
45+
if ( mRubberBand == NULL )
46+
{
47+
mRubberBand = new QgsRubberBand( mCanvas, true );
48+
}
49+
mRubberBand->addPoint( toMapCoordinates( e->pos() ) );
50+
mDragging = true;
51+
}
52+
53+
54+
void QgsMapToolSelectFreehand::canvasMoveEvent( QMouseEvent * e )
55+
{
56+
if ( !mDragging || mRubberBand == NULL )
57+
{
58+
return;
59+
}
60+
mRubberBand->addPoint( toMapCoordinates( e->pos() ) );
61+
}
62+
63+
64+
void QgsMapToolSelectFreehand::canvasReleaseEvent( QMouseEvent * e )
65+
{
66+
if ( mRubberBand == NULL )
67+
{
68+
return;
69+
}
70+
if ( mRubberBand->numberOfVertices() > 2 )
71+
{
72+
QgsGeometry* shapeGeom = mRubberBand->asGeometry();
73+
QgsMapToolSelectUtils::setSelectFeatures( mCanvas, shapeGeom, e );
74+
delete shapeGeom;
75+
}
76+
mRubberBand->reset( true );
77+
delete mRubberBand;
78+
mRubberBand = 0;
79+
mDragging = false;
80+
}

‎src/app/qgsmaptoolselectfreehand.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/***************************************************************************
2+
qgsmaptoolselectfreehand.h - map tool for selecting features by freehand
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#ifndef QGSMAPTOOLSELECTFREEHAND_H
18+
#define QGSMAPTOOLSELECTFREEHAND_H
19+
20+
#include "qgsmaptool.h"
21+
22+
class QgsMapCanvas;
23+
class QgsRubberBand;
24+
25+
26+
class QgsMapToolSelectFreehand : public QgsMapTool
27+
{
28+
Q_OBJECT
29+
public:
30+
QgsMapToolSelectFreehand( QgsMapCanvas* canvas );
31+
32+
virtual ~QgsMapToolSelectFreehand();
33+
34+
//! Overridden mouse move event
35+
virtual void canvasMoveEvent( QMouseEvent * e );
36+
37+
//! Overridden mouse press event
38+
virtual void canvasPressEvent( QMouseEvent * e );
39+
40+
//! Overridden mouse release event
41+
virtual void canvasReleaseEvent( QMouseEvent * e );
42+
43+
private:
44+
45+
//! used for storing all of the maps point for the freehand sketch
46+
QgsRubberBand* mRubberBand;
47+
48+
bool mDragging;
49+
};
50+
51+
#endif

‎src/app/qgsmaptoolselectpolygon.cpp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/***************************************************************************
2+
qgsmaptoolselectpolygon.cpp - map tool for selecting features by polygon
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#include "qgsmaptoolselectpolygon.h"
18+
#include "qgsmaptoolselectutils.h"
19+
#include "qgsgeometry.h"
20+
#include "qgsrubberband.h"
21+
#include "qgsmapcanvas.h"
22+
#include "qgis.h"
23+
24+
#include <QMouseEvent>
25+
26+
27+
QgsMapToolSelectPolygon::QgsMapToolSelectPolygon( QgsMapCanvas* canvas )
28+
: QgsMapTool( canvas )
29+
{
30+
mRubberBand = 0;
31+
mCursor = Qt::ArrowCursor;
32+
}
33+
34+
QgsMapToolSelectPolygon::~QgsMapToolSelectPolygon()
35+
{
36+
delete mRubberBand;
37+
}
38+
39+
void QgsMapToolSelectPolygon::canvasPressEvent( QMouseEvent * e )
40+
{
41+
if ( mRubberBand == NULL )
42+
{
43+
mRubberBand = new QgsRubberBand( mCanvas, true );
44+
}
45+
if ( e->button() == Qt::LeftButton )
46+
{
47+
mRubberBand->addPoint( toMapCoordinates( e->pos() ) );
48+
}
49+
else
50+
{
51+
if ( mRubberBand->numberOfVertices() > 2 )
52+
{
53+
QgsGeometry* polygonGeom = mRubberBand->asGeometry();
54+
QgsMapToolSelectUtils::setSelectFeatures( mCanvas, polygonGeom, e );
55+
delete polygonGeom;
56+
}
57+
mRubberBand->reset( true );
58+
delete mRubberBand;
59+
mRubberBand = 0;
60+
}
61+
}
62+
63+
void QgsMapToolSelectPolygon::canvasMoveEvent( QMouseEvent * e )
64+
{
65+
if ( mRubberBand == NULL )
66+
{
67+
return;
68+
}
69+
if ( mRubberBand->numberOfVertices() > 0 )
70+
{
71+
mRubberBand->removeLastPoint( 0 );
72+
mRubberBand->addPoint( toMapCoordinates( e->pos() ) );
73+
}
74+
}
75+

‎src/app/qgsmaptoolselectpolygon.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/***************************************************************************
2+
qgsmaptoolselectpolygon.h - map tool for selecting features by polygon
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#ifndef QGSMAPTOOLSELECTPOLYGON_H
18+
#define QGSMAPTOOLSELECTPOLYGON_H
19+
20+
#include "qgsmaptool.h"
21+
22+
class QgsMapCanvas;
23+
class QgsRubberBand;
24+
25+
26+
class QgsMapToolSelectPolygon : public QgsMapTool
27+
{
28+
Q_OBJECT
29+
public:
30+
QgsMapToolSelectPolygon( QgsMapCanvas* canvas );
31+
32+
virtual ~QgsMapToolSelectPolygon();
33+
34+
//! Overridden mouse move event
35+
virtual void canvasMoveEvent( QMouseEvent * e );
36+
37+
//! Overridden mouse press event
38+
virtual void canvasPressEvent( QMouseEvent * e );
39+
40+
private:
41+
42+
//! used for storing all of the maps point for the polygon
43+
QgsRubberBand* mRubberBand;
44+
};
45+
46+
#endif

‎src/app/qgsmaptoolselectradius.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/***************************************************************************
2+
qgsmaptoolselectradius.cpp - map tool for selecting features by radius
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#include "qgsmaptoolselectradius.h"
18+
#include "qgsmaptoolselectutils.h"
19+
#include "qgsgeometry.h"
20+
#include "qgsrubberband.h"
21+
#include "qgsmapcanvas.h"
22+
#include "qgis.h"
23+
#include "qgslogger.h"
24+
25+
#include <cmath>
26+
#include <QMouseEvent>
27+
28+
#ifndef M_PI
29+
#define M_PI 3.1415926535897931159979634685
30+
#endif
31+
32+
const int RADIUS_SEGMENTS = 40;
33+
34+
QgsMapToolSelectRadius::QgsMapToolSelectRadius( QgsMapCanvas* canvas )
35+
: QgsMapTool( canvas ), mDragging( false )
36+
{
37+
mRubberBand = 0;
38+
mCursor = Qt::ArrowCursor;
39+
}
40+
41+
QgsMapToolSelectRadius::~QgsMapToolSelectRadius()
42+
{
43+
delete mRubberBand;
44+
}
45+
46+
void QgsMapToolSelectRadius::canvasPressEvent( QMouseEvent * e )
47+
{
48+
if ( e->button() != Qt::LeftButton )
49+
{
50+
return;
51+
}
52+
mRadiusCenter = toMapCoordinates( e->pos() );
53+
}
54+
55+
56+
void QgsMapToolSelectRadius::canvasMoveEvent( QMouseEvent * e )
57+
{
58+
if ( e->buttons() != Qt::LeftButton )
59+
{
60+
return;
61+
}
62+
if ( !mDragging )
63+
{
64+
if ( mRubberBand == NULL )
65+
{
66+
mRubberBand = new QgsRubberBand( mCanvas, true );
67+
}
68+
mDragging = true;
69+
}
70+
QgsPoint radiusEdge = toMapCoordinates( e->pos() );
71+
setRadiusRubberBand( radiusEdge );
72+
}
73+
74+
75+
void QgsMapToolSelectRadius::canvasReleaseEvent( QMouseEvent * e )
76+
{
77+
if ( e->button() != Qt::LeftButton )
78+
{
79+
return;
80+
}
81+
if ( !mDragging )
82+
{
83+
if ( mRubberBand == NULL )
84+
{
85+
mRubberBand = new QgsRubberBand( mCanvas, true );
86+
}
87+
mRadiusCenter = toMapCoordinates( e->pos() );
88+
QgsPoint radiusEdge = toMapCoordinates( QPoint( e->pos().x() + 1, e->pos().y() + 1 ) );
89+
setRadiusRubberBand( radiusEdge );
90+
}
91+
QgsGeometry* radiusGeometry = mRubberBand->asGeometry();
92+
QgsMapToolSelectUtils::setSelectFeatures( mCanvas, radiusGeometry, e );
93+
delete radiusGeometry;
94+
mRubberBand->reset( true );
95+
delete mRubberBand;
96+
mRubberBand = 0;
97+
mDragging = false;
98+
}
99+
100+
101+
void QgsMapToolSelectRadius::setRadiusRubberBand( QgsPoint & radiusEdge )
102+
{
103+
double r = sqrt( mRadiusCenter.sqrDist( radiusEdge ) );
104+
mRubberBand->reset( true );
105+
for ( int i = 0; i <= RADIUS_SEGMENTS; ++i )
106+
{
107+
double theta = i * ( 2.0 * M_PI / RADIUS_SEGMENTS );
108+
QgsPoint radiusPoint( mRadiusCenter.x() + r * cos( theta ),
109+
mRadiusCenter.y() + r * sin( theta ) );
110+
mRubberBand->addPoint( radiusPoint );
111+
}
112+
}

‎src/app/qgsmaptoolselectradius.h

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/***************************************************************************
2+
qgsmaptoolselectradius.h - map tool for selecting features by radius
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#ifndef QGSMAPTOOLSELECTRADIUS_H
18+
#define QGSMAPTOOLSELECTRADIUS_H
19+
20+
21+
#include "qgsmaptool.h"
22+
#include "qgspoint.h"
23+
24+
class QgsMapCanvas;
25+
class QgsRubberBand;
26+
27+
28+
class QgsMapToolSelectRadius : public QgsMapTool
29+
{
30+
Q_OBJECT
31+
public:
32+
QgsMapToolSelectRadius( QgsMapCanvas* canvas );
33+
34+
virtual ~QgsMapToolSelectRadius();
35+
36+
//! Overridden mouse move event
37+
virtual void canvasMoveEvent( QMouseEvent * e );
38+
39+
//! Overridden mouse press event
40+
virtual void canvasPressEvent( QMouseEvent * e );
41+
42+
//! Overridden mouse release event
43+
virtual void canvasReleaseEvent( QMouseEvent * e );
44+
45+
private:
46+
47+
//! sets the rubber band to a circle approximated using 40 segments.
48+
// The radius center point is defined in the canvasPressEvent event.
49+
void setRadiusRubberBand( QgsPoint & radiusEdge );
50+
51+
//! used for storing all of the maps point for the polygon
52+
QgsRubberBand* mRubberBand;
53+
54+
//! Center point for the radius
55+
QgsPoint mRadiusCenter;
56+
57+
bool mDragging;
58+
};
59+
60+
#endif

‎src/app/qgsmaptoolselectrectangle.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/***************************************************************************
2+
qgsmaptoolselectrectangle.cpp - map tool for selecting features by
3+
rectangle
4+
----------------------
5+
begin : January 2006
6+
copyright : (C) 2006 by Martin Dobias
7+
email : wonder.sk at gmail dot com
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
/* $Id: qgsmaptoolselectrangle.cpp 13380 2010-04-25 12:51:49Z jef $ */
17+
18+
#include "qgsmaptoolselectrectangle.h"
19+
#include "qgsmaptoolselectutils.h"
20+
#include "qgsrubberband.h"
21+
#include "qgsmapcanvas.h"
22+
#include "qgsmaptopixel.h"
23+
#include "qgsvectorlayer.h"
24+
#include "qgscursors.h"
25+
#include "qgsgeometry.h"
26+
#include "qgspoint.h"
27+
#include "qgis.h"
28+
29+
#include <QMouseEvent>
30+
#include <QRect>
31+
32+
33+
QgsMapToolSelectRectangle::QgsMapToolSelectRectangle( QgsMapCanvas* canvas )
34+
: QgsMapTool( canvas ), mDragging( false )
35+
{
36+
QPixmap mySelectQPixmap = QPixmap(( const char ** ) select_cursor );
37+
mCursor = QCursor( mySelectQPixmap, 1, 1 );
38+
mRubberBand = 0;
39+
}
40+
41+
42+
void QgsMapToolSelectRectangle::canvasPressEvent( QMouseEvent * e )
43+
{
44+
mSelectRect.setRect( 0, 0, 0, 0 );
45+
mRubberBand = new QgsRubberBand( mCanvas, true );
46+
}
47+
48+
49+
void QgsMapToolSelectRectangle::canvasMoveEvent( QMouseEvent * e )
50+
{
51+
if ( e->buttons() != Qt::LeftButton )
52+
return;
53+
54+
if ( !mDragging )
55+
{
56+
mDragging = true;
57+
mSelectRect.setTopLeft( e->pos() );
58+
}
59+
mSelectRect.setBottomRight( e->pos() );
60+
QgsMapToolSelectUtils::setRubberBand( mCanvas, mSelectRect, mRubberBand );
61+
}
62+
63+
64+
void QgsMapToolSelectRectangle::canvasReleaseEvent( QMouseEvent * e )
65+
{
66+
QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( mCanvas );
67+
if ( vlayer == NULL )
68+
{
69+
return;
70+
}
71+
72+
//if the user simply clicked without dragging a rect
73+
//we will fabricate a small 1x1 pix rect and then continue
74+
//as if they had dragged a rect
75+
if ( !mDragging )
76+
{
77+
QgsMapToolSelectUtils::expandSelectRectangle( mSelectRect, vlayer, e->pos() );
78+
}
79+
else
80+
{
81+
// Set valid values for rectangle's width and height
82+
if ( mSelectRect.width() == 1 )
83+
{
84+
mSelectRect.setLeft( mSelectRect.left() + 1 );
85+
}
86+
if ( mSelectRect.height() == 1 )
87+
{
88+
mSelectRect.setBottom( mSelectRect.bottom() + 1 );
89+
}
90+
}
91+
92+
QgsMapToolSelectUtils::setRubberBand( mCanvas, mSelectRect, mRubberBand );
93+
QgsGeometry* selectGeom = mRubberBand->asGeometry();
94+
QgsMapToolSelectUtils::setSelectFeatures( mCanvas, selectGeom, e );
95+
delete selectGeom;
96+
97+
mRubberBand->reset( true );
98+
delete mRubberBand;
99+
mRubberBand = 0;
100+
mDragging = false;
101+
}

‎src/app/qgsmaptoolselectrectangle.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/***************************************************************************
2+
qgsmaptoolselectrectangle.h - map tool for selecting features by
3+
rectangle
4+
---------------------
5+
begin : January 2006
6+
copyright : (C) 2006 by Martin Dobias
7+
email : wonder.sk at gmail dot com
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
/* $Id: qgsmaptoolselectrectangle.h 13187 2010-03-28 22:14:44Z jef $ */
17+
18+
#ifndef QGSMAPTOOLRECTANGLE_H
19+
#define QGSMAPTOOLRECTANGLE_H
20+
21+
#include <QRect>
22+
#include "qgsmaptool.h"
23+
24+
class QPoint;
25+
class QMouseEvent;
26+
class QgsMapCanvas;
27+
class QgsVectorLayer;
28+
class QgsGeometry;
29+
class QgsRubberBand;
30+
31+
32+
class QgsMapToolSelectRectangle : public QgsMapTool
33+
{
34+
Q_OBJECT
35+
public:
36+
QgsMapToolSelectRectangle( QgsMapCanvas* canvas );
37+
38+
//! Overridden mouse move event
39+
virtual void canvasMoveEvent( QMouseEvent * e );
40+
41+
//! Overridden mouse press event
42+
virtual void canvasPressEvent( QMouseEvent * e );
43+
44+
//! Overridden mouse release event
45+
virtual void canvasReleaseEvent( QMouseEvent * e );
46+
47+
private:
48+
49+
//! Flag to indicate a map canvas drag operation is taking place
50+
bool mDragging;
51+
52+
//! stores actual select rect
53+
QRect mSelectRect;
54+
55+
QgsRubberBand* mRubberBand;
56+
};
57+
58+
#endif

‎src/app/qgsmaptoolselectutils.cpp

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/***************************************************************************
2+
qgsmaptoolselectutils.cpp - Utility methods to help with select map tools
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#include <limits>
18+
19+
#include "qgsmaptoolselectutils.h"
20+
#include "qgsmapcanvas.h"
21+
#include "qgsvectorlayer.h"
22+
#include "qgsfeature.h"
23+
#include "qgsgeometry.h"
24+
#include "qgsrubberband.h"
25+
#include "qgscsexception.h"
26+
#include "qgslogger.h"
27+
#include "qgis.h"
28+
29+
#include <QMouseEvent>
30+
#include <QApplication>
31+
#include <QMessageBox>
32+
33+
QgsVectorLayer* QgsMapToolSelectUtils::getCurrentVectorLayer( QgsMapCanvas* canvas )
34+
{
35+
QgsVectorLayer* vlayer = NULL;
36+
if ( !canvas->currentLayer()
37+
|| ( vlayer = qobject_cast<QgsVectorLayer *>( canvas->currentLayer() ) ) == NULL )
38+
{
39+
QMessageBox::warning( canvas, QObject::tr( "No active vector layer" ),
40+
QObject::tr( "To select features, you must choose a "
41+
"vector layer by clicking on its name in the legend"
42+
) );
43+
}
44+
return vlayer;
45+
}
46+
47+
void QgsMapToolSelectUtils::setRubberBand( QgsMapCanvas* canvas, QRect& selectRect, QgsRubberBand* rubberBand )
48+
{
49+
const QgsMapToPixel* transform = canvas->getCoordinateTransform();
50+
QgsPoint ll = transform->toMapCoordinates( selectRect.left(), selectRect.bottom() );
51+
QgsPoint ur = transform->toMapCoordinates( selectRect.right(), selectRect.top() );
52+
rubberBand->reset( true );
53+
rubberBand->addPoint( ll, false );
54+
rubberBand->addPoint( QgsPoint( ur.x(), ll.y() ), false );
55+
rubberBand->addPoint( ur, false );
56+
rubberBand->addPoint( QgsPoint( ll.x(), ur.y() ), true );
57+
}
58+
59+
void QgsMapToolSelectUtils::expandSelectRectangle( QRect& selectRect,
60+
QgsVectorLayer* vlayer,
61+
QPoint point )
62+
{
63+
int boxSize = 0;
64+
if ( vlayer->geometryType() != QGis::Polygon )
65+
{
66+
//if point or line use an artificial bounding box of 10x10 pixels
67+
//to aid the user to click on a feature accurately
68+
boxSize = 5;
69+
}
70+
else
71+
{
72+
//otherwise just use the click point for polys
73+
boxSize = 1;
74+
}
75+
selectRect.setLeft( point.x() - boxSize );
76+
selectRect.setRight( point.x() + boxSize );
77+
selectRect.setTop( point.y() - boxSize );
78+
selectRect.setBottom( point.y() + boxSize );
79+
}
80+
81+
void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas,
82+
QgsGeometry* selectGeometry,
83+
bool doContains,
84+
bool addSelection,
85+
bool substractSelection,
86+
bool singleSelect )
87+
{
88+
if ( selectGeometry->type() != QGis::Polygon )
89+
{
90+
return;
91+
}
92+
QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas );
93+
if ( vlayer == NULL )
94+
{
95+
return;
96+
}
97+
98+
// toLayerCoordinates will throw an exception for any 'invalid' points in
99+
// the rubber band.
100+
// For example, if you project a world map onto a globe using EPSG 2163
101+
// and then click somewhere off the globe, an exception will be thrown.
102+
QgsGeometry selectGeomTrans( *selectGeometry );
103+
104+
if ( canvas->mapRenderer()->hasCrsTransformEnabled() )
105+
{
106+
try
107+
{
108+
QgsCoordinateTransform ct( canvas->mapRenderer()->destinationSrs(), vlayer->crs() );
109+
selectGeomTrans.transform( ct );
110+
}
111+
catch ( QgsCsException &cse )
112+
{
113+
Q_UNUSED( cse );
114+
// catch exception for 'invalid' point and leave existing selection unchanged
115+
QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) );
116+
QMessageBox::warning( canvas, QObject::tr( "CRS Exception" ),
117+
QObject::tr( "Selection extends beyond layer's coordinate system." ) );
118+
return;
119+
}
120+
}
121+
122+
QApplication::setOverrideCursor( Qt::WaitCursor );
123+
124+
QgsDebugMsg( "Selection layer: " + vlayer->name() );
125+
QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() );
126+
QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) );
127+
QgsDebugMsg( "addSelection: " + QString( addSelection ? "T" : "F" ) );
128+
QgsDebugMsg( "substractSelection: " + QString( substractSelection ? "T" : "F" ) );
129+
130+
vlayer->select( QgsAttributeList(), selectGeomTrans.boundingBox(), true, true );
131+
132+
QgsFeatureIds newSelectedFeatures;
133+
QgsFeature f;
134+
int closestFeatureId = 0;
135+
double closestFeatureDist = std::numeric_limits<double>::max();
136+
while ( vlayer->nextFeature( f ) )
137+
{
138+
QgsGeometry* g = f.geometry();
139+
if ( doContains && !selectGeomTrans.contains( g ) )
140+
{
141+
continue;
142+
}
143+
if ( singleSelect )
144+
{
145+
double distance = g->distance( selectGeomTrans );
146+
if ( distance <= closestFeatureDist )
147+
{
148+
closestFeatureDist = distance;
149+
closestFeatureId = f.id();
150+
}
151+
}
152+
else
153+
{
154+
newSelectedFeatures.insert( f.id() );
155+
}
156+
}
157+
if ( singleSelect && closestFeatureId > 0 )
158+
{
159+
newSelectedFeatures.insert( closestFeatureId );
160+
}
161+
162+
QgsDebugMsg( "Number of selected features: " + QString::number( newSelectedFeatures.size() ) );
163+
164+
QgsFeatureIds layerSelectedFeatures;
165+
if ( addSelection )
166+
{
167+
layerSelectedFeatures = vlayer->selectedFeaturesIds();
168+
QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd();
169+
while ( i != newSelectedFeatures.constBegin() )
170+
{
171+
--i;
172+
layerSelectedFeatures.insert( *i );
173+
}
174+
}
175+
else if ( substractSelection )
176+
{
177+
layerSelectedFeatures = vlayer->selectedFeaturesIds();
178+
QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd();
179+
while ( i != newSelectedFeatures.constBegin() )
180+
{
181+
--i;
182+
if ( layerSelectedFeatures.contains( *i ) )
183+
{
184+
layerSelectedFeatures.remove( *i );
185+
}
186+
}
187+
}
188+
else
189+
{
190+
layerSelectedFeatures = newSelectedFeatures;
191+
}
192+
vlayer->setSelectedFeatures( layerSelectedFeatures );
193+
194+
QApplication::restoreOverrideCursor();
195+
}
196+
197+
void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, QMouseEvent * e )
198+
{
199+
bool doContains = e->modifiers() & Qt::AltModifier ? false : true;
200+
bool addSelection = e->modifiers() & Qt::ControlModifier ? true : false;
201+
bool substractSelection = e->modifiers() & Qt::ShiftModifier ? true : false;
202+
setSelectFeatures( canvas, selectGeometry, doContains, addSelection, substractSelection );
203+
}

‎src/app/qgsmaptoolselectutils.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/***************************************************************************
2+
qgsmaptoolselectutils.h - Utility methods to help with select map tools
3+
---------------------
4+
begin : May 2010
5+
copyright : (C) 2010 by Jeremy Palmer
6+
email : jpalmer at linz dot govt dot nz
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
/* $Id$ */
16+
17+
#ifndef QGSMAPTOOLSELECTUTILS_H
18+
#define QGSMAPTOOLSELECTUTILS_H
19+
20+
#include <Qt>
21+
#include <QRect>
22+
#include <QPoint>
23+
24+
class QMouseEvent;
25+
class QgsMapCanvas;
26+
class QgsVectorLayer;
27+
class QgsGeometry;
28+
class QgsRubberBand;
29+
30+
/**
31+
Namespace containing methods which are useful for the select maptool widgets
32+
*/
33+
namespace QgsMapToolSelectUtils
34+
{
35+
/**
36+
Selects the features within currently selected layer.
37+
@param canvas The map canvas used to get the current selected vector layer and
38+
for any required geometry transformations
39+
@param selectGeometry The geometry to select the layers features. This geometry
40+
must be in terms of the canvas coordinate system.
41+
@param doContains Features will only be selected if contained within the
42+
selection rubber band.
43+
@param addSelection New selected features will be added to the layer's
44+
currently selected features.
45+
@param substractSelection New selected features will be subtracted from
46+
the layer's currently selected features.
47+
@param singleSelect Only selects the closest feature to the selectGeometry.
48+
*/
49+
void setSelectFeatures( QgsMapCanvas* canvas,
50+
QgsGeometry* selectGeometry,
51+
bool doContains = true,
52+
bool addSelection = false,
53+
bool substractSelection = false,
54+
bool singleSelect = false );
55+
56+
/**
57+
Select the features within currently selected layer.
58+
@param canvas The map canvas used to get the current selected vector layer and
59+
for any required geometry transformations
60+
@param selectGeometry The geometry to select the layers features. This geometry
61+
must be in terms of the canvas coordinate system.
62+
@param e MouseEvents are used to determine the current selection
63+
operations (add, subtract, contains)
64+
*/
65+
void setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, QMouseEvent * e );
66+
67+
/**
68+
Get the current selected canvas map layer. Returns NULL if it is not a vector layer
69+
@param canvas The map canvas used for getting the current layer
70+
@return QgsVectorLayer The layer
71+
*/
72+
QgsVectorLayer* getCurrentVectorLayer( QgsMapCanvas* canvas );
73+
74+
/**
75+
Expands a rectangle to a minimum size for selection based on the vector layer type
76+
@param selectRect The QRect to expand
77+
@param vlayer The vector layer layer
78+
@param vlayer The point to expand the rectangle around
79+
*/
80+
void expandSelectRectangle( QRect& selectRect, QgsVectorLayer* vlayer, const QPoint point );
81+
82+
/**
83+
Sets a QgsRubberband to rectangle in map units using a rectangle defined in device coords
84+
@param canvas The map canvas used to transform the rectangle into map units
85+
@param selectRect The input rectangle in device coords
86+
@param rubberBand The rubberband that will be set in map units using the input rectangle
87+
*/
88+
void setRubberBand( QgsMapCanvas* canvas, QRect& selectRect, QgsRubberBand* rubberBand );
89+
}
90+
91+
#endif

‎src/gui/qgisinterface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ class GUI_EXPORT QgisInterface : public QObject
239239
virtual QAction *actionZoomIn() = 0;
240240
virtual QAction *actionZoomOut() = 0;
241241
virtual QAction *actionSelect() = 0;
242+
virtual QAction *actionSelectRectangle() = 0;
243+
virtual QAction *actionSelectPolygon() = 0;
244+
virtual QAction *actionSelectFreehand() = 0;
245+
virtual QAction *actionSelectRadius() = 0;
242246
virtual QAction *actionIdentify() = 0;
243247
virtual QAction *actionMeasure() = 0;
244248
virtual QAction *actionMeasureArea() = 0;

‎src/gui/qgsrubberband.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,50 @@ const QgsPoint *QgsRubberBand::getPoint( int i, int j ) const
431431
else
432432
return 0;
433433
}
434+
435+
QgsGeometry *QgsRubberBand::asGeometry()
436+
{
437+
QgsGeometry *geom = NULL;
438+
if ( mIsPolygon )
439+
{
440+
QgsPolygon polygon;
441+
QList<QList<QgsPoint>>::const_iterator it = mPoints.constBegin();
442+
for ( ; it != mPoints.constEnd(); ++it )
443+
{
444+
polygon.append( getPolyline( *it ) );
445+
}
446+
geom = QgsGeometry::fromPolygon( polygon );
447+
}
448+
else
449+
{
450+
if ( mPoints.size() > 0 )
451+
{
452+
if ( mPoints.size() > 1 )
453+
{
454+
QgsMultiPolyline multiPolyline;
455+
QList<QList<QgsPoint>>::const_iterator it = mPoints.constBegin();
456+
for ( ; it != mPoints.constEnd(); ++it )
457+
{
458+
multiPolyline.append( getPolyline( *it ) );
459+
}
460+
geom = QgsGeometry::fromMultiPolyline( multiPolyline );
461+
}
462+
else
463+
{
464+
geom = QgsGeometry::fromPolyline( getPolyline( mPoints[0] ) );
465+
}
466+
}
467+
}
468+
return geom;
469+
}
470+
471+
QgsPolyline QgsRubberBand::getPolyline( const QList<QgsPoint> & points )
472+
{
473+
QgsPolyline polyline;
474+
QList<QgsPoint>::const_iterator iter = points.constBegin();
475+
for ( ; iter != points.constEnd(); ++iter )
476+
{
477+
polyline.append( *iter );
478+
}
479+
return polyline;
480+
}

‎src/gui/qgsrubberband.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
#define QGSRUBBERBAND_H
1818

1919
#include "qgsmapcanvasitem.h"
20+
#include "qgsgeometry.h"
2021
#include <QBrush>
2122
#include <QList>
2223
#include <QPen>
2324
#include <QPolygon>
2425

25-
class QgsGeometry;
2626
class QgsVectorLayer;
2727
class QPaintEvent;
2828

@@ -84,6 +84,10 @@ class GUI_EXPORT QgsRubberBand: public QgsMapCanvasItem
8484
/**Return vertex*/
8585
const QgsPoint *getPoint( int i, int j = 0 ) const;
8686

87+
/**Returns the rubberband as a Geometry.
88+
* added in 1.6 */
89+
QgsGeometry* asGeometry();
90+
8791
protected:
8892
virtual void paint( QPainter* p );
8993

@@ -101,6 +105,9 @@ class GUI_EXPORT QgsRubberBand: public QgsMapCanvasItem
101105
double mTranslationOffsetY;
102106

103107
QgsRubberBand();
108+
109+
static QgsPolyline getPolyline( const QList<QgsPoint> & points );
110+
104111
};
105112

106113
#endif

‎src/plugins/coordinate_capture/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ INCLUDE_DIRECTORIES(
3636
../../core/symbology
3737
../../gui
3838
..
39+
${GEOS_INCLUDE_DIR}
3940
)
4041

4142
TARGET_LINK_LIBRARIES(coordinatecaptureplugin

0 commit comments

Comments
 (0)
Please sign in to comment.