Skip to content

Commit

Permalink
Implement distance within for WFS/oapif provider
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Aug 5, 2021
1 parent 12de6e8 commit 5f94fbd
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
28 changes: 28 additions & 0 deletions src/providers/wfs/qgsbackgroundcachedfeatureiterator.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgslogger.h"
#include "qgsmessagelog.h"
#include "qgswfsutils.h" // for isCompatibleType()
#include "qgsgeometryengine.h"

#include <QDataStream>
#include <QDir>
Expand Down Expand Up @@ -301,6 +302,23 @@ QgsBackgroundCachedFeatureIterator::QgsBackgroundCachedFeatureIterator(
return;
}

// prepare spatial filter geometries for optimal speed
switch ( mRequest.spatialFilterType() )
{
case Qgis::SpatialFilterType::NoFilter:
case Qgis::SpatialFilterType::BoundingBox:
break;

case Qgis::SpatialFilterType::DistanceWithin:
if ( !mRequest.referenceGeometry().isEmpty() )
{
mDistanceWithinGeom = mRequest.referenceGeometry();
mDistanceWithinEngine.reset( QgsGeometry::createGeometryEngine( mDistanceWithinGeom.constGet() ) );
mDistanceWithinEngine->prepareGeometry();
}
break;
}

// Configurable for the purpose of unit tests
QString threshold( getenv( "QGIS_WFS_ITERATOR_TRANSFER_THRESHOLD" ) );
if ( !threshold.isEmpty() )
Expand Down Expand Up @@ -425,6 +443,7 @@ void QgsBackgroundCachedFeatureIterator::fillRequestCache( QgsFeatureRequest req
requestCache.setFilterRect( mFilterRect );

if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) ||
( mRequest.spatialFilterType() == Qgis::SpatialFilterType::DistanceWithin ) ||
( mRequest.filterType() == QgsFeatureRequest::FilterExpression && mRequest.filterExpression()->needsGeometry() ) )
{
mFetchGeometry = true;
Expand Down Expand Up @@ -671,6 +690,9 @@ bool QgsBackgroundCachedFeatureIterator::fetchFeature( QgsFeature &f )
copyFeature( cachedFeature, f, true );
geometryToDestinationCrs( f, mTransform );

if ( mDistanceWithinEngine && mDistanceWithinEngine->distance( f.geometry().constGet() ) > mRequest.distanceWithin() )
continue;

// Retrieve the user-visible id from the Spatialite cache database Id
QgsFeatureId userVisibleId;
if ( mShared->getUserVisibleIdFromSpatialiteId( cachedFeature.id(), userVisibleId ) )
Expand Down Expand Up @@ -767,6 +789,12 @@ bool QgsBackgroundCachedFeatureIterator::fetchFeature( QgsFeature &f )
}

copyFeature( feat, f, false );

geometryToDestinationCrs( f, mTransform );

if ( mDistanceWithinEngine && mDistanceWithinEngine->distance( f.geometry().constGet() ) > mRequest.distanceWithin() )
continue;

return true;
}

Expand Down
2 changes: 2 additions & 0 deletions src/providers/wfs/qgsbackgroundcachedfeatureiterator.h
Expand Up @@ -377,6 +377,8 @@ class QgsBackgroundCachedFeatureIterator final: public QObject,

QgsCoordinateTransform mTransform;
QgsRectangle mFilterRect;
QgsGeometry mDistanceWithinGeom;
std::unique_ptr< QgsGeometryEngine > mDistanceWithinEngine;

//! typically to save a FilterFid/FilterFids request that will not be captured by mRequest
QgsFeatureRequest mAdditionalRequest;
Expand Down

0 comments on commit 5f94fbd

Please sign in to comment.