Skip to content
Permalink
Browse files

Make more use of prepared geometries for intersection tests

Should speed up a few operations
  • Loading branch information
nyalldawson committed Jun 7, 2017
1 parent 5f1a78d commit be501a0f5f63c148bcec123acf97fddbb822715d
@@ -16,6 +16,7 @@
#include "qgsmemoryprovider.h"

#include "qgsgeometry.h"
#include "qgsgeometryengine.h"
#include "qgslogger.h"
#include "qgsspatialindex.h"
#include "qgsmessagelog.h"
@@ -35,6 +36,8 @@ QgsMemoryFeatureIterator::QgsMemoryFeatureIterator( QgsMemoryFeatureSource *sour
if ( !mRequest.filterRect().isNull() && mRequest.flags() & QgsFeatureRequest::ExactIntersect )
{
mSelectRectGeom = QgsGeometry::fromRect( request.filterRect() );
mSelectRectEngine.reset( QgsGeometry::createGeometryEngine( mSelectRectGeom.geometry() ) );
mSelectRectEngine->prepareGeometry();
}

// if there's spatial index, use it!
@@ -92,7 +95,7 @@ bool QgsMemoryFeatureIterator::nextFeatureUsingList( QgsFeature &feature )
if ( !mRequest.filterRect().isNull() && mRequest.flags() & QgsFeatureRequest::ExactIntersect )
{
// do exact check in case we're doing intersection
if ( mSource->mFeatures.value( *mFeatureIdListIterator ).hasGeometry() && mSource->mFeatures.value( *mFeatureIdListIterator ).geometry().intersects( mSelectRectGeom ) )
if ( mSource->mFeatures.value( *mFeatureIdListIterator ).hasGeometry() && mSelectRectEngine->intersects( *mSource->mFeatures.value( *mFeatureIdListIterator ).geometry().geometry() ) )
hasFeature = true;
}
else
@@ -144,7 +147,7 @@ bool QgsMemoryFeatureIterator::nextFeatureTraverseAll( QgsFeature &feature )
if ( mRequest.flags() & QgsFeatureRequest::ExactIntersect )
{
// using exact test when checking for intersection
if ( mSelectIterator->hasGeometry() && mSelectIterator->geometry().intersects( mSelectRectGeom ) )
if ( mSelectIterator->hasGeometry() && mSelectRectEngine->intersects( *mSelectIterator->geometry().geometry() ) )
hasFeature = true;
}
else
@@ -66,6 +66,7 @@ class QgsMemoryFeatureIterator : public QgsAbstractFeatureIteratorFromSource<Qgs
bool nextFeatureTraverseAll( QgsFeature &feature );

QgsGeometry mSelectRectGeom;
std::unique_ptr< QgsGeometryEngine > mSelectRectEngine;
QgsFeatureMap::const_iterator mSelectIterator;
bool mUsingFeatureIdList = false;
QList<QgsFeatureId> mFeatureIdList;
@@ -24,6 +24,7 @@
#include "qgsvectorlayer.h"
#include "qgssymbollayerutils.h"
#include "qgsgeometry.h"
#include "qgsgeometryengine.h"
#include "qgscrscache.h"

QgsMapHitTest::QgsMapHitTest( const QgsMapSettings &settings, const QgsGeometry &polygon, const LayerFilterExpression &layerFilterExpression )
@@ -121,6 +122,7 @@ void QgsMapHitTest::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols,

QgsFeature f;
QgsFeatureRequest request;
std::unique_ptr< QgsGeometryEngine > polygonEngine;
if ( !mOnlyExpressions )
{
if ( mPolygon.isNull() )
@@ -131,6 +133,8 @@ void QgsMapHitTest::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols,
else
{
request.setFilterRect( transformedPolygon.boundingBox() );
polygonEngine.reset( QgsGeometry::createGeometryEngine( transformedPolygon.geometry() ) );
polygonEngine->prepareGeometry();
}
}
QgsFeatureIterator fi = vl->getFeatures( request );
@@ -149,9 +153,9 @@ void QgsMapHitTest::runHitTestLayer( QgsVectorLayer *vl, SymbolSet &usedSymbols,
{
context.expressionContext().setFeature( f );
// filter out elements outside of the polygon
if ( !mOnlyExpressions && !mPolygon.isNull() )
if ( f.geometry() && polygonEngine )
{
if ( !transformedPolygon.intersects( f.geometry() ) )
if ( !polygonEngine->intersects( *f.geometry().geometry() ) )
{
continue;
}

0 comments on commit be501a0

Please sign in to comment.
You can’t perform that action at this time.