Skip to content

Commit

Permalink
Merge pull request #490 from nyalldawson/heatmap_fixes
Browse files Browse the repository at this point in the history
Choose sensible default value for heatmap radius, some small documentation updates
  • Loading branch information
NathanW2 committed Mar 30, 2013
2 parents 72b476e + 86ba94b commit 5602c8e
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 22 deletions.
28 changes: 17 additions & 11 deletions resources/context_help/HeatmapGui-en_US
@@ -1,26 +1,32 @@
<h1>Heatmap Plugin Help</h1>
<p>Heatmap Plugin creates a heatmap raster for the input point vector layer. The heatmap is generated based on the number of points in a given location. The higher the number of points, the higher the corresponding pixel(s) value will be in the raster.</p>
<p>The Heatmap plugin uses Kernel Density Estimation to create a density (heatmap) raster of an input point vector layer. The density is calculated based on the number of points in a location, with larger numbers of clustered points resulting in a larger raster values.</p>

<h2>The Dialog Parameters</h2>
<h2>Dialog Parameters</h2>

<h3>Input Point Vector</h3>
<p>The input is always a vector layer of point type. All the point vector layers that are currently loaded in the canvas are automatically populated in the input layer drop-down list. Click the dropdown button and select the desired layer.</p>
<p>The input is always a vector layer of point type. All the point vector layers that are currently loaded in the canvas are shown in the drop-down list. Click the dropdown button and select the desired layer.</p>

<h3>Output Ratser</h3>
<h3>Output Raster</h3>
<p>The output raster location and filename can be set by clicking the <label>...</label> button next to the output raster textbox.<br/>
<b>Note:</b>The file format is automatically added depending upon the output format selected, if not explicitly given.</p>
<b>Note:</b> The file format is automatically added depending upon the output format selected, if not explicitly given.</p>

<h3>Output Format</h3>
<p>All the file creation supporting GDAL formats are available in the drop down list. Click and select the required output format for your file.<br/>
<b>Note:</b> GeoTiff and ERDAS Imagine .img formats are recommended. Some formats make the application crash. Kindly stick to the recommended formats until the crash issue is resolved or use an other formats if you know GDAL supports it completely.</p>

<h3>Heatmap Point Attributes</h3>
<h4>Buffer Radius</h4>
<p>The buffer radius specifies the number of <b>pixels or cells</b> around a point where the heat(influence) of the point will be felt. Smaller values give you clear distinction between points and bigger values gives you nicely merged heatmap regions. This is the spatial parameter of the heat region of a point.<br/>
<b>Note:</b> The value is always a whole number.</p>
<h4>Decay Ratio</h4>
<p>The decay ratio defines amount of heat(influence) that should reach the outermost pixel in the Buffer Radius. It is the direct measure of the outer most value.<br/>
<b>Example:</b> If decay Ratio is set to 0 and radius to 10, then the center pixel of a point will have value and the pixel away by a distance of 10 units will have the value 0, a pixel which is 5 units away will have a value of 0.5 and so on. Here distance is measure not by pixel count rather using sqrt( xOffset^2 + yOffset^2 ), so you always get a circular heat region.</p>
<h4>Radius (bandwidth)</h4>
<p>The buffer radius specifies the distance around a point at which the influence of the point will be felt. Larger values result in greater smoothing, but smaller values may show finer details.</p>

<h4>Kernel shape</h4>
<p>The kernel shape parameter controls the rate at which the influence of a point decreases as the distance from the point increases. A number of standard kernel functions are available, which are described in detail on <a href="http://en.wikipedia.org/wiki/Kernel_(statistics)#Kernel_functions_in_common_use">Wikipedia</a>.
</p>
<h4>Use radius from field</h4>
<p>Optionally, the value in a specified field can be used to control the kernel radius for each point in the input layer.</p>
<h4>Use weight from field</h4>
<p>Optionally, a column containg weights for points can be used to weight some points in the input layer more than others.</p>
<h4>Decay ratio</h4>
<p>For triangular kernels, the decay ratio defines amount of influence that applies to the outermost pixels in the buffer radius. A value of 0 reflects a standard triangular kernel, where the influences drops to zero as the distance from the pixel to the point approaches the specified radius. In contrast, a value of 1 indicates that no falloff occurs as the distance from the point increases.</p>

<h2>Further Details</h2>
<p>Contact the author through aruntheguy at gmail dot com</p>
Expand Down
46 changes: 45 additions & 1 deletion src/plugins/heatmap/heatmapgui.cpp
Expand Up @@ -204,13 +204,57 @@ void HeatmapGui::on_mRadiusUnitCombo_currentIndexChanged( int index )
updateBBox();
}

/*
* Estimate a good default radius for the heatmap, based on the
* bounding box size of the layer
*/
double HeatmapGui::estimateRadius()
{

QgsVectorLayer *inputLayer = inputVectorLayer();

// No input layer? Default to radius of 100
if ( !inputLayer )
return 100;

// Find max dimension of layer bounding box
QgsRectangle mExtent = inputLayer->extent();
double extentWidth = abs( mExtent.xMinimum() - mExtent.xMaximum() );
double extentHeight = abs( mExtent.yMinimum() - mExtent.yMaximum() );
double maxExtent = max( extentWidth, extentHeight );

// Return max dimension divided by 30. This is fairly arbitrary
// but approximately corresponds to the default value chosen by ArcMap
// TODO - a better solution is to let the data define the radius
// choice by setting the radius equal to the average Nearest
// Neighbour Index for the closest n points

double estimate = maxExtent / 30;

if ( mRadiusUnitCombo->currentIndex() == HeatmapGui::Meters )
{
// metres selected, so convert estimate from map units
QgsCoordinateReferenceSystem layerCrs = inputLayer->crs();
estimate = estimate / mapUnitsOf( 1, layerCrs );
}

// Make estimate pretty by rounding off to first digit only (eg 356->300, 0.567->0.5)
double tens = pow( 10, floor( log10( estimate ) ) );
return floor( estimate / tens + 0.5 ) * tens;
}

void HeatmapGui::on_mInputVectorCombo_currentIndexChanged( int index )
{
Q_UNUSED( index );

// Set initial value for radius field based on layer's extent
mBufferLineEdit->setText( QString::number( estimateRadius() ) );

updateBBox();

if ( advancedGroupBox->isChecked() )
{
populateFields();
updateBBox();
}
QgsDebugMsg( QString( "Input vector index changed to %1" ).arg( index ) );
}
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/heatmap/heatmapgui.h
Expand Up @@ -124,6 +124,12 @@ class HeatmapGui : public QDialog, private Ui::HeatmapGuiBase
void on_mInputVectorCombo_currentIndexChanged( int index );
void on_mBufferLineEdit_editingFinished();
void on_kernelShapeCombo_currentIndexChanged( int index );

/** Estimate a reasonable starting value for the radius field */
double estimateRadius();

inline double max( double a, double b )
{ return a > b ? a : b; }
};

#endif
20 changes: 10 additions & 10 deletions src/plugins/heatmap/heatmapguibase.ui
Expand Up @@ -26,7 +26,7 @@
<item row="0" column="0">
<widget class="QLabel" name="mInputLabel">
<property name="text">
<string>Input Point Vector</string>
<string>Input point layer</string>
</property>
</widget>
</item>
Expand All @@ -36,7 +36,7 @@
<item row="1" column="0">
<widget class="QLabel" name="mOutputLabel">
<property name="text">
<string>Output Raster</string>
<string>Output raster</string>
</property>
</widget>
</item>
Expand All @@ -59,7 +59,7 @@
<item row="3" column="0">
<widget class="QLabel" name="mFormatLabel">
<property name="text">
<string>Output Format</string>
<string>Output format</string>
</property>
</widget>
</item>
Expand Down Expand Up @@ -137,7 +137,7 @@
<item row="1" column="0">
<widget class="QLabel" name="cellsizeXLabel">
<property name="text">
<string>Cell Size X</string>
<string>Cell size X</string>
</property>
<property name="buddy">
<cstring>cellXLineEdit</cstring>
Expand All @@ -157,7 +157,7 @@
<item row="1" column="2">
<widget class="QLabel" name="cellsizeYLabel">
<property name="text">
<string>Cell Size Y</string>
<string>Cell size Y</string>
</property>
<property name="buddy">
<cstring>cellYLineEdit</cstring>
Expand All @@ -183,7 +183,7 @@
<item row="1" column="0">
<widget class="QCheckBox" name="useRadius">
<property name="text">
<string>Use Radius from field</string>
<string>Use radius from field</string>
</property>
</widget>
</item>
Expand Down Expand Up @@ -214,7 +214,7 @@
<item row="2" column="0">
<widget class="QCheckBox" name="useWeight">
<property name="text">
<string>Use Weight from field</string>
<string>Use weight from field</string>
</property>
</widget>
</item>
Expand All @@ -238,15 +238,15 @@
<item row="3" column="0">
<widget class="QLabel" name="mDecayLabel">
<property name="text">
<string>Decay Ratio</string>
<string>Decay ratio</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="kernelShapeCombo">
<item>
<property name="text">
<string>Quartic (Biweight)</string>
<string>Quartic (biweight)</string>
</property>
</item>
<item>
Expand Down Expand Up @@ -274,7 +274,7 @@
<item row="0" column="0">
<widget class="QLabel" name="kernelShapeLable">
<property name="text">
<string>Kernel Shape</string>
<string>Kernel shape</string>
</property>
</widget>
</item>
Expand Down

0 comments on commit 5602c8e

Please sign in to comment.