@@ -5650,16 +5650,20 @@ static QVariant fcnFromBase64( const QVariantList &values, const QgsExpressionCo
5650
5650
return QVariant ( decoded );
5651
5651
}
5652
5652
5653
- typedef std::function < QVariant( QgsExpression &subExp, QgsExpressionContext &subContext, const QgsSpatialIndex &spatialIndex, std::shared_ptr<QgsVectorLayer> cachedTarget, const QgsGeometry &geometry, bool testOnly, bool invert, int neighbors, double max_distance, double bboxGrow ) > overlayFunc;
5653
+ typedef std::function < QVariant( QgsExpression &subExp, QgsExpressionContext &subContext, const QgsSpatialIndex &spatialIndex, std::shared_ptr<QgsVectorLayer> cachedTarget, const QgsGeometry &geometry, bool testOnly, bool invert, QVariant currentFeatId, int neighbors, double max_distance, double bboxGrow ) > overlayFunc;
5654
5654
5655
5655
static QVariant executeGeomOverlay ( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, bool testOnly, const overlayFunc &overlayFunction, bool invert = false , double bboxGrow = 0 )
5656
5656
{
5657
+
5658
+ const QVariant sourceLayerRef = context->variable ( QStringLiteral ( " layer" ) ); // used to detect if sorceLayer and targetLayer are the same
5659
+ QgsVectorLayer *sourceLayer = QgsExpressionUtils::getVectorLayer ( sourceLayerRef, parent );
5660
+
5657
5661
// First parameter is the overlay layer
5658
5662
QgsExpressionNode *node = QgsExpressionUtils::getNode ( values.at ( 0 ), parent );
5659
5663
ENSURE_NO_EVAL_ERROR
5660
5664
5661
5665
const bool layerCanBeCached = node->isStatic ( parent, context );
5662
- QVariant layerValue = node->eval ( parent, context );
5666
+ QVariant targetLayerValue = node->eval ( parent, context );
5663
5667
ENSURE_NO_EVAL_ERROR
5664
5668
5665
5669
QString subExpString;
@@ -5675,10 +5679,10 @@ static QVariant executeGeomOverlay( const QVariantList &values, const QgsExpress
5675
5679
QgsSpatialIndex spatialIndex;
5676
5680
std::shared_ptr<QgsVectorLayer> cachedTarget;
5677
5681
5678
- QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer ( layerValue , parent );
5682
+ QgsVectorLayer *layer = QgsExpressionUtils::getVectorLayer ( targetLayerValue , parent );
5679
5683
if ( !layer ) // No layer, no joy
5680
5684
{
5681
- parent->setEvalErrorString ( QObject::tr ( " Layer '%1' could not be loaded." ).arg ( layerValue .toString () ) );
5685
+ parent->setEvalErrorString ( QObject::tr ( " Layer '%1' could not be loaded." ).arg ( targetLayerValue .toString () ) );
5682
5686
return QVariant ();
5683
5687
}
5684
5688
@@ -5752,15 +5756,21 @@ static QVariant executeGeomOverlay( const QVariantList &values, const QgsExpress
5752
5756
FEAT_FROM_CONTEXT ( context, feat )
5753
5757
const QgsGeometry geometry = feat.geometry ();
5754
5758
5755
- return overlayFunction ( subExpression, subContext, spatialIndex, cachedTarget, geometry, testOnly, invert, neighbors, max_distance, bboxGrow );
5759
+ QVariant currentFeatId;
5760
+ if (sourceLayer->id () == targetLayerValue)
5761
+ {
5762
+ currentFeatId = feat.id (); // if sourceLayer and targetLayer are the same, current feature have to be excluded from spatial check
5763
+ }
5764
+
5765
+ return overlayFunction ( subExpression, subContext, spatialIndex, cachedTarget, geometry, testOnly, invert, currentFeatId, neighbors, max_distance, bboxGrow );
5756
5766
}
5757
5767
5758
5768
// Intersect functions:
5759
5769
5760
5770
typedef bool ( QgsGeometry::*t_relationFunction )( const QgsGeometry &geometry ) const ;
5761
5771
5762
5772
template <t_relationFunction T>
5763
- static QVariant indexedFilteredOverlay ( QgsExpression &subExp, QgsExpressionContext &subContext, const QgsSpatialIndex &spatialIndex, std::shared_ptr<QgsVectorLayer> cachedTarget, const QgsGeometry &geometry, bool testOnly, bool invert, int neighbors, double max_distance, double bboxGrow = 0 )
5773
+ static QVariant indexedFilteredOverlay ( QgsExpression &subExp, QgsExpressionContext &subContext, const QgsSpatialIndex &spatialIndex, std::shared_ptr<QgsVectorLayer> cachedTarget, const QgsGeometry &geometry, bool testOnly, bool invert, QVariant currentFeatId, int neighbors, double max_distance, double bboxGrow = 0 )
5764
5774
{
5765
5775
QgsRectangle intDomain = geometry.boundingBox ();
5766
5776
if ( bboxGrow != 0 )
@@ -5774,6 +5784,10 @@ static QVariant indexedFilteredOverlay( QgsExpression &subExp, QgsExpressionCont
5774
5784
QVariantList results;
5775
5785
for ( QgsFeatureId id : targetFeatureIds )
5776
5786
{
5787
+ if (!currentFeatId.isNull () && currentFeatId.toLongLong () == id)
5788
+ {
5789
+ continue ; // if sourceLayer and targetLayer are the same, current feature have to be excluded from spatial check
5790
+ }
5777
5791
5778
5792
QgsFeature feat = cachedTarget->getFeature ( id );
5779
5793
@@ -5826,7 +5840,7 @@ static QVariant indexedFilteredOverlay( QgsExpression &subExp, QgsExpressionCont
5826
5840
}
5827
5841
}
5828
5842
5829
- static QVariantList indexedFilteredNearest ( QgsExpression &subExp, QgsExpressionContext &subContext, const QgsSpatialIndex &spatialIndex, std::shared_ptr<QgsVectorLayer> cachedTarget, const QgsGeometry &geometry, bool testOnly, bool invert, int neighbors, double max_distance, double bboxGrow = 0 )
5843
+ static QVariantList indexedFilteredNearest ( QgsExpression &subExp, QgsExpressionContext &subContext, const QgsSpatialIndex &spatialIndex, std::shared_ptr<QgsVectorLayer> cachedTarget, const QgsGeometry &geometry, bool testOnly, bool invert, QVariant currentFeatId, int neighbors, double max_distance, double bboxGrow = 0 )
5830
5844
{
5831
5845
5832
5846
const QList<QgsFeatureId> targetFeatureIds = spatialIndex.nearestNeighbor ( geometry, neighbors, max_distance );
0 commit comments