Skip to content

Commit

Permalink
Use sets for index results
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Jul 7, 2018
1 parent 682671d commit 612c9cb
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 23 deletions.
13 changes: 9 additions & 4 deletions python/core/auto_generated/qgsspatialindexkdbush.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ Copy constructor

~QgsSpatialIndexKDBush();

QList<QgsFeatureId> intersect( const QgsRectangle &rectangle ) const;
QSet<QgsFeatureId> intersect( const QgsRectangle &rectangle ) const;
%Docstring
Returns a list of features which fall within the specified ``rectangle``.
Returns the set of features which fall within the specified ``rectangle``.
%End


QList<QgsFeatureId> within( const QgsPointXY &point, double radius ) const;
QSet<QgsFeatureId> within( const QgsPointXY &point, double radius ) const;
%Docstring
Returns a list of features which are within the given search ``radius``
Returns the set of features which are within the given search ``radius``
of ``point``.
%End

Expand All @@ -84,6 +84,11 @@ Fetches the point from the index with matching ``id`` and stores it in ``point``

Returns true if the point was found, or false if no matching feature ID is present
in the index.
%End

qgssize size() const;
%Docstring
Returns the size of the index, i.e. the number of points contained within the index.
%End

};
Expand Down
15 changes: 10 additions & 5 deletions src/core/qgsspatialindexkdbush.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ QgsSpatialIndexKDBush::~QgsSpatialIndexKDBush()
delete d;
}

QList<QgsFeatureId> QgsSpatialIndexKDBush::within( const QgsPointXY &point, double radius ) const
QSet<QgsFeatureId> QgsSpatialIndexKDBush::within( const QgsPointXY &point, double radius ) const
{
QList<QgsFeatureId> result;
d->index->within( point.x(), point.y(), radius, [&result]( const QgsFeatureId id ) { result << id; } );
QSet<QgsFeatureId> result;
d->index->within( point.x(), point.y(), radius, [&result]( const QgsFeatureId id ) { result.insert( id ); } );
return result;
}

Expand All @@ -73,9 +73,14 @@ bool QgsSpatialIndexKDBush::point( QgsFeatureId id, QgsPointXY &point ) const
return d->index->point( id, point );
}

QList<QgsFeatureId> QgsSpatialIndexKDBush::intersect( const QgsRectangle &rectangle ) const
qgssize QgsSpatialIndexKDBush::size() const
{
QList<QgsFeatureId> result;
return d->index->size();
}

QSet<QgsFeatureId> QgsSpatialIndexKDBush::intersect( const QgsRectangle &rectangle ) const
{
QSet<QgsFeatureId> result;
d->index->range( rectangle.xMinimum(),
rectangle.yMinimum(),
rectangle.xMaximum(),
Expand Down
13 changes: 9 additions & 4 deletions src/core/qgsspatialindexkdbush.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ class CORE_EXPORT QgsSpatialIndexKDBush
~QgsSpatialIndexKDBush();

/**
* Returns a list of features which fall within the specified \a rectangle.
* Returns the set of features which fall within the specified \a rectangle.
*/
QList<QgsFeatureId> intersect( const QgsRectangle &rectangle ) const;
QSet<QgsFeatureId> intersect( const QgsRectangle &rectangle ) const;

/**
* Calls a \a visitor function for all features which fall within the specified \a rectangle.
Expand All @@ -95,10 +95,10 @@ class CORE_EXPORT QgsSpatialIndexKDBush
void intersect( const QgsRectangle &rectangle, const std::function<void( QgsFeatureId )> &visitor ) const SIP_SKIP;

/**
* Returns a list of features which are within the given search \a radius
* Returns the set of features which are within the given search \a radius
* of \a point.
*/
QList<QgsFeatureId> within( const QgsPointXY &point, double radius ) const;
QSet<QgsFeatureId> within( const QgsPointXY &point, double radius ) const;

/**
* Calls a \a visitor function for all features which are within the given search \a radius
Expand All @@ -116,6 +116,11 @@ class CORE_EXPORT QgsSpatialIndexKDBush
*/
bool point( QgsFeatureId id, QgsPointXY &point ) const;

/**
* Returns the size of the index, i.e. the number of points contained within the index.
*/
qgssize size() const;

private:

//! Implicitly shared data pointer
Expand Down
5 changes: 5 additions & 0 deletions src/core/qgsspatialindexkdbush_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ class PointXYKDBush : public kdbush::KDBush< std::pair<double, double>, QgsFeatu
return true;
}

std::size_t size() const
{
return points.size();
}

private:

QHash< QgsFeatureId, QgsPointXY > mIdToPoint;
Expand Down
22 changes: 12 additions & 10 deletions tests/src/core/testqgsspatialindexkdbush.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,27 +73,28 @@ class TestQgsSpatialIndexKdBush : public QObject
for ( QgsFeature f : _pointFeatures() )
vl->dataProvider()->addFeature( f );
QgsSpatialIndexKDBush index( *vl->dataProvider() );
QCOMPARE( index.size(), 4 );

QList<QgsFeatureId> fids = index.intersect( QgsRectangle( 0, 0, 10, 10 ) );
QSet<QgsFeatureId> fids = index.intersect( QgsRectangle( 0, 0, 10, 10 ) );
QVERIFY( fids.count() == 1 );
QCOMPARE( fids[0], 1 );
QVERIFY( fids.contains( 1 ) );

QList<QgsFeatureId> fids2 = index.intersect( QgsRectangle( -10, -10, 0, 10 ) );
QSet<QgsFeatureId> fids2 = index.intersect( QgsRectangle( -10, -10, 0, 10 ) );
QCOMPARE( fids2.count(), 2 );
QVERIFY( fids2.contains( 2 ) );
QVERIFY( fids2.contains( 3 ) );

QList<QgsFeatureId> fids3 = index.within( QgsPointXY( 0, 0 ), 2 );
QSet<QgsFeatureId> fids3 = index.within( QgsPointXY( 0, 0 ), 2 );
QCOMPARE( fids3.count(), 4 );
QVERIFY( fids3.contains( 1 ) );
QVERIFY( fids3.contains( 2 ) );
QVERIFY( fids3.contains( 3 ) );
QVERIFY( fids3.contains( 4 ) );

QList<QgsFeatureId> fids4 = index.within( QgsPointXY( 0, 0 ), 1 );
QSet<QgsFeatureId> fids4 = index.within( QgsPointXY( 0, 0 ), 1 );
QCOMPARE( fids4.count(), 0 );

QList<QgsFeatureId> fids5 = index.within( QgsPointXY( -1, -1 ), 2.1 );
QSet<QgsFeatureId> fids5 = index.within( QgsPointXY( -1, -1 ), 2.1 );
QCOMPARE( fids5.count(), 3 );
QVERIFY( fids5.contains( 2 ) );
QVERIFY( fids5.contains( 3 ) );
Expand Down Expand Up @@ -127,9 +128,9 @@ class TestQgsSpatialIndexKdBush : public QObject
QVERIFY( index->d->ref == 2 );

// test that copied index works
QList<QgsFeatureId> fids = indexCopy->intersect( QgsRectangle( 0, 0, 10, 10 ) );
QSet<QgsFeatureId> fids = indexCopy->intersect( QgsRectangle( 0, 0, 10, 10 ) );
QVERIFY( fids.count() == 1 );
QCOMPARE( fids[0], 1 );
QVERIFY( fids.contains( 1 ) );

// check that the index is still shared
QCOMPARE( index->d, indexCopy->d );
Expand All @@ -140,12 +141,13 @@ class TestQgsSpatialIndexKdBush : public QObject
// test that copied index still works
fids = indexCopy->intersect( QgsRectangle( 0, 0, 10, 10 ) );
QVERIFY( fids.count() == 1 );
QCOMPARE( fids[0], 1 );
QVERIFY( fids.contains( 1 ) );
QVERIFY( indexCopy->d->ref == 1 );

// assignment operator
std::unique_ptr< QgsVectorLayer > vl2 = qgis::make_unique< QgsVectorLayer >( "Point", QString(), QStringLiteral( "memory" ) );
QgsSpatialIndexKDBush index3( *vl2->dataProvider() );
QCOMPARE( index3.size(), 0 );
fids = index3.intersect( QgsRectangle( 0, 0, 10, 10 ) );
QCOMPARE( fids.count(), 0 );
QVERIFY( index3.d->ref == 1 );
Expand All @@ -155,7 +157,7 @@ class TestQgsSpatialIndexKdBush : public QObject
QVERIFY( index3.d->ref == 2 );
fids = index3.intersect( QgsRectangle( 0, 0, 10, 10 ) );
QVERIFY( fids.count() == 1 );
QCOMPARE( fids[0], 1 );
QVERIFY( fids.contains( 1 ) );

indexCopy.reset();
QVERIFY( index3.d->ref == 1 );
Expand Down

0 comments on commit 612c9cb

Please sign in to comment.