26using namespace Qt::StringLiterals;
31QString QgsHeatmapAlgorithm::name()
const
33 return u
"heatmapkerneldensityestimation"_s;
36QString QgsHeatmapAlgorithm::displayName()
const
38 return QObject::tr(
"Heatmap (Kernel Density Estimation)" );
41QStringList QgsHeatmapAlgorithm::tags()
const
43 return QObject::tr(
"heatmap,kde,hotspot" ).split(
',' );
46QString QgsHeatmapAlgorithm::group()
const
48 return QObject::tr(
"Interpolation" );
51QString QgsHeatmapAlgorithm::groupId()
const
53 return u
"interpolation"_s;
56QIcon QgsHeatmapAlgorithm::icon()
const
61QgsHeatmapAlgorithm::~QgsHeatmapAlgorithm() =
default;
63void QgsHeatmapAlgorithm::initAlgorithm(
const QVariantMap & )
65 auto inputParam = std::make_unique<QgsProcessingParameterFeatureSource>( u
"INPUT"_s, QObject::tr(
"Point layer" ), QList<int>() <<
static_cast<int>(
Qgis::ProcessingSourceType::VectorPoint ) );
66 inputParam->setHelp( QObject::tr(
"The point vector layer to calculate the heatmap from." ) );
67 addParameter( inputParam.release() );
69 auto radiusParam = std::make_unique<QgsProcessingParameterDistance>( u
"RADIUS"_s, QObject::tr(
"Radius" ), 100.0, u
"INPUT"_s,
false, 0.0 );
70 radiusParam->setHelp( QObject::tr(
"The search radius to use for calculating the heatmap. This represents the distance around each point that will be considered when calculating the density." ) );
71 addParameter( radiusParam.release() );
76 radiusFieldParam->setHelp( QObject::tr(
"An optional numeric field from the input layer which specifies a per-feature radius to use instead of the global radius parameter." ) );
77 addParameter( radiusFieldParam.release() );
79 auto pixelSizeParam = std::make_unique<QgsProcessingParameterHeatmapPixelSize>( u
"PIXEL_SIZE"_s, QObject::tr(
"Output raster size" ), u
"INPUT"_s, u
"RADIUS"_s, u
"RADIUS_FIELD"_s, 0.1 );
80 pixelSizeParam->setHelp( QObject::tr(
"The size of pixels in the output raster. This will determine the spatial resolution of the generated heatmap." ) );
81 addParameter( pixelSizeParam.release() );
86 weightFieldParam->setHelp(
87 QObject::tr(
"An optional numeric field from the input layer to use for weighting the points. If specified, the density will be calculated using this weight instead of simply counting the points." )
89 addParameter( weightFieldParam.release() );
91 const QStringList kernels = { QObject::tr(
"Quartic" ), QObject::tr(
"Triangular" ), QObject::tr(
"Uniform" ), QObject::tr(
"Triweight" ), QObject::tr(
"Epanechnikov" ) };
92 auto kernelShapeParam = std::make_unique<QgsProcessingParameterEnum>( u
"KERNEL"_s, QObject::tr(
"Kernel shape" ), kernels,
false, 0 );
94 kernelShapeParam->setHelp( QObject::tr(
"The shape of the kernel to use for density estimation. Different kernel shapes affect the influence of points at varying distances from the center." ) );
95 addParameter( kernelShapeParam.release() );
100 decayRatio->setHelp( QObject::tr(
"The decay ratio for triangular kernels. This controls how the weight of a point decreases as the distance from the point increases." ) );
101 addParameter( decayRatio.release() );
103 const QStringList outputScalings = { QObject::tr(
"Raw" ), QObject::tr(
"Scaled" ) };
104 auto outputScaling = std::make_unique<QgsProcessingParameterEnum>( u
"OUTPUT_VALUE"_s, QObject::tr(
"Output value scaling" ), outputScalings,
false, 0 );
106 outputScaling->setHelp( QObject::tr(
"The scaling to apply to output values. 'Raw' will output the raw density values, while 'Scaled' will scale the values to represent an overall density." ) );
107 addParameter( outputScaling.release() );
109 auto outputParam = std::make_unique<QgsProcessingParameterRasterDestination>( u
"OUTPUT"_s, QObject::tr(
"Heatmap" ) );
110 outputParam->setHelp( QObject::tr(
"The output heatmap raster layer." ) );
111 addParameter( outputParam.release() );
114QString QgsHeatmapAlgorithm::shortHelpString()
const
117 "This algorithm creates a density (heatmap) raster of an input point vector layer using kernel density estimation. "
118 "Heatmaps allow easy identification of hotspots and clustering of points.\n\n"
119 "The density is calculated based on the number of points in a location, "
120 "with larger numbers of clustered points resulting in larger values."
124QString QgsHeatmapAlgorithm::shortDescription()
const
126 return QObject::tr(
"Creates a heatmap from points using kernel density estimation." );
129QgsHeatmapAlgorithm *QgsHeatmapAlgorithm::createInstance()
const
131 return new QgsHeatmapAlgorithm();
136 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u
"INPUT"_s, context ) );
140 const double radius = parameterAsDouble( parameters, u
"RADIUS"_s, context );
141 const int kernelShape = parameterAsEnum( parameters, u
"KERNEL"_s, context );
142 const double pixelSize = parameterAsDouble( parameters, u
"PIXEL_SIZE"_s, context );
143 const double decay = parameterAsDouble( parameters, u
"DECAY"_s, context );
144 const int outputValues = parameterAsEnum( parameters, u
"OUTPUT_VALUE"_s, context );
145 const QString outputFile = parameterAsOutputLayer( parameters, u
"OUTPUT"_s, context );
146 const QString weightField = parameterAsString( parameters, u
"WEIGHT_FIELD"_s, context );
147 const QString radiusField = parameterAsString( parameters, u
"RADIUS_FIELD"_s, context );
149 const QString outputFormat = parameterAsOutputRasterFormat( parameters, u
"OUTPUT"_s, context );
153 kdeParams.
source = source.get();
154 kdeParams.
radius = radius;
157 if ( !radiusField.isEmpty() )
159 const int fieldIndex = source->fields().lookupField( radiusField );
160 if ( fieldIndex < 0 )
162 throw QgsProcessingException( QObject::tr(
"Invalid radius field: “%1” does not exist" ).arg( radiusField ) );
165 attrs.append( fieldIndex );
168 if ( !weightField.isEmpty() )
170 const int fieldIndex = source->fields().lookupField( weightField );
171 if ( fieldIndex < 0 )
173 throw QgsProcessingException( QObject::tr(
"Invalid weight field: “%1” does not exist" ).arg( weightField ) );
177 attrs.append( fieldIndex );
192 const double total = source->featureCount() > 0 ? 100.0 / source->featureCount() : 0;
200 feedback->
reportError( QObject::tr(
"Error adding feature with ID %1 to heatmap" ).arg( f.
id() ) );
210 outputs.insert( u
"OUTPUT"_s, outputFile );
@ VectorPoint
Vector point layers.
@ Numeric
Accepts numeric fields.
@ Advanced
Parameter is an advanced parameter which should be hidden from users by default.
@ Double
Double/float values.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
Wraps a request for features to a vector layer (or directly its vector data provider).
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool isCanceled() const
Tells whether the operation has been canceled already.
void setProgress(double progress)
Sets the current progress for the feedback object.
Performs Kernel Density Estimation ("heatmap") calculations on a vector layer.
KernelShape
Kernel shape type.
OutputValues
Output values type.
@ Success
Operation completed successfully.
Contains information about the context in which a processing algorithm is executed.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
virtual void reportError(const QString &error, bool fatalError=false)
Reports that the algorithm encountered an error while executing.
QgsKernelDensityEstimation::OutputValues outputValues
Type of output value.
QString radiusField
Field for radius, or empty if using a fixed radius.
double radius
Fixed radius, in map units.
QgsFeatureSource * source
Point feature source.
double decayRatio
Decay ratio (Triangular kernels only).
QgsKernelDensityEstimation::KernelShape shape
Kernel shape.
QString weightField
Field name for weighting field, or empty if not using weights.
double pixelSize
Size of pixel in output file.