27 #include <spatialindex/SpatialIndex.h>    29 #include <QMutexLocker>    52       mList.append( d.getIdentifier() );
    55     void visitData( std::vector<const IData *> &v )
 override    59     QList<QgsFeatureId> &mList;
    71       : mNewIndex( newIndex ) {}
    78       SpatialIndex::IShape *shape = 
nullptr;
    80       mNewIndex->insertData( 0, 
nullptr, *shape, d.getIdentifier() );
    84     void visitData( std::vector<const IData *> &v )
 override    88     SpatialIndex::ISpatialIndex *mNewIndex = 
nullptr;
    92 class QgsNearestNeighborComparator : 
public INearestNeighborComparator
    96     QgsNearestNeighborComparator( 
const QHash< QgsFeatureId, QgsGeometry > *geometries, 
const QgsPointXY &point, 
double maxDistance )
    97       : mGeometries( geometries )
    99       , mMaxDistance( maxDistance )
   103     QgsNearestNeighborComparator( 
const QHash< QgsFeatureId, QgsGeometry > *geometries, 
const QgsGeometry &geometry, 
double maxDistance )
   104       : mGeometries( geometries )
   106       , mMaxDistance( maxDistance )
   110     const QHash< QgsFeatureId, QgsGeometry > *mGeometries = 
nullptr;
   112     double mMaxDistance = 0;
   113     QSet< QgsFeatureId > mFeaturesOutsideMaxDistance;
   115     double getMinimumDistance( 
const IShape &query, 
const IShape &entry )
 override   117       return query.getMinimumDistance( entry );
   120     double getMinimumDistance( 
const IShape &query, 
const IData &data )
 override   124       data.getShape( &pS );
   125       double dist = query.getMinimumDistance( *pS );
   133       if ( mGeometries && ( mMaxDistance <= 0.0 || dist <= mMaxDistance ) )
   135         QgsGeometry other = mGeometries->value( data.getIdentifier() );
   139       if ( mMaxDistance > 0 && dist > mMaxDistance )
   149         mFeaturesOutsideMaxDistance.insert( data.getIdentifier() );
   150         return mMaxDistance + 0.00000001;
   162 class QgsFeatureIteratorDataStream : 
public IDataStream
   166     explicit QgsFeatureIteratorDataStream( 
const QgsFeatureIterator &fi, 
QgsFeedback *feedback = 
nullptr, QgsSpatialIndex::Flags flags = 
nullptr,
   167                                            const std::function< 
bool( 
const QgsFeature & ) > *callback = 
nullptr )
   169       , mFeedback( feedback )
   171       , mCallback( callback )
   176     ~QgsFeatureIteratorDataStream()
 override   182     IData *getNext()
 override   184       if ( mFeedback && mFeedback->isCanceled() )
   187       RTree::Data *ret = mNextData;
   194     bool hasNext()
 override { 
return nullptr != mNextData; }
   197     uint32_t size()
 override { Q_ASSERT( 
false && 
"not available" ); 
return 0; }
   200     void rewind()
 override { Q_ASSERT( 
false && 
"not available" ); }
   202     QHash< QgsFeatureId, QgsGeometry > geometries;
   208       SpatialIndex::Region r;
   210       while ( mFi.nextFeature( f ) )
   214           bool res = ( *mCallback )( f );
   221         if ( QgsSpatialIndex::featureInfo( f, r, 
id ) )
   223           mNextData = 
new RTree::Data( 0, 
nullptr, r, 
id );
   233     RTree::Data *mNextData = 
nullptr;
   235     QgsSpatialIndex::Flags mFlags = 
nullptr;
   236     const std::function< bool( const QgsFeature & ) > *mCallback = 
nullptr;
   247 class QgsSpatialIndexData : 
public QSharedData
   250     QgsSpatialIndexData( QgsSpatialIndex::Flags flags )
   256     QgsSpatialIndex::Flags mFlags = 
nullptr;
   258     QHash< QgsFeatureId, QgsGeometry > mGeometries;
   269                                   const std::function< 
bool( 
const QgsFeature & ) > *callback = 
nullptr )
   272       QgsFeatureIteratorDataStream fids( fi, feedback, mFlags, callback );
   275         mGeometries = fids.geometries;
   278     QgsSpatialIndexData( 
const QgsSpatialIndexData &other )
   279       : QSharedData( other )
   280       , mFlags( other.mFlags )
   281       , mGeometries( other.mGeometries )
   283       QMutexLocker locker( &other.mMutex );
   288       double low[]  = { std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest() };
   289       double high[] = { std::numeric_limits<double>::max(), std::numeric_limits<double>::max() };
   290       SpatialIndex::Region query( low, high, 2 );
   292       other.mRTree->intersectsWithQuery( query, visitor );
   295     ~QgsSpatialIndexData()
   301     QgsSpatialIndexData &operator=( 
const QgsSpatialIndexData &rh ) = 
delete;
   303     void initTree( IDataStream *inputStream = 
nullptr )
   306       mStorage = StorageManager::createNewMemoryStorageManager();
   309       double fillFactor = 0.7;
   310       unsigned long indexCapacity = 10;
   311       unsigned long leafCapacity = 10;
   312       unsigned long dimension = 2;
   313       RTree::RTreeVariant variant = RTree::RV_RSTAR;
   316       SpatialIndex::id_type indexId;
   318       if ( inputStream && inputStream->hasNext() )
   319         mRTree = RTree::createAndBulkLoadNewRTree( RTree::BLM_STR, *inputStream, *mStorage, fillFactor, indexCapacity,
   320                  leafCapacity, dimension, variant, indexId );
   322         mRTree = RTree::createNewRTree( *mStorage, fillFactor, indexCapacity,
   323                                         leafCapacity, dimension, variant, indexId );
   327     SpatialIndex::IStorageManager *mStorage = 
nullptr;
   330     SpatialIndex::ISpatialIndex *mRTree = 
nullptr;
   332     mutable QMutex mMutex;
   343   d = 
new QgsSpatialIndexData( flags );
   348   d = 
new QgsSpatialIndexData( fi, feedback, flags );
   354   d = 
new QgsSpatialIndexData( fi, 
nullptr, flags, &callback );
   374   if ( 
this != &other )
   382   if ( !featureInfo( f, rect, 
id ) )
   407   if ( !featureInfo( feature, rect, 
id ) )
   414       QMutexLocker locker( &d->mMutex );
   415       d->mGeometries.insert( feature.
id(), feature.
geometry() );
   424   QgsFeatureList::iterator fIt = features.begin();
   426   for ( ; fIt != features.end(); ++fIt )
   448   QMutexLocker locker( &d->mMutex );
   456   catch ( Tools::Exception &e )
   459     QgsDebugMsg( QStringLiteral( 
"Tools::Exception caught: " ).arg( e.what().c_str() ) );
   461   catch ( 
const std::exception &e )
   464     QgsDebugMsg( QStringLiteral( 
"std::exception caught: " ).arg( e.what() ) );
   468     QgsDebugMsg( QStringLiteral( 
"unknown spatial index exception caught" ) );
   476   SpatialIndex::Region r;
   478   if ( !featureInfo( f, r, 
id ) )
   481   QMutexLocker locker( &d->mMutex );
   484     d->mGeometries.remove( f.
id() );
   490   QList<QgsFeatureId> list;
   495   QMutexLocker locker( &d->mMutex );
   496   d->mRTree->intersectsWithQuery( r, visitor );
   503   QList<QgsFeatureId> list;
   506   double pt[2] = { point.
x(), point.
y() };
   509   QMutexLocker locker( &d->mMutex );
   511                                     point, maxDistance );
   512   d->mRTree->nearestNeighborQuery( neighbors, p, visitor, nnc );
   514   if ( maxDistance > 0 )
   517     list.erase( std::remove_if( list.begin(), list.end(),
   520       return nnc.mFeaturesOutsideMaxDistance.contains( 
id );
   529   QList<QgsFeatureId> list;
   534   QMutexLocker locker( &d->mMutex );
   536                                     geometry, maxDistance );
   537   d->mRTree->nearestNeighborQuery( neighbors, r, visitor, nnc );
   539   if ( maxDistance > 0 )
   542     list.erase( std::remove_if( list.begin(), list.end(),
   545       return nnc.mFeaturesOutsideMaxDistance.contains( 
id );
   554   QMutexLocker locker( &d->mMutex );
   555   return d->mGeometries.value( 
id );
 
Wrapper for iterator of features from vector data provider or vector layer. 
 
A rectangle specified with double values. 
 
QgsGeometry geometry(QgsFeatureId id) const
Returns the stored geometry for the indexed feature with matching id. 
 
QgsSpatialIndex & operator=(const QgsSpatialIndex &other)
Implement assignment operator. 
 
double distance(const QgsGeometry &geom) const
Returns the minimum distance between this geometry and another geometry. 
 
QList< QgsFeature > QgsFeatureList
 
A class to represent a 2D point. 
 
void visitNode(const INode &n) override
 
A geometry is the spatial representation of a feature. 
 
Q_DECL_DEPRECATED bool insertFeature(const QgsFeature &feature)
Adds a feature to the index. 
 
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
 
static SpatialIndex::Region rectangleToRegion(const QgsRectangle &rectangle)
Converts a QGIS rectangle to a SpatialIndex region. 
 
bool hasGeometry() const
Returns true if the feature has an associated geometry. 
 
QgsSpatialIndexCopyVisitor(SpatialIndex::ISpatialIndex *newIndex)
 
void visitNode(const INode &n) override
 
Base class for feedback objects to be used for cancellation of something running in a worker thread...
 
QgisVisitor(QList< QgsFeatureId > &list)
 
void visitData(std::vector< const IData *> &v) override
 
This class wraps a request for features to a vector layer (or directly its vector data provider)...
 
void visitData(const IData &d) override
 
void visitData(std::vector< const IData *> &v) override
 
bool isFinite() const
Returns true if the rectangle has finite boundaries. 
 
QgsSpatialIndex(QgsSpatialIndex::Flags flags=nullptr)
Constructor for QgsSpatialIndex. 
 
void visitData(const IData &d) override
 
bool deleteFeature(const QgsFeature &feature)
Removes a feature from the index. 
 
A spatial index for QgsFeature objects. 
 
An interface for objects which provide features via a getFeatures method. 
 
bool addFeatures(QgsFeatureList &features, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the index. 
 
Custom visitor that adds found features to list. 
 
QgsRectangle boundingBox() const
Returns the bounding box of the geometry. 
 
#define FID_TO_NUMBER(fid)
 
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) override
Adds a feature to the index. 
 
QList< QgsFeatureId > nearestNeighbor(const QgsPointXY &point, int neighbors=1, double maxDistance=0) const
Returns nearest neighbors to a point. 
 
~QgsSpatialIndex() override
Destructor finalizes work with spatial index. 
 
QList< QgsFeatureId > intersects(const QgsRectangle &rectangle) const
Returns a list of features with a bounding box which intersects the specified rectangle. 
 
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object. 
 
Indicates that the spatial index should also store feature geometries. This requires more memory...
 
virtual QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const =0
Returns an iterator for the features in the source. 
 
QAtomicInt refs() const
Gets reference count - just for debugging!