Skip to content

Commit

Permalink
heatmap updates:
Browse files Browse the repository at this point in the history
- fix warnings on windows
- minor cleanups
- some string updates
  • Loading branch information
jef-n committed Feb 8, 2012
1 parent 30e2f32 commit 3289c09
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 49 deletions.
4 changes: 2 additions & 2 deletions python/core/qgsmaplayerregistry.sip
Expand Up @@ -20,8 +20,8 @@ public:

~QgsMapLayerRegistry();

//! Retrieve a pointer to a loaded plugin by id
QgsMapLayer * mapLayer(QString theLayerId);
//! Retrieve a pointer to a loaded layer by id
QgsMapLayer *mapLayer(QString theLayerId);

//! Retrieve the mapLayers collection (mainly intended for use by projection)
QMap<QString,QgsMapLayer*> & mapLayers();
Expand Down
8 changes: 4 additions & 4 deletions resources/context_help/HeatmapGui-en_US
@@ -1,26 +1,26 @@
<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 will be the corresponding pixel(s) value in the raster.</p>
<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>

<h2>The 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 window are automatically populated in the input layer drop-down list. Click the Dropdown button and select the required 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 automatically populated in the input layer drop-down list. Click the dropdown button and select the desired layer.</p>

<h3>Output Ratser</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>

<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 makes the application crash. Kindly stick to the recommended formats until the crash issue is resolved or Use other formats if you know about its GDAL support completely.</p>
<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 Buffer Ratio is set as 0 and Radius as 10, then the centre 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>
<b>Example:</b> If Buffer Ratio is set as 0 and Radius as 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>

<h2>Further Details</h2>
<p>Contact the author through aruntheguy at gmail dot com</p>
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsmaplayerregistry.h
Expand Up @@ -46,7 +46,7 @@ class CORE_EXPORT QgsMapLayerRegistry : public QObject

~QgsMapLayerRegistry();

//! Retrieve a pointer to a loaded plugin by id
//! Retrieve a pointer to a loaded layer by id
QgsMapLayer * mapLayer( QString theLayerId );

//! Retrieve the mapLayers collection (mainly intended for use by projectio)
Expand Down
25 changes: 13 additions & 12 deletions src/plugins/heatmap/heatmap.cpp
Expand Up @@ -74,7 +74,7 @@ void Heatmap::initGui()
// Create the action for tool
mQActionPointer = new QAction( QIcon( ":/heatmap/heatmap.png" ), tr( "Heatmap" ), this );
// Set the what's this text
mQActionPointer->setWhatsThis( tr( "Creats a heatmap raster for the input point vector." ) );
mQActionPointer->setWhatsThis( tr( "Creates a heatmap raster for the input point vector." ) );
// Connect the action to the run
connect( mQActionPointer, SIGNAL( triggered() ), this, SLOT( run() ) );
// Add the icon to the toolbar
Expand Down Expand Up @@ -130,7 +130,7 @@ void Heatmap::createRaster( QgsVectorLayer* theVectorLayer, int theBuffer, float
myDriver = GetGDALDriverManager()->GetDriverByName( theOutputFormat.toUtf8() );
if ( myDriver == NULL )
{
QMessageBox::information( 0, tr( "Error in GDAL Driver!" ), tr( "Cannot open the driver for the format specified" ) );
QMessageBox::information( 0, tr( "GDAL driver error" ), tr( "Cannot open the driver for the specified format" ) );
return;
}

Expand Down Expand Up @@ -159,9 +159,10 @@ void Heatmap::createRaster( QgsVectorLayer* theVectorLayer, int theBuffer, float
poBand->SetNoDataValue( NO_DATA );

float* line = ( float * ) CPLMalloc( sizeof( float ) * xSize );
std::fill_n( line, xSize, NO_DATA );
for ( int i = 0; i < xSize; i++ )
line[i] = NO_DATA;
// Write the empty raster
for ( int i = 0; i < ySize ; i += 1 )
for ( int i = 0; i < ySize ; i++ )
{
poBand->RasterIO( GF_Write, 0, 0, xSize, 1, line, xSize, 1, GDT_Float32, 0, 0 );
}
Expand All @@ -175,7 +176,7 @@ void Heatmap::createRaster( QgsVectorLayer* theVectorLayer, int theBuffer, float
heatmapDS = ( GDALDataset * ) GDALOpen( theOutputFilename.toUtf8(), GA_Update );
if ( !heatmapDS )
{
QMessageBox::information( 0, tr( "Error in Updating Raster!" ), tr( "Couldnot open the created raster for updation. The Heatmap was not generated." ) );
QMessageBox::information( 0, tr( "Raster update error" ), tr( "Could not open the created raster for updating. The heatmap was not generated." ) );
return;
}
poBand = heatmapDS->GetRasterBand( 1 );
Expand All @@ -185,7 +186,7 @@ void Heatmap::createRaster( QgsVectorLayer* theVectorLayer, int theBuffer, float
QgsVectorDataProvider* myVectorProvider = theVectorLayer->dataProvider();
if ( !myVectorProvider )
{
QMessageBox::information( 0, tr( "Error in Point Layer!" ), tr( "Couldnot identify the vector data provider." ) );
QMessageBox::information( 0, tr( "Point layer error" ), tr( "Could not identify the vector data provider." ) );
return;
}
QgsAttributeList dummyList;
Expand All @@ -201,11 +202,11 @@ void Heatmap::createRaster( QgsVectorLayer* theVectorLayer, int theBuffer, float

while ( myVectorProvider->nextFeature( myFeature ) )
{
counter += 1;
counter++;
p.setValue( counter );
if ( p.wasCanceled() )
{
QMessageBox::information( 0, tr( "Heatmap Generation Aborted!" ), tr( "QGIS will now load the partially-computed raster." ) );
QMessageBox::information( 0, tr( "Heatmap generation aborted" ), tr( "QGIS will now load the partially-computed raster." ) );
break;
}

Expand All @@ -228,11 +229,11 @@ void Heatmap::createRaster( QgsVectorLayer* theVectorLayer, int theBuffer, float
float *dataBuffer = ( float * ) CPLMalloc( sizeof( float ) * blockSize * blockSize );
poBand->RasterIO( GF_Read, xPosition, yPosition, blockSize, blockSize, dataBuffer, blockSize, blockSize, GDT_Float32, 0, 0 );

for ( int xp = 0; xp <= theBuffer; xp += 1 )
for ( int xp = 0; xp <= theBuffer; xp++ )
{
for ( int yp = 0; yp <= theBuffer; yp += 1 )
for ( int yp = 0; yp <= theBuffer; yp++ )
{
float distance = sqrt( pow( xp, 2 ) + pow( yp, 2 ) );
float distance = sqrt( pow( xp, 2.0 ) + pow( yp, 2.0 ) );
float pixelValue = 1 - (( 1 - theDecay ) * distance / theBuffer );

// clearing anamolies along the axes
Expand All @@ -252,7 +253,7 @@ void Heatmap::createRaster( QgsVectorLayer* theVectorLayer, int theBuffer, float
pos[1] = ( theBuffer + xp ) * blockSize + ( theBuffer - yp );
pos[2] = ( theBuffer - xp ) * blockSize + ( theBuffer + yp );
pos[3] = ( theBuffer - xp ) * blockSize + ( theBuffer - yp );
for ( int p = 0; p < 4; p += 1 )
for ( int p = 0; p < 4; p++ )
{
if ( dataBuffer[ pos[p] ] == NO_DATA )
{
Expand Down
46 changes: 16 additions & 30 deletions src/plugins/heatmap/heatmapgui.cpp
Expand Up @@ -36,17 +36,13 @@ HeatmapGui::HeatmapGui( QWidget* parent, Qt::WFlags fl )
setupUi( this );

// Adding point layers to the mInputVectorCombo
QMap<QString, QgsMapLayer*> mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
QMapIterator<QString, QgsMapLayer*> layers( mapLayers );

while ( layers.hasNext() )
foreach( QgsMapLayer *l, QgsMapLayerRegistry::instance()->mapLayers() )
{
layers.next();
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( layers.value() );
if (( vl ) && ( vl->geometryType() == QGis::Point ) )
{
mInputVectorCombo->addItem( vl->name(), QVariant( vl->id() ) );
}
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( l );
if ( !vl || vl->geometryType() != QGis::Point )
continue;

mInputVectorCombo->addItem( vl->name(), vl->id() );
}

// Adding GDAL drivers with CREATE to the mFormatCombo
Expand Down Expand Up @@ -85,7 +81,6 @@ HeatmapGui::~HeatmapGui()
void HeatmapGui::on_mButtonBox_accepted()
{
// Variables to be emitted with the createRaster signal
QgsVectorLayer* inputLayer;
int bufferDistance;
float decayRatio;
QString outputFileName;
Expand All @@ -94,31 +89,21 @@ void HeatmapGui::on_mButtonBox_accepted()
QString dummyText;

// The input vector layer
int myLayerId = mInputVectorCombo->itemData( mInputVectorCombo->currentIndex() ).toInt();

QMap<QString, QgsMapLayer*> mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
QMapIterator<QString, QgsMapLayer*> layers( mapLayers );
QString myLayerId = mInputVectorCombo->itemData( mInputVectorCombo->currentIndex() ).toString();

while ( layers.hasNext() )
QgsVectorLayer* inputLayer = qobject_cast<QgsVectorLayer *>( QgsMapLayerRegistry::instance()->mapLayer( myLayerId ) );
if ( !inputLayer )
{
layers.next();
QgsVectorLayer* vl = qobject_cast<QgsVectorLayer *>( layers.value() );
if ( vl )
{
dummyText = vl->id();
if ( dummyText.toInt() == myLayerId )
{
inputLayer = vl;
}
}
QMessageBox::information( 0, tr( "Layer not found" ), tr( "Layer %1 not found." ).arg( myLayerId ) );
return;
}

// The buffer distance
dummyText = mBufferLineEdit->text();
bufferDistance = dummyText.toInt();
if ( bufferDistance == NULL )
if ( bufferDistance == 0 )
{
QMessageBox::information( 0, tr( "Invalid Buffer Value!" ), tr( "Buffer distance cannot be NULL, kindly enter a valid value." ) );
QMessageBox::information( 0, tr( "Invalid buffer value" ), tr( "Buffer distance cannot be zero. Please enter a valid value." ) );
return;
}
// The decay ratio
Expand All @@ -130,7 +115,7 @@ void HeatmapGui::on_mButtonBox_accepted()
QFileInfo myFileInfo( outputFileName );
if ( outputFileName.isEmpty() || !myFileInfo.dir().exists() )
{
QMessageBox::information( 0, tr( "Output filename is invalid!" ), tr( "Kindly enter a valid output file path and name." ) );
QMessageBox::information( 0, tr( "Invalid output filename" ), tr( "Please enter a valid output file path and name." ) );
return;
}

Expand All @@ -155,6 +140,7 @@ void HeatmapGui::on_mButtonBox_accepted()
}

emit createRaster( inputLayer, bufferDistance, decayRatio, outputFileName, outputFormat );

//and finally
accept();
}
Expand All @@ -174,7 +160,7 @@ void HeatmapGui::on_mBrowseButton_clicked()
QSettings s;
QString lastDir = s.value( "/Heatmap/lastOutputDir", "" ).toString();

QString outputFilename = QFileDialog::getSaveFileName( 0, tr( "Save Heatmap as: " ), lastDir );
QString outputFilename = QFileDialog::getSaveFileName( 0, tr( "Save Heatmap as:" ), lastDir );
if ( !outputFilename.isEmpty() )
{
mOutputRasterLineEdit->setText( outputFilename );
Expand Down

0 comments on commit 3289c09

Please sign in to comment.