Skip to content

Commit acf302e

Browse files
strknyalldawson
authored andcommittedSep 21, 2021
Add a distanceWithin method to the QgsGeometryEngine virtual class
And use it from QgsVectorLayerFeatureIterator References #472 The current implementation is really just a wrapper around distance() but opens the door for future improvements
1 parent 0711166 commit acf302e

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed
 

‎python/core/auto_generated/geometry/qgsgeometryengine.sip.in

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,13 @@ Calculate the convex hull of this.
166166
Calculates the distance between this and ``geom``.
167167

168168
.. versionadded:: 3.0
169+
%End
170+
171+
virtual bool distanceWithin( const QgsAbstractGeometry *geom, double maxdistance, QString *errorMsg = 0 ) const = 0;
172+
%Docstring
173+
Checks if ``geom`` is within ``maxdistance`` distance from this geometry
174+
175+
.. versionadded:: 3.22
169176
%End
170177

171178
virtual bool intersects( const QgsAbstractGeometry *geom, QString *errorMsg = 0 ) const = 0;

‎src/core/geometry/qgsgeometryengine.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ class CORE_EXPORT QgsGeometryEngine
184184
*/
185185
virtual double distance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const = 0;
186186

187+
/**
188+
* Checks if \a geom is within \a maxdistance distance from this geometry
189+
*
190+
* \since QGIS 3.22
191+
*/
192+
virtual bool distanceWithin( const QgsAbstractGeometry *geom, double maxdistance, QString *errorMsg = nullptr ) const = 0;
193+
187194
/**
188195
* Checks if \a geom intersects this.
189196
*

‎src/core/geometry/qgsgeos.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,44 @@ double QgsGeos::distance( const QgsAbstractGeometry *geom, QString *errorMsg ) c
475475
return distance;
476476
}
477477

478+
bool QgsGeos::distanceWithin( const QgsAbstractGeometry *geom, double maxdist, QString *errorMsg ) const
479+
{
480+
if ( !mGeos )
481+
{
482+
return false;
483+
}
484+
485+
geos::unique_ptr otherGeosGeom( asGeos( geom, mPrecision ) );
486+
if ( !otherGeosGeom )
487+
{
488+
return false;
489+
}
490+
491+
// TODO: optimize implementation of this function to early-exit if
492+
// any part of othergeosGeom is found to be within the given
493+
// distance
494+
495+
double distance;
496+
try
497+
{
498+
#if GEOS_VERSION_MAJOR>3 || ( GEOS_VERSION_MAJOR == 3 && GEOS_VERSION_MINOR>=9 )
499+
if ( mGeosPrepared )
500+
{
501+
GEOSPreparedDistance_r( geosinit()->ctxt, mGeosPrepared.get(), otherGeosGeom.get(), &distance );
502+
}
503+
else
504+
{
505+
GEOSDistance_r( geosinit()->ctxt, mGeos.get(), otherGeosGeom.get(), &distance );
506+
}
507+
#else
508+
GEOSDistance_r( geosinit()->ctxt, mGeos.get(), otherGeosGeom.get(), &distance );
509+
#endif
510+
}
511+
CATCH_GEOS_WITH_ERRMSG( false )
512+
513+
return distance <= maxdist;
514+
}
515+
478516
double QgsGeos::hausdorffDistance( const QgsAbstractGeometry *geom, QString *errorMsg ) const
479517
{
480518
double distance = -1.0;

‎src/core/geometry/qgsgeos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ class CORE_EXPORT QgsGeos: public QgsGeometryEngine
180180
QgsPoint *pointOnSurface( QString *errorMsg = nullptr ) const override;
181181
QgsAbstractGeometry *convexHull( QString *errorMsg = nullptr ) const override;
182182
double distance( const QgsAbstractGeometry *geom, QString *errorMsg = nullptr ) const override;
183+
bool distanceWithin( const QgsAbstractGeometry *geom, double maxdistance, QString *errorMsg = nullptr ) const override;
183184

184185
/**
185186
* Returns the Hausdorff distance between this geometry and \a geom. This is basically a measure of how similar or dissimilar 2 geometries are.

‎src/core/vector/qgsvectorlayerfeatureiterator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ bool QgsVectorLayerFeatureIterator::postProcessFeature( QgsFeature &feature )
903903

904904
if ( result && mDistanceWithinEngine && feature.hasGeometry() )
905905
{
906-
result = mDistanceWithinEngine->distance( feature.geometry().constGet() ) <= mDistanceWithin;
906+
result = mDistanceWithinEngine->distanceWithin( feature.geometry().constGet(), mDistanceWithin );
907907
}
908908

909909
return result;

0 commit comments

Comments
 (0)
Please sign in to comment.