16 #ifndef QGSGENERICSPATIALINDEX_H
17 #define QGSGENERICSPATIALINDEX_H
19 #include "qgis_core.h"
30 #include <spatialindex/SpatialIndex.h>
53 mStorageManager.reset( SpatialIndex::StorageManager::createNewMemoryStorageManager() );
54 mRTree = createSpatialIndex( *mStorageManager );
67 const QMutexLocker locker( &mMutex );
69 const qint64
id = mNextId++;
70 mIdToData.insert(
id, data );
71 mDataToId.insert( data,
id );
74 mRTree->insertData( 0,
nullptr, r,
static_cast< qint64
>(
id ) );
77 catch ( Tools::Exception &e )
80 QgsDebugMsg( QStringLiteral(
"Tools::Exception caught: " ).arg( e.what().c_str() ) );
82 catch (
const std::exception &e )
85 QgsDebugMsg( QStringLiteral(
"std::exception caught: " ).arg( e.what() ) );
89 QgsDebugMsg( QStringLiteral(
"unknown spatial index exception caught" ) );
105 const QMutexLocker locker( &mMutex );
107 const qint64
id = mDataToId.value( data, 0 );
112 const bool res = mRTree->deleteData( r,
id );
113 mDataToId.remove( data );
114 mIdToData.remove(
id );
125 GenericIndexVisitor<T> visitor( callback, mIdToData );
128 const QMutexLocker locker( &mMutex );
129 mRTree->intersectsWithQuery( r, visitor );
138 const QMutexLocker locker( &mMutex );
139 return mIdToData.isEmpty();
144 std::unique_ptr< SpatialIndex::ISpatialIndex > createSpatialIndex( SpatialIndex::IStorageManager &storageManager )
147 constexpr
double fillFactor = 0.7;
148 constexpr
unsigned long indexCapacity = 10;
149 constexpr
unsigned long leafCapacity = 10;
150 constexpr
unsigned long dimension = 2;
151 constexpr SpatialIndex::RTree::RTreeVariant variant = SpatialIndex::RTree::RV_RSTAR;
154 SpatialIndex::id_type indexId;
155 return std::unique_ptr< SpatialIndex::ISpatialIndex >( SpatialIndex::RTree::createNewRTree( storageManager, fillFactor, indexCapacity,
156 leafCapacity, dimension, variant, indexId ) );
159 std::unique_ptr< SpatialIndex::IStorageManager > mStorageManager;
160 std::unique_ptr< SpatialIndex::ISpatialIndex > mRTree;
162 mutable QMutex mMutex;
165 QHash< qint64, T * > mIdToData;
166 QHash< T *, qint64 > mDataToId;
168 template <
typename TT>
169 class GenericIndexVisitor :
public SpatialIndex::IVisitor
172 explicit GenericIndexVisitor(
const std::function<
bool( TT *data )> &callback,
const QHash< qint64, TT * > &data )
173 : mCallback( callback )
177 void visitNode(
const SpatialIndex::INode &n )
override
180 void visitData(
const SpatialIndex::IData &d )
override
182 const qint64
id = d.getIdentifier();
183 T *data = mData.value(
id );
187 void visitData( std::vector<const SpatialIndex::IData *> &v )
override
191 const std::function< bool( TT *data )> &mCallback;
192 QHash< qint64, TT * > mData;
A generic rtree spatial index based on a libspatialindex backend.
bool intersects(const QgsRectangle &bounds, const std::function< bool(T *data)> &callback) const
Performs an intersection check against the index, for data intersecting the specified bounds.
QgsGenericSpatialIndex()
Constructor for QgsGenericSpatialIndex.
bool isEmpty() const
Returns true if the index contains no items.
bool insert(T *data, const QgsRectangle &bounds)
Inserts new data into the spatial index, with the specified bounds.
bool remove(T *data, const QgsRectangle &bounds)
Removes existing data from the spatial index, with the specified bounds.
A rectangle specified with double values.
static SpatialIndex::Region rectangleToRegion(const QgsRectangle &rectangle)
Converts a QGIS rectangle to a SpatialIndex region.