Skip to content

Commit 68739c6

Browse files
committed
Fix selecting features by radius (fix #14748)
(cherry-picked from 33a5ee7)
1 parent 5305486 commit 68739c6

File tree

5 files changed

+67
-1
lines changed

5 files changed

+67
-1
lines changed

python/gui/qgsrubberband.sip

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,14 @@ class QgsRubberBand: QgsMapCanvasItem
122122
*/
123123
void addPoint( const QgsPoint & p, bool doUpdate = true, int geometryIndex = 0 );
124124

125+
/** Ensures that a polygon geometry is closed and that the last vertex equals the
126+
* first vertex.
127+
* @param doUpdate set to true to update the map canvas immediately
128+
* @param geometryIndex index of the feature part (in case of multipart geometries)
129+
* @note added in QGIS 2.16
130+
*/
131+
void closePoints( bool doUpdate = true, int geometryIndex = 0 );
132+
125133
/**
126134
* Remove a vertex from the rubberband and (optionally) update canvas.
127135
* @param index The index of the vertex/point to remove, negative indexes start at end

src/app/qgsmaptoolselectradius.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void QgsMapToolSelectRadius::setRadiusRubberBand( QgsPoint & radiusEdge )
109109
double theta = i * ( 2.0 * M_PI / RADIUS_SEGMENTS );
110110
QgsPoint radiusPoint( mRadiusCenter.x() + r * cos( theta ),
111111
mRadiusCenter.y() + r * sin( theta ) );
112-
mRubberBand->addPoint( radiusPoint );
112+
mRubberBand->addPoint( radiusPoint, false );
113113
}
114+
mRubberBand->closePoints( true );
114115
}

src/gui/qgsrubberband.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,26 @@ void QgsRubberBand::addPoint( const QgsPoint & p, bool doUpdate /* = true */, in
188188
}
189189
}
190190

191+
void QgsRubberBand::closePoints( bool doUpdate, int geometryIndex )
192+
{
193+
if ( geometryIndex < 0 || geometryIndex >= mPoints.size() )
194+
{
195+
return;
196+
}
197+
198+
if ( mPoints.at( geometryIndex ).at( 0 ) != mPoints.at( geometryIndex ).at( mPoints.at( geometryIndex ).size() - 1 ) )
199+
{
200+
mPoints[geometryIndex] << mPoints.at( geometryIndex ).at( 0 );
201+
}
202+
203+
if ( doUpdate )
204+
{
205+
setVisible( true );
206+
updateRect();
207+
update();
208+
}
209+
}
210+
191211

192212
void QgsRubberBand::removePoint( int index, bool doUpdate/* = true*/, int geometryIndex/* = 0*/ )
193213
{

src/gui/qgsrubberband.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ class GUI_EXPORT QgsRubberBand: public QgsMapCanvasItem
149149
*/
150150
void addPoint( const QgsPoint & p, bool doUpdate = true, int geometryIndex = 0 );
151151

152+
/** Ensures that a polygon geometry is closed and that the last vertex equals the
153+
* first vertex.
154+
* @param doUpdate set to true to update the map canvas immediately
155+
* @param geometryIndex index of the feature part (in case of multipart geometries)
156+
* @note added in QGIS 2.16
157+
*/
158+
void closePoints( bool doUpdate = true, int geometryIndex = 0 );
159+
152160
/**
153161
* Remove a vertex from the rubberband and (optionally) update canvas.
154162
* @param index The index of the vertex/point to remove, negative indexes start at end

tests/src/gui/testqgsrubberband.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class TestQgsRubberband : public QObject
4646
void testAddSingleMultiGeometries(); //test for #7728
4747
void testBoundingRect(); //test for #12392
4848
void testVisibility(); //test for 12486
49+
void testClose(); //test closing geometry
4950

5051
private:
5152
QgsMapCanvas* mCanvas;
@@ -193,6 +194,34 @@ void TestQgsRubberband::testVisibility()
193194

194195
}
195196

197+
void TestQgsRubberband::testClose()
198+
{
199+
QgsRubberBand r( mCanvas, QGis::Polygon );
200+
201+
// try closing empty rubber band, don't want to crash
202+
r.closePoints();
203+
QCOMPARE( r.partSize( 0 ), 0 );
204+
205+
r.addPoint( QgsPoint( 1, 2 ) );
206+
r.addPoint( QgsPoint( 1, 3 ) );
207+
r.addPoint( QgsPoint( 2, 3 ) );
208+
QCOMPARE( r.partSize( 0 ), 3 );
209+
210+
// test with some bad geometry indexes - don't want to crash!
211+
r.closePoints( true, -1 );
212+
QCOMPARE( r.partSize( 0 ), 3 );
213+
r.closePoints( true, 100 );
214+
QCOMPARE( r.partSize( 0 ), 3 );
215+
216+
// valid close
217+
r.closePoints();
218+
QCOMPARE( r.partSize( 0 ), 4 );
219+
220+
// close already closed polygon, should be no change
221+
r.closePoints();
222+
QCOMPARE( r.partSize( 0 ), 4 );
223+
}
224+
196225

197226
QTEST_MAIN( TestQgsRubberband )
198227
#include "testqgsrubberband.moc"

0 commit comments

Comments
 (0)