Skip to content

Commit

Permalink
Estimate a sensible default radius for heatmaps from the layer extent
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Mar 30, 2013
1 parent 6e75ea4 commit 70685fc
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
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

0 comments on commit 70685fc

Please sign in to comment.