Skip to content

Commit

Permalink
Remove unwanted iteration from QgsDbscanClusteringAlgorithm and
Browse files Browse the repository at this point in the history
instead collect datetime values during index population
  • Loading branch information
nyalldawson committed Jul 26, 2021
1 parent 8a3d4e7 commit 72a848a
Showing 1 changed file with 21 additions and 14 deletions.
35 changes: 21 additions & 14 deletions src/analysis/processing/qgsalgorithmdbscanclustering.cpp
Expand Up @@ -130,30 +130,37 @@ QVariantMap QgsDbscanClusteringAlgorithm::processAlgorithm( const QVariantMap &p
if ( !sink )
throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );

// build spatial index
feedback->pushInfo( QObject::tr( "Building spatial index" ) );
QgsSpatialIndexKDBush index( *source, feedback );
if ( feedback->isCanceled() )
return QVariantMap();
QgsFeatureRequest indexRequest;

std::unordered_map< QgsFeatureId, QDateTime> idToDateTime;
const QString dateTimeFieldName = parameterAsString( parameters, QStringLiteral( "DATETIME_FIELD" ), context );
int dateTimefieldIndex = -1;
if ( !dateTimeFieldName.isEmpty() )
{
const int dateTimefieldIndex = source->fields().lookupField( dateTimeFieldName );
dateTimefieldIndex = source->fields().lookupField( dateTimeFieldName );
if ( dateTimefieldIndex == -1 )
throw QgsProcessingException( QObject::tr( "Datetime field missing" ) );

// fetch temporal values
feedback->pushInfo( QObject::tr( "Fetching temporal values" ) );
QgsFeatureIterator features = source->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() << dateTimefieldIndex ), QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks );
QgsFeature feature;
while ( features.nextFeature( feature ) )
{
idToDateTime[ feature.id() ] = feature.attributes().at( dateTimefieldIndex ).toDateTime();
}
indexRequest.setSubsetOfAttributes( QgsAttributeList() << dateTimefieldIndex );
}
else
{
indexRequest.setNoAttributes();
}

// build spatial index, also collecting feature datetimes if required
feedback->pushInfo( QObject::tr( "Building spatial index" ) );
QgsFeatureIterator indexIterator = source->getFeatures( indexRequest );
QgsSpatialIndexKDBush index( indexIterator, [&idToDateTime, dateTimefieldIndex]( const QgsFeature & feature )->bool
{
if ( dateTimefieldIndex >= 0 )
idToDateTime[ feature.id() ] = feature.attributes().at( dateTimefieldIndex ).toDateTime();
return true;
}, feedback );

if ( feedback->isCanceled() )
return QVariantMap();

// stdbscan!
feedback->pushInfo( QObject::tr( "Analysing clusters" ) );
std::unordered_map< QgsFeatureId, int> idToCluster;
Expand Down

0 comments on commit 72a848a

Please sign in to comment.