21 #include <spatialindex/SpatialIndex.h>
23 #include <QLinkedListIterator>
25 using namespace SpatialIndex;
34 return Point( plow, 2 );
40 double pLow[2], pHigh[2];
45 return SpatialIndex::Region( pLow, pHigh, 2 );
65 virtual IData*
getNext()
override {
return mIt.next(); }
66 virtual bool hasNext()
override {
return mIt.hasNext(); }
68 virtual uint32_t
size()
override { Q_ASSERT( 0 &&
"not available" );
return 0; }
69 virtual void rewind()
override { Q_ASSERT( 0 &&
"not available" ); }
72 QLinkedList<RTree::Data*> mDataList;
73 QLinkedListIterator<RTree::Data*> mIt;
85 : mLocator( pl ), mBest( m ), mSrcPoint( srcPoint ), mFilter( filter ) {}
87 void visitNode(
const INode& n )
override { Q_UNUSED( n ); }
88 void visitData( std::vector<const IData*>& v )
override { Q_UNUSED( v ); }
90 void visitData(
const IData& d )
override
94 int vertexIndex, beforeVertex, afterVertex;
100 if ( mFilter && !mFilter->acceptMatch( m ) )
103 if ( !mBest.isValid() || m.
distance() < mBest.distance() )
123 : mLocator( pl ), mBest( m ), mSrcPoint( srcPoint ), mFilter( filter ) {}
125 void visitNode(
const INode& n )
override { Q_UNUSED( n ); }
126 void visitData( std::vector<const IData*>& v )
override { Q_UNUSED( v ); }
128 void visitData(
const IData& d )
override
139 edgePoints[0] = geom->
vertexAt( afterVertex - 1 );
140 edgePoints[1] = geom->
vertexAt( afterVertex );
143 if ( mFilter && !mFilter->acceptMatch( m ) )
146 if ( !mBest.isValid() || m.
distance() < mBest.distance() )
167 : mLocator( pl ), mList( list ), mGeomPt(
QgsGeometry::fromPoint( origPt ) ) {}
171 void visitNode(
const INode& n )
override { Q_UNUSED( n ); }
172 void visitData( std::vector<const IData*>& v )
override { Q_UNUSED( v ); }
174 void visitData(
const IData& d )
override
198 static const int INSIDE = 0;
201 static const int BOTTOM = 4;
202 static const int TOP = 8;
209 if ( x < mRect.xMinimum() )
211 else if ( x > mRect.xMaximum() )
213 if ( y < mRect.yMinimum() )
215 else if ( y > mRect.yMaximum() )
220 bool isSegmentInRect(
double x0,
double y0,
double x1,
double y1 )
223 OutCode outcode0 = computeOutCode( x0, y0 );
224 OutCode outcode1 = computeOutCode( x1, y1 );
229 if ( !( outcode0 | outcode1 ) )
235 else if ( outcode0 & outcode1 )
247 OutCode outcodeOut = outcode0 ? outcode0 : outcode1;
251 if ( outcodeOut & TOP )
253 x = x0 + ( x1 - x0 ) * ( mRect.yMaximum() - y0 ) / ( y1 - y0 );
254 y = mRect.yMaximum();
256 else if ( outcodeOut & BOTTOM )
258 x = x0 + ( x1 - x0 ) * ( mRect.yMinimum() - y0 ) / ( y1 - y0 );
259 y = mRect.yMinimum();
261 else if ( outcodeOut &
RIGHT )
263 y = y0 + ( y1 - y0 ) * ( mRect.xMaximum() - x0 ) / ( x1 - x0 );
264 x = mRect.xMaximum();
266 else if ( outcodeOut &
LEFT )
268 y = y0 + ( y1 - y0 ) * ( mRect.xMinimum() - x0 ) / ( x1 - x0 );
269 x = mRect.xMinimum();
274 if ( outcodeOut == outcode0 )
278 outcode0 = computeOutCode( x0, y0 );
284 outcode1 = computeOutCode( x1, y1 );
299 unsigned char* wkb =
const_cast<unsigned char*
>( geom->
asWkb() );
309 bool hasZValue =
false;
329 double prevx = 0.0, prevy = 0.0;
333 wkbPtr >> thisx >> thisy;
335 wkbPtr +=
sizeof( double );
342 edgePoints[0].
set( prevx, prevy );
343 edgePoints[1].
set( thisx, thisy );
361 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
363 wkbPtr += 1 +
sizeof( int );
367 double prevx = 0.0, prevy = 0.0;
368 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
371 wkbPtr >> thisx >> thisy;
373 wkbPtr +=
sizeof( double );
380 edgePoints[0].
set( prevx, prevy );
381 edgePoints[1].
set( thisx, thisy );
402 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
407 double prevx = 0.0, prevy = 0.0;
408 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
411 wkbPtr >> thisx >> thisy;
413 wkbPtr +=
sizeof( double );
420 edgePoints[0].
set( prevx, prevy );
421 edgePoints[1].
set( thisx, thisy );
441 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
443 wkbPtr += 1 +
sizeof( int );
446 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
451 double prevx = 0.0, prevy = 0.0;
452 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
455 wkbPtr >> thisx >> thisy;
457 wkbPtr +=
sizeof( double );
464 edgePoints[0].
set( prevx, prevy );
465 edgePoints[1].
set( thisx, thisy );
493 : mLocator( pl ), mList( lst ), mSrcRect( srcRect ), mFilter( filter ) {}
495 void visitNode(
const INode& n )
override { Q_UNUSED( n ); }
496 void visitData( std::vector<const IData*>& v )
override { Q_UNUSED( v ); }
498 void visitData(
const IData& d )
override
506 if ( mFilter && !mFilter->acceptMatch( m ) )
533 void getNextEntry(
const IEntry& entry, id_type& nextEntry,
bool& hasNext )
override
535 const INode* n =
dynamic_cast<const INode*
>( &entry );
539 qDebug(
"NODE: %ld", n->getIdentifier() );
540 if ( n->getLevel() > 0 )
543 for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
545 qDebug(
"- CH: %ld", n->getChildIdentifier( cChild ) );
546 ids.push( n->getChildIdentifier( cChild ) );
552 for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
554 qDebug(
"- L: %ld", n->getChildIdentifier( cChild ) );
560 nextEntry = ids.back(); ids.pop();
574 , mIsEmptyLayer( false )
589 mStorage = StorageManager::createNewMemoryStorageManager();
613 return mRTree != 0 || mIsEmptyLayer;
622 QLinkedList<RTree::Data*> dataList;
639 QgsDebugMsg( QString(
"could not transform bounding box to map, skipping the snap filter (%1)").arg(e.
what()) );
645 int indexedCount = 0;
657 QgsDebugMsg( QString(
"could not transform geometry to map, skipping the snap for it (%1)").arg(e.
what()) );
663 dataList <<
new RTree::Data( 0, 0, r, f.
id() );
667 if ( maxFeaturesToIndex != -1 && indexedCount > maxFeaturesToIndex )
669 qDeleteAll( dataList );
676 double fillFactor = 0.7;
677 unsigned long indexCapacity = 10;
678 unsigned long leafCapacity = 10;
679 unsigned long dimension = 2;
680 RTree::RTreeVariant variant = RTree::RV_RSTAR;
681 SpatialIndex::id_type indexId;
683 if ( dataList.isEmpty() )
685 mIsEmptyLayer =
true;
690 mRTree = RTree::createAndBulkLoadNewRTree( RTree::BLM_STR, stream, *mStorage, fillFactor, indexCapacity,
691 leafCapacity, dimension, variant, indexId );
701 mIsEmptyLayer =
false;
708 void QgsPointLocator::onFeatureAdded(
QgsFeatureId fid )
729 QgsDebugMsg( QString(
"could not transform geometry to map, skipping the snap for it (%1)").arg(e.
what()) );
735 mRTree->insertData( 0, 0, r, f.
id() );
740 void QgsPointLocator::onFeatureDeleted(
QgsFeatureId fid )
745 if ( mGeoms.contains( fid ) )
747 mRTree->deleteData(
rect2region( mGeoms[fid]->boundingBox() ), fid );
748 mGeoms.remove( fid );
755 onFeatureDeleted( fid );
756 onFeatureAdded( fid );
771 QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
772 mRTree->intersectsWithQuery(
rect2region( rect ), visitor );
789 QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
790 mRTree->intersectsWithQuery(
rect2region( rect ), visitor );
807 mRTree->intersectsWithQuery(
rect2region( rect ), visitor );
814 QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
830 mRTree->intersectsWithQuery(
point2point( point ), visitor );