32#include <spatialindex/SpatialIndex.h> 
   34#include <QLinkedListIterator> 
   35#include <QtConcurrent> 
   41static SpatialIndex::Point point2point( 
const QgsPointXY &point )
 
   43  double plow[2] = { point.
x(), point.
y() };
 
   44  return Point( plow, 2 );
 
   48static SpatialIndex::Region rect2region( 
const QgsRectangle &rect )
 
   52  return SpatialIndex::Region( pLow, pHigh, 2 );
 
   60static const double POINT_LOC_EPSILON = 1e-12;
 
   74      : mDataList( dataList )
 
   78    IData *
getNext()
 override { 
return mIt.next(); }
 
   79    bool hasNext()
 override { 
return mIt.hasNext(); }
 
   81    uint32_t 
size()
 override { Q_ASSERT( 
false && 
"not available" ); 
return 0; }
 
   82    void rewind()
 override { Q_ASSERT( 
false && 
"not available" ); }
 
   85    QLinkedList<RTree::Data *> mDataList;
 
   86    QLinkedListIterator<RTree::Data *> mIt;
 
  104      , mSrcPoint( srcPoint )
 
  108    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  109    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  117      int vertexIndex, beforeVertex, afterVertex;
 
  161      , mSrcPoint( srcPoint )
 
  165    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  166    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  215      , mSrcPoint( srcPoint )
 
  219    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  220    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  236      edgePoints[0] = geom->
vertexAt( afterVertex - 1 );
 
  237      edgePoints[1] = geom->
vertexAt( afterVertex );
 
  238      pt = 
QgsPointXY( ( edgePoints[0].x() + edgePoints[1].x() ) / 2.0, ( edgePoints[0].y() + edgePoints[1].y() ) / 2.0 );
 
  276      , mSrcPoint( srcPoint )
 
  280    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  281    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  286      const QgsGeometry *geom = mLocator->mGeoms.value( 
id );
 
  291      int bestVertexNumber = -1;
 
  292      auto replaceIfBetter = [
this, &bestPoint, &bestVertexNumber]( 
const QgsPoint & candidate, 
int vertexNumber )
 
  294        if ( bestPoint.
isEmpty() || candidate.distanceSquared( mSrcPoint.
x(), mSrcPoint.
y() ) < bestPoint.
sqrDist( mSrcPoint ) )
 
  297          bestVertexNumber = vertexNumber;
 
  303        case Qgis::GeometryType::Point:
 
  304        case Qgis::GeometryType::Unknown:
 
  305        case Qgis::GeometryType::Null:
 
  308        case Qgis::GeometryType::Line:
 
  310          int partStartVertexNum = 0;
 
  313            if ( 
const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( *partIt ) )
 
  315              replaceIfBetter( curve->startPoint(), partStartVertexNum );
 
  316              replaceIfBetter( curve->endPoint(), partStartVertexNum + curve->numPoints() - 1 );
 
  317              partStartVertexNum += curve->numPoints();
 
  323        case Qgis::GeometryType::Polygon:
 
  325          int partStartVertexNum = 0;
 
  328            if ( 
const QgsCurvePolygon *polygon = qgsgeometry_cast< const QgsCurvePolygon * >( *partIt ) )
 
  330              if ( polygon->exteriorRing() )
 
  332                replaceIfBetter( polygon->exteriorRing()->startPoint(), partStartVertexNum );
 
  333                partStartVertexNum += polygon->exteriorRing()->numPoints();
 
  335              for ( 
int i = 0; i < polygon->numInteriorRings(); ++i )
 
  337                const QgsCurve *ring = polygon->interiorRing( i );
 
  338                replaceIfBetter( ring->
startPoint(), partStartVertexNum );
 
  378      , mSrcPoint( srcPoint )
 
  382    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  383    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  399      edgePoints[0] = geom->
vertexAt( afterVertex - 1 );
 
  400      edgePoints[1] = geom->
vertexAt( afterVertex );
 
  435    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  436    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  496      if ( !( outcode0 | outcode1 ) )
 
  502      else if ( outcode0 & outcode1 )
 
  514        const OutCode outcodeOut = outcode0 ? outcode0 : outcode1;
 
  518        if ( outcodeOut & 
TOP )
 
  521          x = x0 + ( x1 - x0 ) * ( 
mRect.
yMaximum() - y0 ) / ( y1 - y0 );
 
  524        else if ( outcodeOut & 
BOTTOM )
 
  527          x = x0 + ( x1 - x0 ) * ( 
mRect.
yMinimum() - y0 ) / ( y1 - y0 );
 
  530        else if ( outcodeOut & 
RIGHT )
 
  533          y = y0 + ( y1 - y0 ) * ( 
mRect.
xMaximum() - x0 ) / ( x1 - x0 );
 
  536        else if ( outcodeOut & 
LEFT )
 
  539          y = y0 + ( y1 - y0 ) * ( 
mRect.
xMinimum() - x0 ) / ( x1 - x0 );
 
  547        if ( outcodeOut == outcode0 )
 
  582  if ( straightGeom.
isEmpty() || ( ( straightGeom.
type() != Qgis::GeometryType::Line ) && ( !straightGeom.
isMultipart() ) ) )
 
  592    QgsCurve *curve = qgsgeometry_cast<QgsCurve *>( *part );
 
  600    while ( it != ( *part )->vertices_end() )
 
  603      if ( cs.isSegmentInRect( prevPoint.x(), prevPoint.y(), thisPoint.x(), thisPoint.y() ) )
 
  606        edgePoints[0] = prevPoint;
 
  607        edgePoints[1] = thisPoint;
 
  630      , mSrcRect( srcRect )
 
  634    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  635    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  644      const auto segmentsInRect {_geometrySegmentsInRect( geom, mSrcRect, mLocator->mLayer, 
id )};
 
  677      , mSrcRect( srcRect )
 
  681    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ) }
 
  682    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ) }
 
  687      const QgsGeometry *geom = mLocator->mGeoms.value( 
id );
 
  726      , mSrcRect( srcRect )
 
  730    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ); }
 
  731    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ); }
 
  736      const QgsGeometry *geom = mLocator->mGeoms.value( 
id );
 
  771      , mSrcRect( srcRect )
 
  775    void visitNode( 
const INode &n )
 override { Q_UNUSED( n ); }
 
  776    void visitData( std::vector<const IData *> &v )
 override { Q_UNUSED( v ); }
 
  781      const QgsGeometry *geom = mLocator->mGeoms.value( 
id );
 
  790        for ( ; it != geom->
vertices_end(); ++it, ++itPrevious )
 
  792          const QgsPointXY pt( ( ( *itPrevious ).x() + ( *it ).x() ) / 2.0, ( ( *itPrevious ).y() + ( *it ).y() ) / 2.0 );
 
  829    void getNextEntry( 
const IEntry &entry, id_type &nextEntry, 
bool &hasNext )
 override 
  831      const INode *n = 
dynamic_cast<const INode *
>( &entry );
 
  835      QgsDebugMsgLevel( QStringLiteral( 
"NODE: %1" ).arg( n->getIdentifier() ), 4 );
 
  836      if ( n->getLevel() > 0 )
 
  839        for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
 
  841          QgsDebugMsgLevel( QStringLiteral( 
"- CH: %1" ).arg( n->getChildIdentifier( cChild ) ), 4 );
 
  842          ids.push( n->getChildIdentifier( cChild ) );
 
  848        for ( uint32_t cChild = 0; cChild < n->getChildrenCount(); cChild++ )
 
  850          QgsDebugMsgLevel( QStringLiteral( 
"- L: %1" ).arg( n->getChildIdentifier( cChild ) ), 4 );
 
  856        nextEntry = ids.back();
 
  878  mStorage.reset( StorageManager::createNewMemoryStorageManager() );
 
  891  mIsDestroying = 
true;
 
  923  mContext.reset( 
nullptr );
 
  927    mContext = std::unique_ptr<QgsRenderContext>( 
new QgsRenderContext( *context ) );
 
  933void QgsPointLocator::onInitTaskFinished()
 
  935  Q_ASSERT_X( QThread::currentThread() == qApp->thread(), 
"QgsPointLocator::onInitTaskFinished", 
"was not called on main thread" );
 
  950  for ( 
const QgsFeatureId fid : std::as_const( mAddedFeatures ) )
 
  951    onFeatureAdded( fid );
 
  952  mAddedFeatures.clear();
 
  954  for ( 
const QgsFeatureId fid : std::as_const( mDeletedFeatures ) )
 
  955    onFeatureDeleted( fid );
 
  956  mDeletedFeatures.clear();
 
  964  if ( geomType == Qgis::GeometryType::Null 
 
  986    connect( mInitTask, &QgsPointLocatorInitTask::taskTerminated, 
this, &QgsPointLocator::onInitTaskFinished );
 
  987    connect( mInitTask, &QgsPointLocatorInitTask::taskCompleted, 
this, &QgsPointLocator::onInitTaskFinished );
 
 1002  disconnect( mInitTask, &QgsPointLocatorInitTask::taskTerminated, 
this, &QgsPointLocator::onInitTaskFinished );
 
 1003  disconnect( mInitTask, &QgsPointLocatorInitTask::taskCompleted, 
this, &QgsPointLocator::onInitTaskFinished );
 
 1004  mInitTask->waitForFinished();
 
 1006  if ( !mIsDestroying )
 
 1007    onInitTaskFinished();
 
 1012  return mIsIndexing || mRTree || mIsEmptyLayer;
 
 1015bool QgsPointLocator::prepare( 
bool relaxed )
 
 1027    init( -1, relaxed );
 
 1028    if ( ( relaxed && mIsIndexing ) || !mRTree ) 
 
 1040  QgsDebugMsgLevel( QStringLiteral( 
"RebuildIndex start : %1" ).arg( mSource->id() ), 2 );
 
 1044  QLinkedList<RTree::Data *> dataList;
 
 1065        QgsDebugMsg( QStringLiteral( 
"could not transform bounding box to map, skipping the snap filter (%1)" ).arg( e.
what() ) );
 
 1071  bool filter = 
false;
 
 1075    ctx = mContext.get();
 
 1079      mRenderer->startRender( *ctx, mSource->fields() );
 
 1086  int indexedCount = 0;
 
 1093    if ( filter && ctx && mRenderer )
 
 1096      if ( !mRenderer->willRenderFeature( f, *ctx ) )
 
 1107        transformedGeometry.
transform( mTransform );
 
 1114        QgsDebugMsg( QStringLiteral( 
"could not transform geometry to map, skipping the snap for it (%1)" ).arg( e.
what() ) );
 
 1122      SpatialIndex::Region r( rect2region( bbox ) );
 
 1123      dataList << 
new RTree::Data( 0, 
nullptr, r, f.
id() );
 
 1125      auto it = mGeoms.find( f.
id() );
 
 1126      if ( it != mGeoms.end() )
 
 1138    if ( maxFeaturesToIndex != -1 && indexedCount > maxFeaturesToIndex )
 
 1140      qDeleteAll( dataList );
 
 1147  const double fillFactor = 0.7;
 
 1148  const unsigned long indexCapacity = 10;
 
 1149  const unsigned long leafCapacity = 10;
 
 1150  const unsigned long dimension = 2;
 
 1151  const RTree::RTreeVariant variant = RTree::RV_RSTAR;
 
 1152  SpatialIndex::id_type indexId;
 
 1154  if ( dataList.isEmpty() )
 
 1156    mIsEmptyLayer = 
true;
 
 1161  mRTree.reset( RTree::createAndBulkLoadNewRTree( RTree::BLM_STR, stream, *mStorage, fillFactor, indexCapacity,
 
 1162                leafCapacity, dimension, variant, indexId ) );
 
 1164  if ( ctx && mRenderer )
 
 1166    mRenderer->stopRender( *ctx );
 
 1169  QgsDebugMsgLevel( QStringLiteral( 
"RebuildIndex end : %1 ms (%2)" ).arg( t.elapsed() ).arg( mSource->id() ), 2 );
 
 1179  mIsEmptyLayer = 
false;
 
 1181  qDeleteAll( mGeoms );
 
 1186void QgsPointLocator::onFeatureAdded( 
QgsFeatureId fid )
 
 1191    mAddedFeatures << fid;
 
 1197    if ( mIsEmptyLayer )
 
 1200      mIsEmptyLayer = 
false;
 
 1214      std::unique_ptr< QgsFeatureRenderer > renderer( mLayer->
renderer() ? mLayer->
renderer()->
clone() : 
nullptr );
 
 1218      ctx = mContext.get();
 
 1219      if ( renderer && ctx )
 
 1222        renderer->startRender( *ctx, mLayer->
fields() );
 
 1225        if ( !renderer->willRenderFeature( f, *ctx ) )
 
 1230        renderer->stopRender( *ctx );
 
 1241        transformedGeom.
transform( mTransform );
 
 1248        QgsDebugMsg( QStringLiteral( 
"could not transform geometry to map, skipping the snap for it (%1)" ).arg( e.
what() ) );
 
 1256      const SpatialIndex::Region r( rect2region( bbox ) );
 
 1257      mRTree->insertData( 0, 
nullptr, r, f.
id() );
 
 1259      auto it = mGeoms.find( f.
id() );
 
 1260      if ( it != mGeoms.end() )
 
 1273void QgsPointLocator::onFeatureDeleted( 
QgsFeatureId fid )
 
 1277    if ( mAddedFeatures.contains( fid ) )
 
 1279      mAddedFeatures.remove( fid );
 
 1284      mDeletedFeatures << fid;
 
 1292  auto it = mGeoms.find( fid );
 
 1293  if ( it != mGeoms.end() )
 
 1295    mRTree->deleteData( rect2region( ( *it )->boundingBox() ), fid );
 
 1305  onFeatureDeleted( fid );
 
 1306  onFeatureAdded( fid );
 
 1309void QgsPointLocator::onAttributeValueChanged( 
QgsFeatureId fid, 
int idx, 
const QVariant &value )
 
 1315    onFeatureDeleted( fid );
 
 1316    onFeatureAdded( fid );
 
 1323  if ( !prepare( relaxed ) )
 
 1328  const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
 
 1329  mRTree->intersectsWithQuery( rect2region( rect ), visitor );
 
 1337  if ( !prepare( relaxed ) )
 
 1343  const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
 
 1344  mRTree->intersectsWithQuery( rect2region( rect ), visitor );
 
 1352  if ( !prepare( relaxed ) )
 
 1358  const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
 
 1359  mRTree->intersectsWithQuery( rect2region( rect ), visitor );
 
 1367  if ( !prepare( relaxed ) )
 
 1373  const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
 
 1374  mRTree->intersectsWithQuery( rect2region( rect ), visitor );
 
 1382  if ( !prepare( relaxed ) )
 
 1386  if ( geomType == Qgis::GeometryType::Point )
 
 1391  const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
 
 1392  mRTree->intersectsWithQuery( rect2region( rect ), visitor );
 
 1400  if ( !prepare( relaxed ) )
 
 1404  if ( !mlist.isEmpty() && mlist.at( 0 ).isValid() )
 
 1406    return mlist.at( 0 );
 
 1409  if ( tolerance == 0 )
 
 1416  if ( geomType == Qgis::GeometryType::Point || geomType == Qgis::GeometryType::Line )
 
 1430  if ( !prepare( relaxed ) )
 
 1434  if ( geomType == Qgis::GeometryType::Point )
 
 1439  mRTree->intersectsWithQuery( rect2region( rect ), visitor );
 
 1446  const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
 
 1452  if ( !prepare( relaxed ) )
 
 1457  mRTree->intersectsWithQuery( rect2region( rect ), visitor );
 
 1464  const QgsRectangle rect( point.
x() - tolerance, point.
y() - tolerance, point.
x() + tolerance, point.
y() + tolerance );
 
 1470  if ( !prepare( relaxed ) )
 
 1474  if ( geomType == Qgis::GeometryType::Point || geomType == Qgis::GeometryType::Line )
 
 1479  mRTree->intersectsWithQuery( point2point( point ), visitor );
 
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
The part_iterator class provides STL-style iterator for const references to geometry parts.
The vertex_iterator class provides 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.
This class 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.
virtual bool isValid() const =0
Returns true if this is a valid layer.
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)
@ Filter
Features may be filtered, i.e. some features may not be rendered (categorized, rule based ....
virtual QgsFeatureRenderer * clone() const =0
Create a deep copy of this renderer.
This class 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.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
Qgis::GeometryOperationResult transform(const QgsCoordinateTransform &ct, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool transformZ=false) SIP_THROW(QgsCsException)
Transforms this geometry as described by the coordinate transform ct.
QgsGeometry convertToType(Qgis::GeometryType destType, bool destMultipart=false) const
Try to convert the geometry to the requested type.
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 ...
Qgis::WkbType wkbType() const SIP_HOLDGIL
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
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.
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.
double closestSegmentWithContext(const QgsPointXY &point, QgsPointXY &minDistPoint, int &nextVertexIndex, int *leftOrRightOfSegment=nullptr, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
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.
QgsCoordinateReferenceSystem crs
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)
Helper class used when traversing the index with areas - builds a list of matches.
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)
constructor
Helper class used when traversing the index looking for centroid - builds a list of matches.
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
Helper class used when traversing the index looking for edges - builds a list of matches.
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
Helper class used when traversing the index looking for middle segment - builds a list of matches.
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.
Helper class used when traversing the index looking for centroid - builds a list of matches.
void visitData(const IData &d) override
void visitNode(const INode &n) override
void visitData(std::vector< const IData * > &v) override
Helper class used when traversing the index looking for edges - builds a list of matches.
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
Helper class used when traversing the index looking for line endpoints (start or end vertex) - builds...
void visitData(std::vector< const IData * > &v) override
void visitNode(const INode &n) override
void visitData(const IData &d) override
Helper class used when traversing the index looking for middle segment - builds a list of matches.
void visitData(std::vector< const IData * > &v) override
void visitData(const IData &d) override
void visitNode(const INode &n) override
Helper class used when traversing the index looking for vertices - builds a list of matches.
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)
Helper class used when traversing the index looking for vertices - builds a list of matches.
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.
The class defines interface for querying point location:
friend class QgsPointLocatorInitTask
MatchList pointInPolygon(const QgsPointXY &point, bool relaxed=false)
find out if the point is in any polygons This method is either blocking or non blocking according to ...
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 ...
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.
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.
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...
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.
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 (since QGIS 3.20)
QgsPointLocator(QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &destinationCrs=QgsCoordinateReferenceSystem(), const QgsCoordinateTransformContext &transformContext=QgsCoordinateTransformContext(), const QgsRectangle *extent=nullptr)
Construct point locator for a layer.
~QgsPointLocator() override
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...
A class to represent a 2D point.
bool isEmpty() const SIP_HOLDGIL
Returns true if the geometry is empty.
double sqrDist(double x, double y) const SIP_HOLDGIL
Returns the squared distance between this point a specified x, y coordinate.
Point geometry type, with support for z-dimension and m-values.
A rectangle specified with double values.
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
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.
long addTask(QgsTask *task, int priority=0)
Adds a task to the manager.
Partial snapshot of vector layer's state (only the members necessary for access to features)
Represents a vector layer which manages a vector based data sets.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QgsFeatureRenderer * renderer()
Returns the feature renderer used for rendering the features in the layer in 2D map views.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &value)
Emitted whenever an attribute value change is done in the edit buffer.
Q_INVOKABLE Qgis::GeometryType geometryType() const
Returns point, line or polygon.
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) SIP_HOLDGIL
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...
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
qint64 QgsFeatureId
64 bit feature ids negative numbers are used for uncommitted/newly added features
#define QgsDebugMsgLevel(str, level)
Interface that allows rejection of some matches in intersection queries (e.g.
virtual bool acceptMatch(const QgsPointLocator::Match &match)=0
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)