23 #include <spatialindex/SpatialIndex.h> 25 #include <QMutexLocker> 32 static Region faceToRegion(
const QgsMesh &mesh,
int id )
35 const QVector<QgsMeshVertex> &vertices = mesh.
vertices;
36 Q_ASSERT( face.size() > 0 );
37 double xMinimum = vertices[face[0]].x();
38 double yMinimum = vertices[face[0]].y();
39 double xMaximum = vertices[face[0]].x();
40 double yMaximum = vertices[face[0]].y();
42 for (
int i = 1; i < face.size(); ++i )
44 xMinimum = std::min( vertices[face[i]].x(), xMinimum );
45 yMinimum = std::min( vertices[face[i]].y(), yMinimum );
46 xMaximum = std::max( vertices[face[i]].x(), xMaximum );
47 yMaximum = std::max( vertices[face[i]].y(), yMaximum );
50 double pt1[2] = { xMinimum, yMinimum };
51 double pt2[2] = { xMaximum, yMaximum };
52 return SpatialIndex::Region( pt1, pt2, 2 );
59 return SpatialIndex::Region( pt1, pt2, 2 );
68 class QgisMeshVisitor :
public SpatialIndex::IVisitor
71 explicit QgisMeshVisitor( QList<int> &list )
74 void visitNode(
const INode &n )
override 77 void visitData(
const IData &d )
override 79 mList.append( static_cast<int>( d.getIdentifier() ) );
82 void visitData( std::vector<const IData *> &v )
override 94 class QgsMeshSpatialIndexCopyVisitor :
public SpatialIndex::IVisitor
97 explicit QgsMeshSpatialIndexCopyVisitor( SpatialIndex::ISpatialIndex *newIndex )
98 : mNewIndex( newIndex ) {}
100 void visitNode(
const INode &n )
override 103 void visitData(
const IData &d )
override 105 SpatialIndex::IShape *shape =
nullptr;
106 d.getShape( &shape );
107 mNewIndex->insertData( 0,
nullptr, *shape, d.getIdentifier() );
111 void visitData( std::vector<const IData *> &v )
override 115 SpatialIndex::ISpatialIndex *mNewIndex =
nullptr;
125 class QgsMeshFaceIteratorDataStream :
public IDataStream
129 explicit QgsMeshFaceIteratorDataStream(
const QgsMesh &triangularMesh,
QgsFeedback *feedback =
nullptr )
130 : mMesh( triangularMesh )
131 , mFeedback( feedback )
136 ~QgsMeshFaceIteratorDataStream()
override 142 IData *getNext()
override 144 if ( mFeedback && mFeedback->isCanceled() )
147 RTree::Data *ret = mNextData;
154 bool hasNext()
override 156 return nullptr != mNextData;
160 uint32_t size()
override 162 return static_cast<uint32_t
>( mMesh.faceCount() );
166 void rewind()
override 174 SpatialIndex::Region r;
175 const int faceCount = mMesh.faceCount();
176 if ( mIterator < faceCount )
178 r = faceToRegion( mMesh, mIterator );
179 mNextData =
new RTree::Data(
191 RTree::Data *mNextData =
nullptr;
202 class QgsMeshSpatialIndexData :
public QSharedData
205 QgsMeshSpatialIndexData()
218 explicit QgsMeshSpatialIndexData(
const QgsMesh &fi,
QgsFeedback *feedback =
nullptr )
220 QgsMeshFaceIteratorDataStream fids( fi, feedback );
224 QgsMeshSpatialIndexData(
const QgsMeshSpatialIndexData &other )
225 : QSharedData( other )
227 QMutexLocker locker( &other.mMutex );
232 double low[] = { std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest() };
233 double high[] = { std::numeric_limits<double>::max(), std::numeric_limits<double>::max() };
234 SpatialIndex::Region query( low, high, 2 );
235 QgsMeshSpatialIndexCopyVisitor visitor( mRTree.get() );
236 other.mRTree->intersectsWithQuery( query, visitor );
239 ~QgsMeshSpatialIndexData() =
default;
241 QgsMeshSpatialIndexData &operator=(
const QgsMeshSpatialIndexData &rh ) =
delete;
243 void initTree( IDataStream *inputStream =
nullptr )
246 mStorage.reset( StorageManager::createNewMemoryStorageManager() );
249 double fillFactor = 0.7;
250 unsigned int indexCapacity = 10;
251 unsigned int leafCapacity = 10;
252 unsigned int dimension = 2;
253 RTree::RTreeVariant variant = RTree::RV_RSTAR;
256 SpatialIndex::id_type indexId;
258 if ( inputStream && inputStream->hasNext() )
260 RTree::createAndBulkLoadNewRTree(
263 *mStorage, fillFactor,
272 RTree::createNewRTree(
284 std::unique_ptr<SpatialIndex::IStorageManager> mStorage;
287 std::unique_ptr<SpatialIndex::ISpatialIndex> mRTree;
289 mutable QMutex mMutex;
297 d =
new QgsMeshSpatialIndexData;
302 d =
new QgsMeshSpatialIndexData( triangularMesh, feedback );
314 if (
this != &other )
322 QgisMeshVisitor visitor( list );
324 SpatialIndex::Region r = rectToRegion( rect );
326 QMutexLocker locker( &d->mMutex );
327 d->mRTree->intersectsWithQuery( r, visitor );
335 QgisMeshVisitor visitor( list );
337 double pt[2] = { point.
x(), point.
y() };
340 QMutexLocker locker( &d->mMutex );
341 d->mRTree->nearestNeighborQuery( static_cast<uint32_t>( neighbors ), p, visitor );
A rectangle specified with double values.
QgsMeshSpatialIndex()
Constructor for QgsSpatialIndex.
QgsMeshSpatialIndex & operator=(const QgsMeshSpatialIndex &other)
Implement assignment operator.
A class to represent a 2D point.
QList< int > intersects(const QgsRectangle &rectangle) const
Returns a list of face ids with a bounding box which intersects the specified rectangle.
QVector< QgsMeshVertex > vertices
vertices
Base class for feedback objects to be used for cancellation of something running in a worker thread...
QList< int > nearestNeighbor(const QgsPointXY &point, int neighbors) const
Returns nearest neighbors to a point.
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
double xMaximum() const
Returns the x maximum value (right side of rectangle).
A spatial index for QgsMeshFace objects.
Mesh - vertices and faces.
QVector< int > QgsMeshFace
List of vertex indexes.
double xMinimum() const
Returns the x minimum value (left side of rectangle).
~QgsMeshSpatialIndex()
Destructor finalizes work with spatial index.
QgsMeshFace face(int index) const
Returns a face at the index.
double yMaximum() const
Returns the y maximum value (top side of rectangle).