Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Expand QgsSpatialIndexKDBush API
  • Loading branch information
nyalldawson committed Jul 7, 2018
1 parent 5c552dd commit 004dc18
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 0 deletions.
12 changes: 12 additions & 0 deletions python/core/auto_generated/qgsspatialindexkdbush.sip.in
Expand Up @@ -23,6 +23,8 @@ Compared to QgsSpatialIndex, this index:
- supports true "distance based" searches, i.e. return all points within a radius
from a search point

QgsSpatialIndexKDBush objects are implicitly shared and can be inexpensively copied.

.. seealso:: :py:class:`QgsSpatialIndex`

.. versionadded:: 3.4
Expand Down Expand Up @@ -68,12 +70,22 @@ Copy constructor
Returns a list of features which fall within the specified ``rectangle``.
%End


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


bool point( QgsFeatureId id, QgsPointXY &point ) const;
%Docstring
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

};

/************************************************************************
Expand Down
18 changes: 18 additions & 0 deletions src/core/qgsspatialindexkdbush.cpp
Expand Up @@ -63,6 +63,16 @@ QList<QgsFeatureId> QgsSpatialIndexKDBush::within( const QgsPointXY &point, doub
return result;
}

void QgsSpatialIndexKDBush::within( const QgsPointXY &point, double radius, const std::function<void( QgsFeatureId )> &visitor )
{
d->index->within( point.x(), point.y(), radius, visitor );
}

bool QgsSpatialIndexKDBush::point( QgsFeatureId id, QgsPointXY &point ) const
{
return d->index->point( id, point );
}

QList<QgsFeatureId> QgsSpatialIndexKDBush::intersect( const QgsRectangle &rectangle ) const
{
QList<QgsFeatureId> result;
Expand All @@ -72,3 +82,11 @@ QList<QgsFeatureId> QgsSpatialIndexKDBush::intersect( const QgsRectangle &rectan
rectangle.yMaximum(), [&result]( const QgsFeatureId id ) { result << id; } );
return result;
}

void QgsSpatialIndexKDBush::intersect( const QgsRectangle &rectangle, const std::function<void ( QgsFeatureId )> &visitor ) const
{
d->index->range( rectangle.xMinimum(),
rectangle.yMinimum(),
rectangle.xMaximum(),
rectangle.yMaximum(), visitor );
}
23 changes: 23 additions & 0 deletions src/core/qgsspatialindexkdbush.h
Expand Up @@ -87,12 +87,35 @@ class CORE_EXPORT QgsSpatialIndexKDBush
*/
QList<QgsFeatureId> intersect( const QgsRectangle &rectangle ) const;

/**
* Calls a \a visitor function for all features which fall within the specified \a rectangle.
*
* \note Not available in Python bindings
*/
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
* of \a point.
*/
QList<QgsFeatureId> within( const QgsPointXY &point, double radius ) const;

/**
* Calls a \a visitor function for all features which are within the given search \a radius
* of \a point.
*
* \note Not available in Python bindings
*/
void within( const QgsPointXY &point, double radius, const std::function<void( QgsFeatureId )> &visitor ) SIP_SKIP;

/**
* Fetches the point from the index with matching \a id and stores it in \a point.
*
* Returns true if the point was found, or false if no matching feature ID is present
* in the index.
*/
bool point( QgsFeatureId id, QgsPointXY &point ) const;

private:

//! Implicitly shared data pointer
Expand Down
13 changes: 13 additions & 0 deletions src/core/qgsspatialindexkdbush_p.h
Expand Up @@ -86,6 +86,19 @@ class PointXYKDBush : public kdbush::KDBush< std::pair<double, double>, QgsFeatu
sortKD( 0, size - 1, 0 );
}

bool point( QgsFeatureId id, QgsPointXY &point ) const
{
auto iter = std::find_if( ids.begin(), ids.end(), [id]( QgsFeatureId f ) { return id == f; } );
size_t index = std::distance( ids.begin(), iter );
if ( index == ids.size() )
{
return false;
}

point = QgsPointXY( points[ index ].first, points[index].second );
return true;
}

};

class QgsSpatialIndexKDBushPrivate
Expand Down

0 comments on commit 004dc18

Please sign in to comment.