18#include <spatialindex/SpatialIndex.h>
36#include <QLinkedListIterator>
37#include <QtConcurrent>
39#include "moc_qgspointlocator.cpp"
45static SpatialIndex::Point point2point(
const QgsPointXY &point )
47 double plow[2] = { point.
x(), point.
y() };
48 return Point( plow, 2 );
56static const double POINT_LOC_EPSILON = 1e-12;
70 : mDataList( dataList )
74 IData *
getNext()
override {
return mIt.next(); }
75 bool hasNext()
override {
return mIt.hasNext(); }
77 uint32_t
size()
override { Q_ASSERT(
false &&
"not available" );
return 0; }
78 void rewind()
override { Q_ASSERT(
false &&
"not available" ); }
81 QLinkedList<RTree::Data *> mDataList;
82 QLinkedListIterator<RTree::Data *> mIt;
100 , mSrcPoint( srcPoint )
104 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
105 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
113 int vertexIndex, beforeVertex, afterVertex;
122 if ( mFilter && !mFilter->acceptMatch( m ) )
125 if ( !mBest.isValid() || m.
distance() < mBest.distance() )
157 , mSrcPoint( srcPoint )
161 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
162 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
175 if ( mFilter && !mFilter->acceptMatch( m ) )
178 if ( !mBest.isValid() || m.
distance() < mBest.distance() )
211 , mSrcPoint( srcPoint )
215 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
216 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
232 edgePoints[0] = geom->
vertexAt( afterVertex - 1 );
233 edgePoints[1] = geom->
vertexAt( afterVertex );
234 pt =
QgsPointXY( ( edgePoints[0].x() + edgePoints[1].x() ) / 2.0, ( edgePoints[0].y() + edgePoints[1].y() ) / 2.0 );
238 if ( mFilter && !mFilter->acceptMatch( m ) )
241 if ( !mBest.isValid() || m.
distance() < mBest.distance() )
272 , mSrcPoint( srcPoint )
276 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
277 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
282 const QgsGeometry *geom = mLocator->mGeoms.value(
id );
287 int bestVertexNumber = -1;
288 auto replaceIfBetter = [
this, &bestPoint, &bestVertexNumber](
const QgsPoint & candidate,
int vertexNumber )
290 if ( bestPoint.
isEmpty() || candidate.distanceSquared( mSrcPoint.x(), mSrcPoint.y() ) < bestPoint.
sqrDist( mSrcPoint ) )
293 bestVertexNumber = vertexNumber;
306 int partStartVertexNum = 0;
311 replaceIfBetter( curve->startPoint(), partStartVertexNum );
312 replaceIfBetter( curve->endPoint(), partStartVertexNum + curve->numPoints() - 1 );
313 partStartVertexNum += curve->numPoints();
321 int partStartVertexNum = 0;
326 if ( polygon->exteriorRing() )
328 replaceIfBetter( polygon->exteriorRing()->startPoint(), partStartVertexNum );
329 partStartVertexNum += polygon->exteriorRing()->numPoints();
331 for (
int i = 0; i < polygon->numInteriorRings(); ++i )
333 const QgsCurve *ring = polygon->interiorRing( i );
334 replaceIfBetter( ring->
startPoint(), partStartVertexNum );
345 if ( mFilter && !mFilter->acceptMatch( m ) )
348 if ( !mBest.isValid() || m.
distance() < mBest.distance() )
374 , mSrcPoint( srcPoint )
378 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
379 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
395 edgePoints[0] = geom->
vertexAt( afterVertex - 1 );
396 edgePoints[1] = geom->
vertexAt( afterVertex );
399 if ( mFilter && !mFilter->acceptMatch( m ) )
402 if ( !mBest.isValid() || m.
distance() < mBest.distance() )
432 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
433 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
445 if ( mFilter && !mFilter->acceptMatch( m ) )
479 if ( x <
mRect.xMinimum() )
481 else if ( x >
mRect.xMaximum() )
483 if ( y <
mRect.yMinimum() )
485 else if ( y >
mRect.yMaximum() )
499 if ( !( outcode0 | outcode1 ) )
505 else if ( outcode0 & outcode1 )
517 const OutCode outcodeOut = outcode0 ? outcode0 : outcode1;
521 if ( outcodeOut &
TOP )
524 x = x0 + ( x1 - x0 ) * (
mRect.yMaximum() - y0 ) / ( y1 - y0 );
525 y =
mRect.yMaximum();
527 else if ( outcodeOut &
BOTTOM )
530 x = x0 + ( x1 - x0 ) * (
mRect.yMinimum() - y0 ) / ( y1 - y0 );
531 y =
mRect.yMinimum();
533 else if ( outcodeOut &
RIGHT )
536 y = y0 + ( y1 - y0 ) * (
mRect.xMaximum() - x0 ) / ( x1 - x0 );
537 x =
mRect.xMaximum();
539 else if ( outcodeOut &
LEFT )
542 y = y0 + ( y1 - y0 ) * (
mRect.xMinimum() - x0 ) / ( x1 - x0 );
543 x =
mRect.xMinimum();
550 if ( outcodeOut == outcode0 )
603 while ( it != ( *part )->vertices_end() )
606 if ( cs.isSegmentInRect( prevPoint.x(), prevPoint.y(), thisPoint.x(), thisPoint.y() ) )
609 edgePoints[0] = prevPoint;
610 edgePoints[1] = thisPoint;
633 , mSrcRect( srcRect )
637 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
638 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
647 const auto segmentsInRect {_geometrySegmentsInRect( geom, mSrcRect, mLocator->mLayer,
id )};
651 if ( mFilter && !mFilter->acceptMatch( m ) )
680 , mSrcRect( srcRect )
684 void visitNode(
const INode &n )
override { Q_UNUSED( n ) }
685 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ) }
690 const QgsGeometry *geom = mLocator->mGeoms.value(
id );
696 if ( mSrcRect.contains( *it ) )
701 if ( mFilter && !mFilter->acceptMatch( m ) )
729 , mSrcRect( srcRect )
733 void visitNode(
const INode &n )
override { Q_UNUSED( n ); }
734 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ); }
739 const QgsGeometry *geom = mLocator->mGeoms.value(
id );
744 if ( mSrcRect.contains( centroid ) )
749 if ( !( mFilter && !mFilter->acceptMatch( m ) ) )
774 , mSrcRect( srcRect )
778 void visitNode(
const INode &n )
override { Q_UNUSED( n ); }
779 void visitData( std::vector<const IData *> &v )
override { Q_UNUSED( v ); }
784 const QgsGeometry *geom = mLocator->mGeoms.value(
id );
793 for ( ; it != geom->
vertices_end(); ++it, ++itPrevious )
795 const QgsPointXY pt( ( ( *itPrevious ).x() + ( *it ).x() ) / 2.0, ( ( *itPrevious ).y() + ( *it ).y() ) / 2.0 );
796 if ( mSrcRect.contains( pt ) )
801 if ( mFilter && !mFilter->acceptMatch( m ) )
833 void getNextEntry(
const IEntry &entry, id_type &nextEntry,
bool &hasNext )
override
835 const INode *n =
dynamic_cast<const INode *
>( &entry );
839 QgsDebugMsgLevel( QStringLiteral(
"NODE: %1" ).arg( n->getIdentifier() ), 4 );
840 if ( n->getLevel() > 0 )
843 for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
845 QgsDebugMsgLevel( QStringLiteral(
"- CH: %1" ).arg( n->getChildIdentifier( cChild ) ), 4 );
846 ids.push( n->getChildIdentifier( cChild ) );
852 for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
854 QgsDebugMsgLevel( QStringLiteral(
"- L: %1" ).arg( n->getChildIdentifier( cChild ) ), 4 );
860 nextEntry = ids.back();
877 mTransform = QgsCoordinateTransform( layer->crs(), destCRS, transformContext );
882 mStorage.reset( StorageManager::createNewMemoryStorageManager() );
895 mIsDestroying =
true;
927 mContext.reset(
nullptr );
931 mContext = std::make_unique<QgsRenderContext>( *context );
937void QgsPointLocator::onInitTaskFinished()
939 Q_ASSERT_X( QThread::currentThread() == qApp->thread(),
"QgsPointLocator::onInitTaskFinished",
"was not called on main thread" );
954 for (
const QgsFeatureId fid : std::as_const( mAddedFeatures ) )
955 onFeatureAdded( fid );
956 mAddedFeatures.clear();
958 for (
const QgsFeatureId fid : std::as_const( mDeletedFeatures ) )
959 onFeatureDeleted( fid );
960 mDeletedFeatures.clear();
973 if ( !mLayer->dataProvider()
974 || !mLayer->dataProvider()->isValid() )
977 mSource = std::make_unique<QgsVectorLayerFeatureSource>( mLayer );
981 mRenderer.reset( mLayer->renderer() ? mLayer->renderer()->clone() :
nullptr );
990 connect( mInitTask, &QgsPointLocatorInitTask::taskTerminated,
this, &QgsPointLocator::onInitTaskFinished );
991 connect( mInitTask, &QgsPointLocatorInitTask::taskCompleted,
this, &QgsPointLocator::onInitTaskFinished );
1007 disconnect( mInitTask, &QgsPointLocatorInitTask::taskTerminated,
this, &QgsPointLocator::onInitTaskFinished );
1008 disconnect( mInitTask, &QgsPointLocatorInitTask::taskCompleted,
this, &QgsPointLocator::onInitTaskFinished );
1009 mInitTask->waitForFinished();
1011 if ( !mIsDestroying )
1012 onInitTaskFinished();
1017 return mIsIndexing || mRTree || mIsEmptyLayer;
1020bool QgsPointLocator::prepare(
bool relaxed )
1032 init( -1, relaxed );
1033 if ( ( relaxed && mIsIndexing ) || !mRTree )
1045 QgsDebugMsgLevel( QStringLiteral(
"RebuildIndex start : %1" ).arg( mSource->id() ), 2 );
1049 QLinkedList<RTree::Data *> dataList;
1058 if ( !mTransform.isShortCircuited() )
1070 QgsDebugError( QStringLiteral(
"could not transform bounding box to map, skipping the snap filter (%1)" ).arg( e.
what() ) );
1076 bool filter =
false;
1080 ctx = mContext.get();
1084 mRenderer->startRender( *ctx, mSource->fields() );
1091 int indexedCount = 0;
1098 if ( filter && ctx && mRenderer )
1101 if ( !mRenderer->willRenderFeature( f, *ctx ) )
1107 if ( mTransform.isValid() )
1112 transformedGeometry.
transform( mTransform );
1119 QgsDebugError( QStringLiteral(
"could not transform geometry to map, skipping the snap for it (%1)" ).arg( e.
what() ) );
1128 dataList <<
new RTree::Data( 0,
nullptr, r, f.
id() );
1130 auto it = mGeoms.find( f.
id() );
1131 if ( it != mGeoms.end() )
1143 if ( maxFeaturesToIndex != -1 && indexedCount > maxFeaturesToIndex )
1145 qDeleteAll( dataList );
1152 const double fillFactor = 0.7;
1153 const unsigned long indexCapacity = 10;
1154 const unsigned long leafCapacity = 10;
1155 const unsigned long dimension = 2;
1156 const RTree::RTreeVariant variant = RTree::RV_RSTAR;
1157 SpatialIndex::id_type indexId;
1159 if ( dataList.isEmpty() )
1161 mIsEmptyLayer =
true;
1168 mRTree.reset( RTree::createAndBulkLoadNewRTree( RTree::BLM_STR, stream, *mStorage, fillFactor, indexCapacity,
1169 leafCapacity, dimension, variant, indexId ) );
1171 catch (
const std::exception &e )
1173 QgsDebugError( QStringLiteral(
"An exception has occurred during the creation of RTree: %1" ).arg( e.what() ) );
1179 if ( ctx && mRenderer )
1181 mRenderer->stopRender( *ctx );
1184 QgsDebugMsgLevel( QStringLiteral(
"RebuildIndex end : %1 ms (%2)" ).arg( t.elapsed() ).arg( mSource->id() ), 2 );
1194 mIsEmptyLayer =
false;
1196 qDeleteAll( mGeoms );
1201void QgsPointLocator::onFeatureAdded(
QgsFeatureId fid )
1206 mAddedFeatures << fid;
1212 if ( mIsEmptyLayer )
1215 mIsEmptyLayer =
false;
1222 if ( mLayer->getFeatures( mContext ? QgsFeatureRequest( fid ) : QgsFeatureRequest( fid ).setNoAttributes() ).nextFeature( f ) )
1229 std::unique_ptr< QgsFeatureRenderer > renderer( mLayer->renderer() ? mLayer->renderer()->clone() :
nullptr );
1230 QgsRenderContext *ctx =
nullptr;
1233 ctx = mContext.get();
1234 if ( renderer && ctx )
1237 renderer->startRender( *ctx, mLayer->fields() );
1240 if ( !renderer->willRenderFeature( f, *ctx ) )
1245 renderer->stopRender( *ctx );
1251 if ( mTransform.isValid() )
1255 QgsGeometry transformedGeom = f.
geometry();
1256 transformedGeom.
transform( mTransform );
1259 catch (
const QgsException &e )
1263 QgsDebugError( QStringLiteral(
"could not transform geometry to map, skipping the snap for it (%1)" ).arg( e.
what() ) );
1272 mRTree->insertData( 0,
nullptr, r, f.
id() );
1274 auto it = mGeoms.find( f.
id() );
1275 if ( it != mGeoms.end() )
1278 *it =
new QgsGeometry( f.
geometry() );
1282 mGeoms[fid] =
new QgsGeometry( f.
geometry() );
1288void QgsPointLocator::onFeatureDeleted(
QgsFeatureId fid )
1292 if ( mAddedFeatures.contains( fid ) )
1294 mAddedFeatures.remove( fid );
1299 mDeletedFeatures << fid;
1307 auto it = mGeoms.find( fid );
1308 if ( it != mGeoms.end() )
1320 onFeatureDeleted( fid );
1321 onFeatureAdded( fid );
1324void QgsPointLocator::onAttributeValueChanged(
QgsFeatureId fid,
int idx,
const QVariant &value )
1330 onFeatureDeleted( fid );
1331 onFeatureAdded( fid );
1338 if ( !prepare( relaxed ) )
1343 const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
1352 if ( !prepare( relaxed ) )
1358 const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
1367 if ( !prepare( relaxed ) )
1373 const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
1382 if ( !prepare( relaxed ) )
1388 const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
1397 if ( !prepare( relaxed ) )
1406 const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
1415 if ( !prepare( relaxed ) )
1419 if ( !mlist.isEmpty() && mlist.at( 0 ).isValid() )
1421 return mlist.at( 0 );
1424 if ( tolerance == 0 )
1445 if ( !prepare( relaxed ) )
1461 const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
1467 if ( !prepare( relaxed ) )
1479 const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
1486 if ( !prepare( relaxed ) )
1495 mRTree->intersectsWithQuery( point2point( point ), visitor );
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
@ Reverse
Reverse/inverse transform (from destination to source).
The part_iterator class provides an STL-style iterator for const references to geometry parts.
The vertex_iterator class provides an STL-style iterator for vertices.
QgsVertexId vertexId() const
Returns vertex ID of the current item.
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
static QgsTaskManager * taskManager()
Returns the application's task manager, used for managing application wide background task handling.
Represents a coordinate reference system (CRS).
bool isValid() const
Returns whether this CRS is correctly initialized and usable.
Contains information about the context in which a coordinate transform is executed.
Curve polygon geometry type.
Abstract base class for curved geometry type.
virtual int numPoints() const =0
Returns the number of points in the curve.
virtual QgsPoint startPoint() const =0
Returns the starting point of the curve.
Defines a QGIS exception class.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
A geometry is the spatial representation of a feature.
double closestSegmentWithContext(const QgsPointXY &point, QgsPointXY &minDistPoint, int &nextVertexIndex, int *leftOrRightOfSegment=nullptr, double epsilon=Qgis::DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
QgsGeometry convertToType(Qgis::GeometryType destType, bool destMultipart=false) const
Try to convert the geometry to the requested type.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false)
Transforms this geometry as described by the coordinate transform ct.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
QgsPointXY closestVertex(const QgsPointXY &point, int &closestVertexIndex, int &previousVertexIndex, int &nextVertexIndex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
void convertToStraightSegment(double tolerance=M_PI/180., QgsAbstractGeometry::SegmentationToleranceType toleranceType=QgsAbstractGeometry::MaximumAngle)
Converts the geometry to straight line segments, if it is a curved geometry type.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
bool isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
int vertexNrFromVertexId(QgsVertexId id) const
Returns the vertex number corresponding to a vertex id.
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry.
QgsAbstractGeometry::vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Qgis::WkbType wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.).
bool intersects(const QgsRectangle &rectangle) const
Returns true if this geometry exactly intersects with a rectangle.
QgsAbstractGeometry::vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
void styleChanged()
Signal emitted whenever a change affects the layer's style.
void dataChanged()
Data of layer changed.
Helper class to dump the R-index nodes and their content.
void getNextEntry(const IEntry &entry, id_type &nextEntry, bool &hasNext) override
Helper class for bulk loading of R-trees.
IData * getNext() override
QgsPointLocator_Stream(const QLinkedList< RTree::Data * > &dataList)
void visitNode(const INode &n) override
void visitData(const IData &d) override
void visitData(std::vector< const IData * > &v) override
QgsPointLocator_VisitorArea(QgsPointLocator *pl, const QgsPointXY &origPt, QgsPointLocator::MatchList &list, QgsPointLocator::MatchFilter *filter=nullptr)
constructor
QgsPointLocator_VisitorCentroidsInRect(QgsPointLocator *pl, QgsPointLocator::MatchList &lst, const QgsRectangle &srcRect, QgsPointLocator::MatchFilter *filter=nullptr)
Constructs the visitor.
void visitData(const IData &d) override
void visitData(std::vector< const IData * > &v) override
void visitNode(const INode &n) override
void visitData(std::vector< const IData * > &v) override
QgsPointLocator_VisitorEdgesInRect(QgsPointLocator *pl, QgsPointLocator::MatchList &lst, const QgsRectangle &srcRect, QgsPointLocator::MatchFilter *filter=nullptr)
void visitNode(const INode &n) override
void visitData(const IData &d) override
void visitData(std::vector< const IData * > &v) override
void visitNode(const INode &n) override
void visitData(const IData &d) override
QgsPointLocator_VisitorMiddlesInRect(QgsPointLocator *pl, QgsPointLocator::MatchList &lst, const QgsRectangle &srcRect, QgsPointLocator::MatchFilter *filter=nullptr)
Constructs the visitor.
void visitData(const IData &d) override
void visitNode(const INode &n) override
void visitData(std::vector< const IData * > &v) override
QgsPointLocator_VisitorNearestEdge(QgsPointLocator *pl, QgsPointLocator::Match &m, const QgsPointXY &srcPoint, QgsPointLocator::MatchFilter *filter=nullptr)
void visitData(const IData &d) override
void visitData(std::vector< const IData * > &v) override
void visitNode(const INode &n) override
void visitData(std::vector< const IData * > &v) override
void visitNode(const INode &n) override
void visitData(const IData &d) override
void visitData(std::vector< const IData * > &v) override
void visitData(const IData &d) override
void visitNode(const INode &n) override
void visitData(const IData &d) override
void visitNode(const INode &n) override
void visitData(std::vector< const IData * > &v) override
QgsPointLocator_VisitorNearestVertex(QgsPointLocator *pl, QgsPointLocator::Match &m, const QgsPointXY &srcPoint, QgsPointLocator::MatchFilter *filter=nullptr)
void visitData(const IData &d) override
void visitNode(const INode &n) override
void visitData(std::vector< const IData * > &v) override
QgsPointLocator_VisitorVerticesInRect(QgsPointLocator *pl, QgsPointLocator::MatchList &lst, const QgsRectangle &srcRect, QgsPointLocator::MatchFilter *filter=nullptr)
Constructs the visitor.
Defines the interface for querying point locations.
friend class QgsPointLocator_VisitorNearestLineEndpoint
friend class QgsPointLocatorInitTask
friend class QgsPointLocator_VisitorEdgesInRect
Match nearestEdge(const QgsPointXY &point, double tolerance, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find nearest edge to the specified point - up to distance specified by tolerance Optional filter may ...
friend class QgsPointLocator_VisitorNearestVertex
void setRenderContext(const QgsRenderContext *context)
Configure render context - if not nullptr, it will use to index only visible feature.
QgsCoordinateReferenceSystem destinationCrs() const
Gets destination CRS - may be an invalid QgsCoordinateReferenceSystem if not doing OTF reprojection.
friend class QgsPointLocator_VisitorNearestCentroid
MatchList pointInPolygon(const QgsPointXY &point, bool relaxed=false, QgsPointLocator::MatchFilter *filter=nullptr)
Find out if the point is in any polygons.
void setExtent(const QgsRectangle *extent)
Configure extent - if not nullptr, it will index only that area.
bool init(int maxFeaturesToIndex=-1, bool relaxed=false)
Prepare the index for queries.
QgsVectorLayer * layer() const
Gets associated layer.
friend class QgsPointLocator_VisitorNearestMiddleOfSegment
MatchList verticesInRect(const QgsRectangle &rect, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find vertices within a specified rectangle This method is either blocking or non blocking according t...
class QList< QgsPointLocator::Match > MatchList
Match nearestVertex(const QgsPointXY &point, double tolerance, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find nearest vertex to the specified point - up to distance specified by tolerance Optional filter ma...
friend class QgsPointLocator_VisitorNearestEdge
const QgsRectangle * extent() const
Gets extent of the area point locator covers - if nullptr then it caches the whole layer.
MatchList edgesInRect(const QgsRectangle &rect, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find edges within a specified rectangle Optional filter may discard unwanted matches.
bool hasIndex() const
Indicate whether the data have been already indexed.
friend class QgsPointLocator_VisitorVerticesInRect
Match nearestMiddleOfSegment(const QgsPointXY &point, double tolerance, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find nearest middle of segment to the specified point - up to distance specified by tolerance Optiona...
void waitForIndexingFinished()
If the point locator has been initialized relaxedly and is currently indexing, this methods waits for...
Match nearestCentroid(const QgsPointXY &point, double tolerance, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find nearest centroid to the specified point - up to distance specified by tolerance Optional filter ...
void initFinished(bool ok)
Emitted whenever index has been built and initialization is finished.
bool rebuildIndex(int maxFeaturesToIndex=-1)
Match nearestArea(const QgsPointXY &point, double tolerance, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find nearest area to the specified point - up to distance specified by tolerance Optional filter may ...
@ Area
Snapped to an area.
@ MiddleOfSegment
Snapped to the middle of a segment.
@ Vertex
Snapped to a vertex. Can be a vertex of the geometry or an intersection.
@ Centroid
Snapped to a centroid.
@ Edge
Snapped to an edge.
@ LineEndpoint
Start or end points of lines only.
QgsPointLocator(QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem(), const QgsCoordinateTransformContext &transformContext=QgsCoordinateTransformContext(), const QgsRectangle *extent=nullptr)
Construct point locator for a layer.
~QgsPointLocator() override
friend class QgsPointLocator_VisitorArea
Match nearestLineEndpoints(const QgsPointXY &point, double tolerance, QgsPointLocator::MatchFilter *filter=nullptr, bool relaxed=false)
Find nearest line endpoint (start or end vertex) to the specified point - up to distance specified by...
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
bool isEmpty() const
Returns true if the geometry is empty.
Point geometry type, with support for z-dimension and m-values.
A rectangle specified with double values.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Contains information about the context of a rendering operation.
QgsExpressionContext & expressionContext()
Gets the expression context.
static SpatialIndex::Region rectangleToRegion(const QgsRectangle &rectangle)
Converts a QGIS rectangle to a SpatialIndex region.
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
Represents a vector layer which manages a vector based dataset.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
void featureAdded(QgsFeatureId fid)
Emitted when a new feature has been added to the layer.
void featureDeleted(QgsFeatureId fid)
Emitted when a feature has been deleted.
void geometryChanged(QgsFeatureId fid, const QgsGeometry &geometry)
Emitted whenever a geometry change is done in the edit buffer.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
QgsPointLocator_VisitorNearestCentroid(QgsPointLocator *pl, QgsPointLocator::Match &m, const QgsPointXY &srcPoint, QgsPointLocator::MatchFilter *filter=nullptr)
Helper class used when traversing the index looking for centroid - builds a list of matches.
QgsPointLocator_VisitorNearestMiddleOfSegment(QgsPointLocator *pl, QgsPointLocator::Match &m, const QgsPointXY &srcPoint, QgsPointLocator::MatchFilter *filter=nullptr)
Helper class used when traversing the index looking for middle segment - builds a list of matches.
QgsPointLocator_VisitorNearestLineEndpoint(QgsPointLocator *pl, QgsPointLocator::Match &m, const QgsPointXY &srcPoint, QgsPointLocator::MatchFilter *filter=nullptr)
Helper class used when traversing the index looking for line endpoints (start or end vertex) - builds...
T qgsgeometry_cast(QgsAbstractGeometry *geom)
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
Interface that allows rejection of some matches in intersection queries (e.g.
QgsFeatureId featureId() const
The id of the feature to which the snapped geometry belongs.
QgsVectorLayer * layer() const
The vector layer where the snap occurred.
double distance() const
for vertex / edge match units depending on what class returns it (geom.cache: layer units,...
QgsPointXY point() const
for vertex / edge match coords depending on what class returns it (geom.cache: layer coords,...
OutCode computeOutCode(double x, double y)
bool isSegmentInRect(double x0, double y0, double x1, double y1)
_CohenSutherland(const QgsRectangle &rect)