Skip to content

Commit

Permalink
Use prepared geometry for spatial query plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent authored and nyalldawson committed Jun 6, 2016
1 parent 221c4e0 commit d3cbe04
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 20 deletions.
44 changes: 28 additions & 16 deletions src/plugins/spatialquery/qgsspatialquery.cpp
Expand Up @@ -21,6 +21,7 @@
#include "qgsvectordataprovider.h"
#include "qgsfeature.h"
#include "qgsgeometrycoordinatetransform.h"
#include "qgsgeometryengine.h"
#include "qgsspatialquery.h"

QgsSpatialQuery::QgsSpatialQuery( MngProgressBar *pb )
Expand Down Expand Up @@ -207,32 +208,32 @@ void QgsSpatialQuery::setSpatialIndexReference( QgsFeatureIds &qsetIndexInvalidR

void QgsSpatialQuery::execQuery( QgsFeatureIds &qsetIndexResult, QgsFeatureIds &qsetIndexInvalidTarget, int relation )
{
bool ( QgsGeometry::* operation )( const QgsGeometry * ) const;
bool ( QgsGeometryEngine::* operation )( const QgsAbstractGeometryV2&, QString* ) const;
switch ( relation )
{
case Disjoint:
operation = &QgsGeometry::disjoint;
operation = &QgsGeometryEngine::disjoint;
break;
case Equals:
operation = &QgsGeometry::equals;
operation = &QgsGeometryEngine::isEqual;
break;
case Touches:
operation = &QgsGeometry::touches;
operation = &QgsGeometryEngine::touches;
break;
case Overlaps:
operation = &QgsGeometry::overlaps;
operation = &QgsGeometryEngine::overlaps;
break;
case Within:
operation = &QgsGeometry::within;
operation = &QgsGeometryEngine::within;
break;
case Contains:
operation = &QgsGeometry::contains;
operation = &QgsGeometryEngine::contains;
break;
case Crosses:
operation = &QgsGeometry::crosses;
operation = &QgsGeometryEngine::crosses;
break;
case Intersects:
operation = &QgsGeometry::intersects;
operation = &QgsGeometryEngine::intersects;
break;
default:
qWarning( "undefined operation" );
Expand All @@ -244,7 +245,7 @@ void QgsSpatialQuery::execQuery( QgsFeatureIds &qsetIndexResult, QgsFeatureIds &
coordinateTransform->setCoordinateTransform( mLayerTarget, mLayerReference );

// Set function for populate result
void ( QgsSpatialQuery::* funcPopulateIndexResult )( QgsFeatureIds&, QgsFeatureId, QgsGeometry *, bool ( QgsGeometry::* )( const QgsGeometry * ) const );
void ( QgsSpatialQuery::* funcPopulateIndexResult )( QgsFeatureIds&, QgsFeatureId, QgsGeometry *, bool ( QgsGeometryEngine::* )( const QgsAbstractGeometryV2&, QString* ) const );
funcPopulateIndexResult = ( relation == Disjoint )
? &QgsSpatialQuery::populateIndexResultDisjoint
: &QgsSpatialQuery::populateIndexResult;
Expand Down Expand Up @@ -273,33 +274,40 @@ void QgsSpatialQuery::execQuery( QgsFeatureIds &qsetIndexResult, QgsFeatureIds &

void QgsSpatialQuery::populateIndexResult(
QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry * geomTarget,
bool ( QgsGeometry::* op )( const QgsGeometry * ) const )
bool ( QgsGeometryEngine::* op )( const QgsAbstractGeometryV2&, QString* ) const )
{
QList<QgsFeatureId> listIdReference;
listIdReference = mIndexReference.intersects( geomTarget->boundingBox() );
if ( listIdReference.isEmpty() )
{
return;
}

//prepare geometry
QgsGeometryEngine* geomEngine = geomTarget->createGeometryEngine( geomTarget->geometry() );
geomEngine->prepareGeometry();

QgsFeature featureReference;
const QgsGeometry * geomReference;
QList<QgsFeatureId>::iterator iterIdReference = listIdReference.begin();
for ( ; iterIdReference != listIdReference.end(); ++iterIdReference )
{
mLayerReference->getFeatures( QgsFeatureRequest().setFilterFid( *iterIdReference ) ).nextFeature( featureReference );
geomReference = featureReference.constGeometry();
if (( geomTarget->*op )( geomReference ) )

if (( geomEngine->*op )( *( geomReference->geometry() ), 0 ) )
{
qsetIndexResult.insert( idTarget );
break;
}
}

delete geomEngine;
} // void QgsSpatialQuery::populateIndexResult(...

void QgsSpatialQuery::populateIndexResultDisjoint(
QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry * geomTarget,
bool ( QgsGeometry::* op )( const QgsGeometry * ) const )
bool ( QgsGeometryEngine::* op )( const QgsAbstractGeometryV2&, QString* ) const )
{
QList<QgsFeatureId> listIdReference;
listIdReference = mIndexReference.intersects( geomTarget->boundingBox() );
Expand All @@ -308,6 +316,11 @@ void QgsSpatialQuery::populateIndexResultDisjoint(
qsetIndexResult.insert( idTarget );
return;
}

//prepare geometry
QgsGeometryEngine* geomEngine = geomTarget->createGeometryEngine( geomTarget->geometry() );
geomEngine->prepareGeometry();

QgsFeature featureReference;
const QgsGeometry * geomReference;
QList<QgsFeatureId>::iterator iterIdReference = listIdReference.begin();
Expand All @@ -316,8 +329,7 @@ void QgsSpatialQuery::populateIndexResultDisjoint(
{
mLayerReference->getFeatures( QgsFeatureRequest().setFilterFid( *iterIdReference ) ).nextFeature( featureReference );
geomReference = featureReference.constGeometry();

if ( !( geomTarget->*op )( geomReference ) )
if (( geomEngine->*op )( *( geomReference->geometry() ), 0 ) )
{
addIndex = false;
break;
Expand All @@ -327,6 +339,6 @@ void QgsSpatialQuery::populateIndexResultDisjoint(
{
qsetIndexResult.insert( idTarget );
}

delete geomEngine;
} // void QgsSpatialQuery::populateIndexResultDisjoint( ...

8 changes: 4 additions & 4 deletions src/plugins/spatialquery/qgsspatialquery.h
Expand Up @@ -24,6 +24,7 @@
#include "qgsmngprogressbar.h"
#include "qgsreaderfeatures.h"

class QgsGeometryEngine;

/**
* \brief Enum with the topologic relations
Expand Down Expand Up @@ -137,17 +138,16 @@ class QgsSpatialQuery
*/
void populateIndexResult(
QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry *geomTarget,
bool ( QgsGeometry::* operation )( const QgsGeometry * ) const );
bool ( QgsGeometryEngine::* operation )( const QgsAbstractGeometryV2&, QString* ) const );
/**
* \brief Populate index Result Disjoint
* \param qsetIndexResult Reference to QSet contains the result query
* \param idTarget Id of the feature Target
* \param geomTarget Geometry the feature Target
* \param operation Pointer to function of GEOS operation
*/
void populateIndexResultDisjoint(
QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry *geomTarget,
bool ( QgsGeometry::* operation )( const QgsGeometry * ) const );
void populateIndexResultDisjoint( QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry *geomTarget,
bool ( QgsGeometryEngine::*operation )( const QgsAbstractGeometryV2&, QString* ) const );

MngProgressBar *mPb;
bool mUseReferenceSelection;
Expand Down

0 comments on commit d3cbe04

Please sign in to comment.