Use QgsFeatureSource instead of QgsVectorLayer for QgsKde

Allows generation of heatmaps from feature sources instead
of requiring vector layer inputs
This commit is contained in:
Nyall Dawson 2017-07-13 20:04:31 +10:00
parent eb0c3015f9
commit d9e29b9742
3 changed files with 17 additions and 16 deletions

View File

@ -49,9 +49,9 @@ class QgsKernelDensityEstimation
struct Parameters struct Parameters
{ {
QgsVectorLayer *vectorLayer; QgsFeatureSource *source;
%Docstring %Docstring
Vector point layer Point feature source
%End %End
double radius; double radius;

View File

@ -14,7 +14,8 @@
***************************************************************************/ ***************************************************************************/
#include "qgskde.h" #include "qgskde.h"
#include "qgsvectorlayer.h" #include "qgsfeaturesource.h"
#include "qgsfeatureiterator.h"
#include "qgsgeometry.h" #include "qgsgeometry.h"
#define NO_DATA -9999 #define NO_DATA -9999
@ -24,7 +25,7 @@
#endif #endif
QgsKernelDensityEstimation::QgsKernelDensityEstimation( const QgsKernelDensityEstimation::Parameters &parameters, const QString &outputFile, const QString &outputFormat ) QgsKernelDensityEstimation::QgsKernelDensityEstimation( const QgsKernelDensityEstimation::Parameters &parameters, const QString &outputFile, const QString &outputFormat )
: mInputLayer( parameters.vectorLayer ) : mSource( parameters.source )
, mOutputFile( outputFile ) , mOutputFile( outputFile )
, mOutputFormat( outputFormat ) , mOutputFormat( outputFormat )
, mRadiusField( -1 ) , mRadiusField( -1 )
@ -39,9 +40,9 @@ QgsKernelDensityEstimation::QgsKernelDensityEstimation( const QgsKernelDensityEs
, mRasterBandH( nullptr ) , mRasterBandH( nullptr )
{ {
if ( !parameters.radiusField.isEmpty() ) if ( !parameters.radiusField.isEmpty() )
mRadiusField = mInputLayer->fields().lookupField( parameters.radiusField ); mRadiusField = mSource->fields().lookupField( parameters.radiusField );
if ( !parameters.weightField.isEmpty() ) if ( !parameters.weightField.isEmpty() )
mWeightField = mInputLayer->fields().lookupField( parameters.weightField ); mWeightField = mSource->fields().lookupField( parameters.weightField );
} }
QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::run() QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::run()
@ -58,7 +59,7 @@ QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::run()
if ( mWeightField >= 0 ) if ( mWeightField >= 0 )
requiredAttributes << mWeightField; requiredAttributes << mWeightField;
QgsFeatureIterator fit = mInputLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( requiredAttributes ) ); QgsFeatureIterator fit = mSource->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( requiredAttributes ) );
QgsFeature f; QgsFeature f;
while ( fit.nextFeature( f ) ) while ( fit.nextFeature( f ) )
@ -79,7 +80,7 @@ QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::prepare()
return DriverError; return DriverError;
} }
if ( !mInputLayer ) if ( !mSource )
return InvalidParameters; return InvalidParameters;
mBounds = calculateBounds(); mBounds = calculateBounds();
@ -235,7 +236,7 @@ bool QgsKernelDensityEstimation::createEmptyLayer( GDALDriverH driver, const Qgs
return false; return false;
// Set the projection on the raster destination to match the input layer // Set the projection on the raster destination to match the input layer
if ( GDALSetProjection( emptyDataset, mInputLayer->crs().toWkt().toLocal8Bit().data() ) != CE_None ) if ( GDALSetProjection( emptyDataset, mSource->sourceCrs().toWkt().toLocal8Bit().data() ) != CE_None )
return false; return false;
GDALRasterBandH poBand = GDALGetRasterBand( emptyDataset, 1 ); GDALRasterBandH poBand = GDALGetRasterBand( emptyDataset, 1 );
@ -399,16 +400,16 @@ double QgsKernelDensityEstimation::triangularKernel( const double distance, cons
QgsRectangle QgsKernelDensityEstimation::calculateBounds() const QgsRectangle QgsKernelDensityEstimation::calculateBounds() const
{ {
if ( !mInputLayer ) if ( !mSource )
return QgsRectangle(); return QgsRectangle();
QgsRectangle bbox = mInputLayer->extent(); QgsRectangle bbox = mSource->sourceExtent();
double radius = 0; double radius = 0;
if ( mRadiusField >= 0 ) if ( mRadiusField >= 0 )
{ {
// if radius is using a field, find the max value // if radius is using a field, find the max value
radius = mInputLayer->maximumValue( mRadiusField ).toDouble(); radius = mSource->maximumValue( mRadiusField ).toDouble();
} }
else else
{ {

View File

@ -25,7 +25,7 @@
#include <cpl_conv.h> #include <cpl_conv.h>
#include "qgis_analysis.h" #include "qgis_analysis.h"
class QgsVectorLayer; class QgsFeatureSource;
class QProgressDialog; class QProgressDialog;
class QgsFeature; class QgsFeature;
@ -70,8 +70,8 @@ class ANALYSIS_EXPORT QgsKernelDensityEstimation
//! KDE parameters //! KDE parameters
struct Parameters struct Parameters
{ {
//! Vector point layer //! Point feature source
QgsVectorLayer *vectorLayer = nullptr; QgsFeatureSource *source = nullptr;
//! Fixed radius, in map units //! Fixed radius, in map units
double radius; double radius;
@ -146,7 +146,7 @@ class ANALYSIS_EXPORT QgsKernelDensityEstimation
QgsRectangle calculateBounds() const; QgsRectangle calculateBounds() const;
QgsVectorLayer *mInputLayer = nullptr; QgsFeatureSource *mSource = nullptr;
QString mOutputFile; QString mOutputFile;
QString mOutputFormat; QString mOutputFormat;