mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Merge pull request #4661 from nyalldawson/feature_index
Add method for manually inserting features into spatial indexes
This commit is contained in:
commit
2f9bfc5653
@ -2060,6 +2060,11 @@ QgsSnapper {#qgis_api_break_3_0_QgsSnapper}
|
||||
- Constructor variant with QgsMapRenderer has been removed. Use the variant with QgsMapSettings.
|
||||
- Signature for snapPoint() has changed.
|
||||
|
||||
QgsSpatialIndex {#qgis_api_break_3_0_QgsSpatialIndex}
|
||||
---------------
|
||||
|
||||
- The protected members were made private. QgsSpatialIndex is not designed to be subclassed.
|
||||
|
||||
|
||||
QgsSublayersDialog {#qgis_api_break_3_0_QgsSublayersDialog}
|
||||
------------------
|
||||
|
@ -54,6 +54,14 @@ Add feature to index
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool insertFeature( QgsFeatureId id, const QgsRectangle &bounds );
|
||||
%Docstring
|
||||
Add a feature ``id`` to the index with a specified bounding box.
|
||||
:return: true if feature was successfully added to index.
|
||||
.. versionadded:: 3.0
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool deleteFeature( const QgsFeature &f );
|
||||
%Docstring
|
||||
Remove feature from index
|
||||
@ -81,9 +89,6 @@ get reference count - just for debugging!
|
||||
:rtype: QAtomicInt
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -253,24 +253,38 @@ SpatialIndex::Region QgsSpatialIndex::rectToRegion( const QgsRectangle &rect )
|
||||
|
||||
bool QgsSpatialIndex::featureInfo( const QgsFeature &f, SpatialIndex::Region &r, QgsFeatureId &id )
|
||||
{
|
||||
if ( !f.hasGeometry() )
|
||||
QgsRectangle rect;
|
||||
if ( !featureInfo( f, rect, id ) )
|
||||
return false;
|
||||
|
||||
QgsGeometry g = f.geometry();
|
||||
|
||||
id = f.id();
|
||||
r = rectToRegion( g.boundingBox() );
|
||||
r = rectToRegion( rect );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsSpatialIndex::featureInfo( const QgsFeature &f, QgsRectangle &rect, QgsFeatureId &id )
|
||||
{
|
||||
if ( !f.hasGeometry() )
|
||||
return false;
|
||||
|
||||
id = f.id();
|
||||
rect = f.geometry().boundingBox();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QgsSpatialIndex::insertFeature( const QgsFeature &f )
|
||||
{
|
||||
SpatialIndex::Region r;
|
||||
QgsRectangle rect;
|
||||
QgsFeatureId id;
|
||||
if ( !featureInfo( f, r, id ) )
|
||||
if ( !featureInfo( f, rect, id ) )
|
||||
return false;
|
||||
|
||||
return insertFeature( id, rect );
|
||||
}
|
||||
|
||||
bool QgsSpatialIndex::insertFeature( QgsFeatureId id, const QgsRectangle &rect )
|
||||
{
|
||||
SpatialIndex::Region r( rectToRegion( rect ) );
|
||||
|
||||
// TODO: handle possible exceptions correctly
|
||||
try
|
||||
{
|
||||
|
@ -81,6 +81,13 @@ class CORE_EXPORT QgsSpatialIndex
|
||||
//! Add feature to index
|
||||
bool insertFeature( const QgsFeature &f );
|
||||
|
||||
/**
|
||||
* Add a feature \a id to the index with a specified bounding box.
|
||||
* \returns true if feature was successfully added to index.
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
bool insertFeature( QgsFeatureId id, const QgsRectangle &bounds );
|
||||
|
||||
//! Remove feature from index
|
||||
bool deleteFeature( const QgsFeature &f );
|
||||
|
||||
@ -98,12 +105,29 @@ class CORE_EXPORT QgsSpatialIndex
|
||||
//! get reference count - just for debugging!
|
||||
QAtomicInt SIP_PYTYPE( int ) refs() const;
|
||||
|
||||
protected:
|
||||
//! \note not available in Python bindings
|
||||
static SpatialIndex::Region rectToRegion( const QgsRectangle &rect ) SIP_SKIP;
|
||||
//! \note not available in Python bindings
|
||||
private:
|
||||
|
||||
static SpatialIndex::Region rectToRegion( const QgsRectangle &rect );
|
||||
|
||||
/** Calculates feature info to insert into index.
|
||||
* \param f input feature
|
||||
* \param r will be set to spatial index region
|
||||
* \param id will be set to feature's ID
|
||||
* \returns true if feature info was successfully retrieved and the feature can be added to
|
||||
* the index
|
||||
*/
|
||||
static bool featureInfo( const QgsFeature &f, SpatialIndex::Region &r, QgsFeatureId &id ) SIP_SKIP;
|
||||
|
||||
/** Calculates feature info to insert into index.
|
||||
* \param f input feature
|
||||
* \param rect will be set to feature's geometry bounding box
|
||||
* \param id will be set to feature's ID
|
||||
* \returns true if feature info was successfully retrieved and the feature can be added to
|
||||
* the index
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
static bool featureInfo( const QgsFeature &f, QgsRectangle &rect, QgsFeatureId &id );
|
||||
|
||||
friend class QgsFeatureIteratorDataStream; // for access to featureInfo()
|
||||
|
||||
private:
|
||||
|
@ -82,6 +82,23 @@ class TestQgsSpatialIndex : public QObject
|
||||
QVERIFY( fids2.contains( 3 ) );
|
||||
}
|
||||
|
||||
void testQueryManualInsert()
|
||||
{
|
||||
QgsSpatialIndex index;
|
||||
index.insertFeature( 1, QgsRectangle( 2, 3, 2, 3 ) );
|
||||
index.insertFeature( 2, QgsRectangle( 12, 13, 12, 13 ) );
|
||||
index.insertFeature( 3, QgsRectangle( 14, 13, 14, 13 ) );
|
||||
|
||||
QList<QgsFeatureId> fids = index.intersects( QgsRectangle( 1, 2, 3, 4 ) );
|
||||
QVERIFY( fids.count() == 1 );
|
||||
QVERIFY( fids.at( 0 ) == 1 );
|
||||
|
||||
QList<QgsFeatureId> fids2 = index.intersects( QgsRectangle( 10, 12, 15, 14 ) );
|
||||
QVERIFY( fids2.count() == 2 );
|
||||
QVERIFY( fids2.contains( 2 ) );
|
||||
QVERIFY( fids2.contains( 3 ) );
|
||||
}
|
||||
|
||||
void testCopy()
|
||||
{
|
||||
QgsSpatialIndex *index = new QgsSpatialIndex;
|
||||
|
Loading…
x
Reference in New Issue
Block a user