30 #include <QDomDocument>
31 #include <QDomElement>
35 , mCalculatedMaxValue( 0 )
40 , mWeightAttrNum( -1 )
42 , mInvertRamp( false )
45 , mFeaturesRendered( 0 )
60 mCalculatedMaxValue = 0;
61 mFeaturesRendered = 0;
63 mRadiusSquared = mRadiusPixels * mRadiusPixels;
76 if ( mWeightAttrNum == -1 )
79 mWeightExpression->prepare( fields );
82 initializeValues( context );
103 Q_UNUSED( selected );
104 Q_UNUSED( drawVertexMarker );
118 if ( !mWeightExpressionString.
isEmpty() )
121 if ( mWeightAttrNum == -1 )
123 Q_ASSERT( mWeightExpression.
data() );
124 value = mWeightExpression->evaluate( &feature );
129 value = attrs.
value( mWeightAttrNum );
132 double evalWeight = value.
toDouble( &ok );
154 delete transformedGeom;
161 int pointX = pixel.
x() / mRenderQuality;
162 int pointY = pixel.
y() / mRenderQuality;
163 for (
int x = qMax( pointX - mRadiusPixels, 0 ); x < qMin( pointX + mRadiusPixels, width ); ++x )
165 for (
int y = qMax( pointY - mRadiusPixels, 0 ); y < qMin( pointY + mRadiusPixels, height ); ++y )
167 int index = y * width + x;
168 if ( index >= mValues.
count( ) )
172 double distanceSquared = pow( pointX - x, 2.0 ) + pow( pointY - y, 2.0 );
173 if ( distanceSquared > mRadiusSquared )
178 double score = weight * quarticKernel( sqrt( distanceSquared ), mRadiusPixels );
179 double value = mValues[
index ] + score;
180 if ( value > mCalculatedMaxValue )
182 mCalculatedMaxValue = value;
184 mValues[
index ] = value;
192 if ( mFeaturesRendered % 200 == 0 )
194 renderImage( context );
201 double QgsHeatmapRenderer::uniformKernel(
const double distance,
const int bandwidth )
const
203 Q_UNUSED( distance );
204 Q_UNUSED( bandwidth );
208 double QgsHeatmapRenderer::quarticKernel(
const double distance,
const int bandwidth )
const
210 return pow( 1. - pow( distance / (
double )bandwidth, 2 ), 2 );
213 double QgsHeatmapRenderer::triweightKernel(
const double distance,
const int bandwidth )
const
215 return pow( 1. - pow( distance / (
double )bandwidth, 2 ), 3 );
218 double QgsHeatmapRenderer::epanechnikovKernel(
const double distance,
const int bandwidth )
const
220 return ( 1. - pow( distance / (
double )bandwidth, 2 ) );
223 double QgsHeatmapRenderer::triangularKernel(
const double distance,
const int bandwidth )
const
225 return ( 1. - ( distance / (
double )bandwidth ) );
230 renderImage( context );
231 mWeightExpression.
reset();
236 if ( !context.
painter() || !mGradientRamp )
243 QImage::Format_ARGB32 );
244 image.
fill( Qt::transparent );
246 double scaleMax = mExplicitMax > 0 ? mExplicitMax : mCalculatedMaxValue;
251 for (
int heightIndex = 0; heightIndex < image.height(); ++heightIndex )
253 QRgb* scanLine = ( QRgb* )image.scanLine( heightIndex );
254 for (
int widthIndex = 0; widthIndex < image.width(); ++widthIndex )
257 pixVal = mValues.
at( idx ) > 0 ? qMin(( mValues.
at( idx ) / scaleMax ), 1.0 ) : 0;
260 pixColor = mGradientRamp->
color( mInvertRamp ? 1 - pixVal : pixVal );
262 scanLine[widthIndex] = pixColor.
rgba();
267 if ( mRenderQuality > 1 )
307 double extension = 0.0;
338 if ( !sourceColorRampElem.
isNull() && sourceColorRampElem.
attribute(
"name" ) ==
"[source]" )
355 rendererElem.
setAttribute(
"weight_expression", mWeightExpressionString );
388 attributes << mWeightExpressionString;
394 return attributes.
toList();
399 if ( renderer->
type() ==
"heatmapRenderer" )
411 delete mGradientRamp;
412 mGradientRamp = ramp;
Class for parsing and evaluation of expressions (formerly called "search strings").
void setInvertRamp(const bool invert)
Sets whether the ramp is inverted.
#define RENDERER_TAG_NAME
A rectangle specified with double values.
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
virtual ~QgsHeatmapRenderer()
QStringList referencedColumns() const
Get list of columns referenced by the expression.
virtual bool renderFeature(QgsFeature &feature, QgsRenderContext &context, int layer=-1, bool selected=false, bool drawVertexMarker=false) override
static QgsVectorColorRampV2 * loadColorRamp(QDomElement &element)
virtual QString dump() const override
for debugging
static QgsFeatureRendererV2 * create(QDomElement &element)
virtual QList< QString > usedAttributes() override
QList< QgsSymbolV2 * > QgsSymbolV2List
QDomNode appendChild(const QDomNode &newChild)
void setXMaximum(double x)
Set the maximum x value.
virtual void modifyRequestExtent(QgsRectangle &extent, QgsRenderContext &context) override
Allows for a renderer to modify the extent of a feature request prior to rendering.
QString attribute(const QString &name, const QString &defValue) const
double yMaximum() const
Get the y maximum value (top side of rectangle)
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name - case insensitive TODO: sort out case sensitive (indexFromName()) vs...
QVector< T > & fill(const T &value, int size)
const_iterator constEnd() const
QgsPoint transform(const QgsPoint &p) const
Transform the point from map (world) coordinates to device coordinates.
QGis::GeometryType type() const
Returns type of the geometry as a QGis::GeometryType.
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
void setWeightExpression(const QString &expression)
Sets the expression used for weighting points when generating the heatmap.
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
const QgsCoordinateTransform * coordinateTransform() const
QgsPaintEffect * mPaintEffect
void setRadiusUnit(const QgsSymbolV2::OutputUnit unit)
Sets the units used for the heatmap's radius.
static double pixelSizeScaleFactor(const QgsRenderContext &c, QgsSymbolV2::OutputUnit u, const QgsMapUnitScale &scale=QgsMapUnitScale())
Returns scale factor painter units -> pixel dimensions.
virtual QgsSymbolV2List symbols() override
for symbol levels
virtual QgsFeatureRendererV2 * clone() const =0
QString number(int n, int base)
static QDomElement saveColorRamp(QString name, QgsVectorColorRampV2 *ramp, QDomDocument &doc)
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
void fill(uint pixelValue)
double xMaximum() const
Get the x maximum value (right side of rectangle)
A renderer which draws points as a live heatmap.
QgsAttributes attributes() const
Returns the feature's attributes.
void setRadiusMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale used for the heatmap's radius.
void setAttribute(const QString &name, const QString &value)
virtual QgsVectorColorRampV2 * clone() const =0
int toInt(bool *ok, int base) const
void setYMinimum(double y)
Set the minimum y value.
QPaintDevice * device() const
virtual QDomElement save(QDomDocument &doc) override
store renderer info to XML element
virtual void startRender(QgsRenderContext &context, const QgsFields &fields) override
virtual QgsFeatureRendererV2 * clone() const override
A class to represent a point.
void setRenderQuality(const int quality)
Sets the render quality used for drawing the heatmap.
virtual QColor color(double value) const =0
virtual QgsSymbolV2 * symbolForFeature(QgsFeature &feature) override
to be overridden
void setRadius(const double radius)
Sets the radius for the heatmap.
const T & at(int i) const
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
const_iterator constBegin() const
void setColorRamp(QgsVectorColorRampV2 *ramp)
Sets the color ramp to use for shading the heatmap.
Contains information about the context of a rendering operation.
void drawImage(const QRectF &target, const QImage &image, const QRectF &source, QFlags< Qt::ImageConversionFlag > flags)
void copyPaintEffect(QgsFeatureRendererV2 *destRenderer) const
Copies paint effect of this renderer to another renderer.
QSet< T > & unite(const QSet< T > &other)
static QgsHeatmapRenderer * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
void setYMaximum(double y)
Set the maximum y value.
float toFloat(bool *ok) const
QgsMultiPoint asMultiPoint() const
Return contents of the geometry as a multi point if wkbType is WKBMultiPoint, otherwise an empty list...
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
QDomElement firstChildElement(const QString &tagName) const
int count(const T &value) const
virtual void stopRender(QgsRenderContext &context) override
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
int transform(const QgsCoordinateTransform &ct)
Transform this geometry as described by CoordinateTransform ct.
const QgsMapToPixel & mapToPixel() const
QList< T > toList() const
double toDouble(bool *ok) const
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
QDomElement createElement(const QString &tagName)
QgsPoint asPoint() const
Return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
double xMinimum() const
Get the x minimum value (left side of rectangle)
void setMaximumValue(const double value)
Sets the maximum value used for shading the heatmap.
QImage scaled(int width, int height, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const
void setXMinimum(double x)
Set the minimum x value.