Add option for unscaled values for heatmaps rasters, set as default

This commit is contained in:
Nyall Dawson 2014-09-24 21:35:23 +10:00
parent 957e791070
commit 9cdea17421
5 changed files with 274 additions and 216 deletions

View File

@ -132,7 +132,8 @@ void Heatmap::run()
int rows = d.rows();
double cellsize = d.cellSizeX(); // or d.cellSizeY(); both have the same value
mDecay = d.decayRatio();
int kernelShape = d.kernelShape();
KernelShape kernelShape = d.kernelShape();
OutputValues valueType = d.outputValues();
//is input layer multipoint?
bool isMultiPoint = inputLayer->wkbType() == QGis::WKBMultiPoint || inputLayer->wkbType() == QGis::WKBMultiPoint25D;
@ -311,7 +312,7 @@ void Heatmap::run()
continue;
}
double pixelValue = weight * calculateKernelValue( distance, myBuffer, kernelShape );
double pixelValue = weight * calculateKernelValue( distance, myBuffer, kernelShape, valueType );
// clearing anamolies along the axes
if ( xp == 0 && yp == 0 )
@ -386,24 +387,24 @@ int Heatmap::bufferSize( double radius, double cellsize )
return buffer;
}
double Heatmap::calculateKernelValue( double distance, int bandwidth, int kernelShape )
double Heatmap::calculateKernelValue( const double distance, const int bandwidth, const KernelShape shape, const OutputValues outputType )
{
switch ( kernelShape )
switch ( shape )
{
case Heatmap::Triangular:
return triangularKernel( distance , bandwidth );
return triangularKernel( distance , bandwidth, outputType );
case Heatmap::Uniform:
return uniformKernel( distance, bandwidth );
return uniformKernel( distance, bandwidth, outputType );
case Heatmap::Quartic:
return quarticKernel( distance, bandwidth );
return quarticKernel( distance, bandwidth, outputType );
case Heatmap::Triweight:
return triweightKernel( distance, bandwidth );
return triweightKernel( distance, bandwidth, outputType );
case Heatmap::Epanechnikov:
return epanechnikovKernel( distance, bandwidth );
return epanechnikovKernel( distance, bandwidth, outputType );
}
return 0;
@ -417,59 +418,99 @@ double Heatmap::calculateKernelValue( double distance, int bandwidth, int kernel
* k is calculated by polar double integration of the kernel function
* between a radius of 0 to the specified bandwidth and equating the area to 1. */
double Heatmap::uniformKernel( double distance, int bandwidth )
double Heatmap::uniformKernel( const double distance, const int bandwidth, const OutputValues outputType ) const
{
Q_UNUSED( distance );
// Normalizing constant
double k = 2. / ( M_PI * ( double )bandwidth );
// Derived from Wand and Jones (1995), p. 175
return k * ( 0.5 / ( double )bandwidth );
}
double Heatmap::quarticKernel( double distance, int bandwidth )
{
// Normalizing constant
double k = 16. / ( 5. * M_PI * pow(( double )bandwidth, 2 ) );
// Derived from Wand and Jones (1995), p. 175
return k * ( 15. / 16. ) * pow( 1. - pow( distance / ( double )bandwidth, 2 ), 2 );
}
double Heatmap::triweightKernel( double distance, int bandwidth )
{
// Normalizing constant
double k = 128. / ( 35. * M_PI * pow(( double )bandwidth, 2 ) );
// Derived from Wand and Jones (1995), p. 175
return k * ( 35. / 32. ) * pow( 1. - pow( distance / ( double )bandwidth, 2 ), 3 );
}
double Heatmap::epanechnikovKernel( double distance, int bandwidth )
{
// Normalizing constant
double k = 8. / ( 3. * M_PI * pow(( double )bandwidth, 2 ) );
// Derived from Wand and Jones (1995), p. 175
return k * ( 3. / 4. ) * ( 1. - pow( distance / ( double )bandwidth, 2 ) );
}
double Heatmap::triangularKernel( double distance, int bandwidth )
{
// Normalizing constant. In this case it's calculated a little different
// due to the inclusion of the non-standard "decay" parameter
if ( mDecay >= 0 )
switch ( outputType )
{
double k = 3. / (( 1. + 2. * mDecay ) * M_PI * pow(( double )bandwidth, 2 ) );
case Heatmap::Scaled:
{
// Normalizing constant
double k = 2. / ( M_PI * ( double )bandwidth );
// Derived from Wand and Jones (1995), p. 175 (with addition of decay parameter)
return k * ( 1. - ( 1. - mDecay ) * ( distance / ( double )bandwidth ) );
// Derived from Wand and Jones (1995), p. 175
return k * ( 0.5 / ( double )bandwidth );
}
default:
return 1.0;
}
else
}
double Heatmap::quarticKernel( const double distance, const int bandwidth, const OutputValues outputType ) const
{
switch ( outputType )
{
// Non-standard or mathematically valid negative decay ("coolmap")
return ( 1. - ( 1. - mDecay ) * ( distance / ( double )bandwidth ) );
case Heatmap::Scaled:
{
// Normalizing constant
double k = outputType == Heatmap::Scaled ? 116. / ( 5. * M_PI * pow(( double )bandwidth, 2 ) ) : 1.0;
// Derived from Wand and Jones (1995), p. 175
return k * ( 15. / 16. ) * pow( 1. - pow( distance / ( double )bandwidth, 2 ), 2 );
}
default:
return pow( 1. - pow( distance / ( double )bandwidth, 2 ), 2 );
}
}
double Heatmap::triweightKernel( const double distance, const int bandwidth, const OutputValues outputType ) const
{
switch ( outputType )
{
case Heatmap::Scaled:
{
// Normalizing constant
double k = outputType == Heatmap::Scaled ? 128. / ( 35. * M_PI * pow(( double )bandwidth, 2 ) ) : 1.0;
// Derived from Wand and Jones (1995), p. 175
return k * ( 35. / 32. ) * pow( 1. - pow( distance / ( double )bandwidth, 2 ), 3 );
}
default:
return pow( 1. - pow( distance / ( double )bandwidth, 2 ), 3 );
}
}
double Heatmap::epanechnikovKernel( const double distance, const int bandwidth, const OutputValues outputType ) const
{
switch ( outputType )
{
case Heatmap::Scaled:
{
// Normalizing constant
double k = outputType == Heatmap::Scaled ? 8. / ( 3. * M_PI * pow(( double )bandwidth, 2 ) ) : 1.0;
// Derived from Wand and Jones (1995), p. 175
return k * ( 3. / 4. ) * ( 1. - pow( distance / ( double )bandwidth, 2 ) );
}
default:
return ( 1. - pow( distance / ( double )bandwidth, 2 ) );
}
}
double Heatmap::triangularKernel( const double distance, const int bandwidth, const OutputValues outputType ) const
{
switch ( outputType )
{
case Heatmap::Scaled:
{
// Normalizing constant. In this case it's calculated a little different
// due to the inclusion of the non-standard "decay" parameter
if ( mDecay >= 0 )
{
double k = 3. / (( 1. + 2. * mDecay ) * M_PI * pow(( double )bandwidth, 2 ) );
// Derived from Wand and Jones (1995), p. 175 (with addition of decay parameter)
return k * ( 1. - ( 1. - mDecay ) * ( distance / ( double )bandwidth ) );
}
else
{
// Non-standard or mathematically valid negative decay ("coolmap")
return ( 1. - ( 1. - mDecay ) * ( distance / ( double )bandwidth ) );
}
}
default:
return ( 1. - ( 1. - mDecay ) * ( distance / ( double )bandwidth ) );
}
}

View File

@ -71,7 +71,7 @@ class Heatmap: public QObject, public QgisPlugin
virtual ~Heatmap();
// Kernel shape type
enum kernelShape
enum KernelShape
{
Quartic,
Triangular,
@ -80,6 +80,13 @@ class Heatmap: public QObject, public QgisPlugin
Epanechnikov
};
// Output values type
enum OutputValues
{
Raw,
Scaled
};
QMap<QString, QVariant> mSessionSettings;
public slots:
@ -100,17 +107,17 @@ class Heatmap: public QObject, public QgisPlugin
//! Worker to calculate buffer size in pixels
int bufferSize( double radius, double cellsize );
//! Calculate the value given to a point width a given distance for a specified kernel shape
double calculateKernelValue( double distance, int bandwidth, int kernelShape );
double calculateKernelValue( const double distance, const int bandwidth, const KernelShape shape, const OutputValues outputType );
//! Uniform kernel function
double uniformKernel( double distance, int bandwidth );
double uniformKernel( const double distance, const int bandwidth , const OutputValues outputType ) const;
//! Quartic kernel function
double quarticKernel( double distance, int bandwidth );
double quarticKernel( const double distance, const int bandwidth , const OutputValues outputType ) const;
//! Triweight kernel function
double triweightKernel( double distance, int bandwidth );
double triweightKernel( const double distance, const int bandwidth , const OutputValues outputType ) const;
//! Epanechnikov kernel function
double epanechnikovKernel( double distance, int bandwidth );
double epanechnikovKernel( const double distance, const int bandwidth, const OutputValues outputType ) const;
//! Triangular kernel function
double triangularKernel( double distance, int bandwidth );
double triangularKernel( const double distance, const int bandwidth , const OutputValues outputType ) const;
// MANDATORY PLUGIN PROPERTY DECLARATIONS .....

View File

@ -46,6 +46,15 @@ HeatmapGui::HeatmapGui( QWidget* parent, Qt::WindowFlags fl, QMap<QString, QVari
blockAllSignals( true );
mKernelShapeCombo->addItem( tr( "Quartic (biweight)" ), Heatmap::Quartic );
mKernelShapeCombo->addItem( tr( "Triangular" ), Heatmap::Triangular );
mKernelShapeCombo->addItem( tr( "Uniform" ), Heatmap::Uniform );
mKernelShapeCombo->addItem( tr( "Triweight" ), Heatmap::Triweight );
mKernelShapeCombo->addItem( tr( "Epanechnikov" ), Heatmap::Epanechnikov );
mOutputValuesComboBox->addItem( tr( "Raw values" ), Heatmap::Raw );
mOutputValuesComboBox->addItem( tr( "Scaled by kernel size" ), Heatmap::Scaled );
mHeatmapSessionSettings = temporarySettings;
// Adding point layers to the inputLayerCombo
@ -124,6 +133,7 @@ void HeatmapGui::blockAllSignals( bool b )
mColumnsSpinBox->blockSignals( b );
mCellXLineEdit->blockSignals( b );
mCellYLineEdit->blockSignals( b );
mOutputValuesComboBox->blockSignals( b );
}
/*
@ -184,10 +194,15 @@ void HeatmapGui::restoreSettings( bool usingLastInputLayer )
// Kernel setting - not layer specific
if ( mHeatmapSessionSettings->value( QString( "lastKernel" ) ).toInt() )
{
mKernelShapeCombo->setCurrentIndex( mHeatmapSessionSettings->value( QString( "lastKernel" ) ).toInt() );
mKernelShapeCombo->setCurrentIndex( mKernelShapeCombo->findData(
( Heatmap::KernelShape )( mHeatmapSessionSettings->value( QString( "lastKernel" ) ).toInt() ) ) );
mDecayLineEdit->setText( mHeatmapSessionSettings->value( QString( "decayRatio" ) ).toString() );
mDecayLineEdit->setEnabled( mAdvancedGroupBox->isChecked() && mKernelShapeCombo->currentIndex() == Heatmap::Triangular );
mDecayLineEdit->setEnabled( mAdvancedGroupBox->isChecked() &&
( Heatmap::KernelShape )( mKernelShapeCombo->itemData( mKernelShapeCombo->currentIndex() ).toInt() ) == Heatmap::Triangular );
}
mOutputValuesComboBox->setCurrentIndex( mOutputValuesComboBox->findData(
( Heatmap::OutputValues )( mHeatmapSessionSettings->value( QString( "lastOutputValues" ), "0" ).toInt() ) ) );
}
void HeatmapGui::saveSettings()
@ -203,13 +218,14 @@ void HeatmapGui::saveSettings()
mHeatmapSessionSettings->insert( QString( "lastRadiusUnit" ), QVariant( mBufferUnitCombo->currentIndex() ) );
mHeatmapSessionSettings->insert( QString( "advancedEnabled" ), QVariant( mAdvancedGroupBox->isChecked() ) );
mHeatmapSessionSettings->insert( QString( "lastRows" ), QVariant( mRowsSpinBox->value() ) );
mHeatmapSessionSettings->insert( QString( "lastKernel" ), QVariant( mKernelShapeCombo->currentIndex() ) );
mHeatmapSessionSettings->insert( QString( "lastKernel" ), QVariant( mKernelShapeCombo->itemData( mKernelShapeCombo->currentIndex() ).toInt() ) );
mHeatmapSessionSettings->insert( QString( "useRadius" ), QVariant( mRadiusFieldCheckBox->isChecked() ) );
mHeatmapSessionSettings->insert( QString( "radiusField" ), QVariant( mRadiusFieldCombo->currentField() ) );
mHeatmapSessionSettings->insert( QString( "radiusFieldUnit" ), QVariant( mRadiusFieldUnitCombo->currentIndex() ) );
mHeatmapSessionSettings->insert( QString( "useWeight" ), QVariant( mWeightFieldCheckBox->isChecked() ) );
mHeatmapSessionSettings->insert( QString( "weightField" ), QVariant( mWeightFieldCombo->currentField() ) );
mHeatmapSessionSettings->insert( QString( "decayRatio" ), QVariant( mDecayLineEdit->text() ) );
mHeatmapSessionSettings->insert( QString( "lastOutputValues" ), QVariant( mOutputValuesComboBox->itemData( mOutputValuesComboBox->currentIndex() ).toInt() ) );
}
void HeatmapGui::on_mButtonBox_rejected()
@ -260,7 +276,8 @@ void HeatmapGui::on_mAdvancedGroupBox_toggled( bool enabled )
}
updateBBox();
mDecayLineEdit->setEnabled( mKernelShapeCombo->currentIndex() == Heatmap::Triangular );
mDecayLineEdit->setEnabled(( Heatmap::KernelShape )( mKernelShapeCombo->itemData( mKernelShapeCombo->currentIndex() ).toInt() ) == Heatmap::Triangular );
}
}
@ -464,7 +481,7 @@ void HeatmapGui::updateBBox()
updateSize();
}
double HeatmapGui::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs )
double HeatmapGui::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs ) const
{
// converter function to transform metres input to mapunits
// so that bounding box can be updated
@ -485,17 +502,17 @@ double HeatmapGui::mapUnitsOf( double meters, QgsCoordinateReferenceSystem layer
*
*/
bool HeatmapGui::weighted()
bool HeatmapGui::weighted() const
{
return mWeightFieldCheckBox->isChecked();
}
bool HeatmapGui::variableRadius()
bool HeatmapGui::variableRadius() const
{
return mRadiusFieldCheckBox->isChecked();
}
double HeatmapGui::radius()
double HeatmapGui::radius() const
{
double radius = mBufferSizeLineEdit->text().toDouble();
if ( mBufferUnitCombo->currentIndex() == HeatmapGui::Meters )
@ -505,7 +522,7 @@ double HeatmapGui::radius()
return radius;
}
int HeatmapGui::radiusUnit()
int HeatmapGui::radiusUnit() const
{
if ( mRadiusFieldCheckBox->isChecked() )
{
@ -514,17 +531,22 @@ int HeatmapGui::radiusUnit()
return mBufferUnitCombo->currentIndex();
}
int HeatmapGui::kernelShape()
Heatmap::KernelShape HeatmapGui::kernelShape() const
{
return mKernelShapeCombo->currentIndex();
return ( Heatmap::KernelShape ) mKernelShapeCombo->itemData( mKernelShapeCombo->currentIndex() ).toInt();
}
double HeatmapGui::decayRatio()
Heatmap::OutputValues HeatmapGui::outputValues() const
{
return ( Heatmap::OutputValues ) mOutputValuesComboBox->itemData( mOutputValuesComboBox->currentIndex() ).toInt();
}
double HeatmapGui::decayRatio() const
{
return mDecayLineEdit->text().toDouble();
}
int HeatmapGui::radiusField()
int HeatmapGui::radiusField() const
{
QgsVectorLayer *inputLayer = inputVectorLayer();
if ( !inputLayer )
@ -533,7 +555,7 @@ int HeatmapGui::radiusField()
return inputLayer->pendingFields().indexFromName( mRadiusFieldCombo->currentField() );
}
int HeatmapGui::weightField()
int HeatmapGui::weightField() const
{
QgsVectorLayer *inputLayer = inputVectorLayer();
if ( !inputLayer )
@ -542,12 +564,12 @@ int HeatmapGui::weightField()
return inputLayer->pendingFields().indexFromName( mWeightFieldCombo->currentField() );
}
bool HeatmapGui::addToCanvas()
bool HeatmapGui::addToCanvas() const
{
return mAddToCanvas->isChecked();
}
QString HeatmapGui::outputFilename()
QString HeatmapGui::outputFilename() const
{
QString outputFileName;
QString outputFormat;
@ -582,7 +604,7 @@ QString HeatmapGui::outputFilename()
return outputFileName;
}
QString HeatmapGui::outputFormat()
QString HeatmapGui::outputFormat() const
{
return mFormatCombo->itemData( mFormatCombo->currentIndex() ).toString();
}

View File

@ -15,6 +15,7 @@
#include <QDialog>
#include <ui_heatmapguibase.h>
#include "heatmap.h"
#include "qgsvectorlayer.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsgeometry.h"
@ -37,55 +38,58 @@ class HeatmapGui : public QDialog, private Ui::HeatmapGuiBase
};
/** Returns whether to apply weighted heat */
bool weighted();
bool weighted() const;
/** Returns whether the radius is static or based on a field */
bool variableRadius();
bool variableRadius() const;
/** Returns the fixed radius value */
double radius();
double radius() const;
/** Return the radius Unit (meters/map units) */
int radiusUnit();
int radiusUnit() const;
/** Return the selected kernel shape */
int kernelShape();
Heatmap::KernelShape kernelShape() const;
/** Return the selected output values setting */
Heatmap::OutputValues outputValues() const;
/** Return the decay ratio */
double decayRatio();
double decayRatio() const;
/** Return the attribute field for variable radius */
int radiusField();
int radiusField() const;
/** Returns the attrinute field for weighted heat */
int weightField();
int weightField() const;
/** Returns state of the add to canvas checkbox*/
bool addToCanvas();
bool addToCanvas() const;
/** Returns the output filename/path */
QString outputFilename();
QString outputFilename() const;
/** Returns the GDAL Format for output raster */
QString outputFormat();
QString outputFormat() const;
/** Returns the input Vector layer */
QgsVectorLayer* inputVectorLayer() const;
/** Returns the no of rows for the raster */
int rows() { return mRows; }
int rows() const { return mRows; }
/** Returns the no of columns in the raster */
int columns() { return mColumns; }
int columns() const { return mColumns; }
/** Returns the cell size X value */
double cellSizeX() { return mXcellsize; }
double cellSizeX() const { return mXcellsize; }
/** Returns the cell size Y valuue */
double cellSizeY() { return mYcellsize; }
double cellSizeY() const { return mYcellsize; }
/** Return the BBox */
QgsRectangle bbox() { return mBBox; }
QgsRectangle bbox() const { return mBBox; }
private:
QMap<QString, QString> mExtensionMap;
@ -116,7 +120,7 @@ class HeatmapGui : public QDialog, private Ui::HeatmapGuiBase
void updateSize();
/** Convert Maters value to the corresponding map units based on Layer projection */
double mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs );
double mapUnitsOf( double meters, QgsCoordinateReferenceSystem layerCrs ) const;
/** Estimate a reasonable starting value for the radius field */
double estimateRadius();

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>460</width>
<height>447</height>
<height>493</height>
</rect>
</property>
<property name="sizePolicy">
@ -133,108 +133,6 @@
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QCheckBox" name="mRadiusFieldCheckBox">
<property name="text">
<string>Use radius from field</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsFieldComboBox" name="mRadiusFieldCombo">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="mRadiusFieldUnitCombo">
<property name="enabled">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>meters</string>
</property>
</item>
<item>
<property name="text">
<string>map units</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="mWeightFieldCheckBox">
<property name="text">
<string>Use weight from field</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QgsFieldComboBox" name="mWeightFieldCombo">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="mDecayLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>0.0</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="decayLabel">
<property name="text">
<string>Decay ratio</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="mKernelShapeCombo">
<item>
<property name="text">
<string>Quartic (biweight)</string>
</property>
</item>
<item>
<property name="text">
<string>Triangular</string>
</property>
</item>
<item>
<property name="text">
<string>Uniform</string>
</property>
</item>
<item>
<property name="text">
<string>Triweight</string>
</property>
</item>
<item>
<property name="text">
<string>Epanechnikov</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="kernelShapeLabel">
<property name="text">
<string>Kernel shape</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<layout class="QGridLayout" name="advancedGrid">
<property name="sizeConstraint">
@ -314,6 +212,92 @@
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout_2">
<item row="2" column="0">
<widget class="QCheckBox" name="mWeightFieldCheckBox">
<property name="text">
<string>Use weight from field</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QgsFieldComboBox" name="mRadiusFieldCombo">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="mRadiusFieldCheckBox">
<property name="text">
<string>Use radius from field</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="mKernelShapeCombo"/>
</item>
<item row="3" column="1" colspan="2">
<widget class="QLineEdit" name="mDecayLineEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>0.0</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="decayLabel">
<property name="text">
<string>Decay ratio</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="kernelShapeLabel">
<property name="text">
<string>Kernel shape</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="mRadiusFieldUnitCombo">
<property name="enabled">
<bool>false</bool>
</property>
<item>
<property name="text">
<string>meters</string>
</property>
</item>
<item>
<property name="text">
<string>map units</string>
</property>
</item>
</widget>
</item>
<item row="4" column="1" colspan="2">
<widget class="QComboBox" name="mOutputValuesComboBox"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Output values</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QgsFieldComboBox" name="mWeightFieldCombo">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
@ -411,22 +395,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>mWeightFieldCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>mWeightFieldCombo</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>109</x>
<y>315</y>
</hint>
<hint type="destinationlabel">
<x>408</x>
<y>318</y>
</hint>
</hints>
</connection>
<connection>
<sender>mRadiusFieldCheckBox</sender>
<signal>toggled(bool)</signal>
@ -507,5 +475,21 @@
</hint>
</hints>
</connection>
<connection>
<sender>mWeightFieldCheckBox</sender>
<signal>toggled(bool)</signal>
<receiver>mWeightFieldCombo</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>109</x>
<y>315</y>
</hint>
<hint type="destinationlabel">
<x>408</x>
<y>318</y>
</hint>
</hints>
</connection>
</connections>
</ui>