Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overlay_nearest() and other overlay_* functions return incorrect results when used with the same layer (target layer = source layer) in some situations #47201

Open
2 tasks done
agiudiceandrea opened this issue Feb 4, 2022 · 3 comments
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Expressions Related to the QGIS expression engine or specific expression functions

Comments

@agiudiceandrea
Copy link
Contributor

agiudiceandrea commented Feb 4, 2022

What is the bug or the crash?

The overlay_nearest() function, used with a target layer which is the same as the source layer and such layer is in a Shapefile or GeoJSON or FlatGeobuf format, incorrectly returns always the same current geometry instead of the nearest geometry.

When the layer is in a Memory or GeoPackage or Spatialite format, then the function correctly returns the nearest geometry to the current geometry.

The issue doesn't occur with the overlay_equals() and overlay_intersects() functions when the cache parameter is not specified or is set to false (the default value).
The issue does also occur with the overlay_equals() and overlay_intersects() functions when the cache parameter is set to true.

Steps to reproduce the issue

1a) create a new scratch (Memory) point layer
1b) add a single point to the memory layer
1c) use the expression overlay_nearest(@layer,$geometry) in the field calculator for such layer: the preview will correctly show [] (i.e. no nearest geometry returned)

2a) export the Memory layer to a Shapefile (or GeoJSON or FlatGeobuf) layer and add it to the map
2b) use the same expression in the field calculator for the Shapefile layer: the preview will incorrectly show [ <geometry: Point> ] (i.e. the expression incorrectly returns the very some point as the nearest point)

3a) export the Memory layer to a GeoPackage or a Spatialite layer and add it to the map
3b) use the same expression in the field calculator for the GeoPackage or a Spatialite layer: the preview will correctly show [] (i.e. no nearest geometry returned)

Versions

QGIS 3.16.0 and QGIS 3.16.5 on Windows 7 (from OSGeo4W v1)
QGIS 3.16.16, QGIS 3.22.3 and QGIS 3.23.0-Master on Windows 10 (from OSGeo4W v2)

Supported QGIS version

  • I'm running a supported QGIS version according to the roadmap.

New profile

  • I tried with a new QGIS profile

Additional context

The overlay_nearest() function and the other overlay_* functions have been ported in core QGIS from the refFunction plugin with PR #38405 by @olivierdalang, @m-kuhn and @enricofer.

The functions code has logic in place to allegedly handle the "some layer" (target layer = source layer) situation in the right way:

QList<QgsFeatureId> fidsList;
if ( isNearestFunc )
{
fidsList = spatialIndex.nearestNeighbor( geometry, sameLayers ? limit + 1 : limit, max_distance );
}
else
{
fidsList = spatialIndex.intersects( intDomain );
}
QListIterator<QgsFeatureId> i( fidsList );
while ( i.hasNext() )
{
QgsFeatureId fId2 = i.next();
if ( sameLayers && feat.id() == fId2 )
continue;
features.append( cachedTarget->getFeature( fId2 ) );
}
}
else
{
// If the cache (local spatial index) is not enabled, we directly
// get the features from the target layer
request.setFilterRect( intDomain );
QgsFeatureIterator fit = targetLayer->getFeatures( request );
QgsFeature feat2;
while ( fit.nextFeature( feat2 ) )
{
if ( sameLayers && feat.id() == feat2.id() )
continue;
features.append( feat2 );
}
}

The function, in this case, should drop the current feature from the result.

See also olivierdalang@751ad05

@agiudiceandrea agiudiceandrea added the Bug Either a bug report, or a bug fix. Let's hope for the latter! label Feb 4, 2022
@agiudiceandrea
Copy link
Contributor Author

Additionally, the overlay_nearest(), when used with the same layer (target layer = source layer), doesn't respect the limit:=-1 option.
In this case, the functions behave as the parameter limit was set to 0 if the layer is in a Memory or GeoPackage or Spatialite formt, while it behave as the parameter limit was set to 1 if the layer is in a Shapefile or GeoJSON or FlatGeobuf format.

@pigreco
Copy link
Sponsor Contributor

pigreco commented Feb 4, 2022

I confirm

OSGeo4W v2 win 10 64 bit

@gioman gioman added the Expressions Related to the QGIS expression engine or specific expression functions label Feb 4, 2022
@pigreco
Copy link
Sponsor Contributor

pigreco commented Feb 17, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Either a bug report, or a bug fix. Let's hope for the latter! Expressions Related to the QGIS expression engine or specific expression functions
Projects
None yet
Development

No branches or pull requests

3 participants