Skip to content

Commit

Permalink
[processing][FEATURE] multiring buffer algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbruy committed Mar 2, 2018
1 parent b61882f commit 04ce435
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/analysis/CMakeLists.txt
Expand Up @@ -47,6 +47,7 @@ SET(QGIS_ANALYSIS_SRCS
processing/qgsalgorithmmergevector.cpp
processing/qgsalgorithmminimumenclosingcircle.cpp
processing/qgsalgorithmmultiparttosinglepart.cpp
processing/qgsalgorithmmultiringbuffer.cpp
processing/qgsalgorithmorderbyexpression.cpp
processing/qgsalgorithmorientedminimumboundingbox.cpp
processing/qgsalgorithmpackage.cpp
Expand Down
129 changes: 129 additions & 0 deletions src/analysis/processing/qgsalgorithmmultiringbuffer.cpp
@@ -0,0 +1,129 @@
/***************************************************************************
qgsalgorithmnultitingbuffer.cpp
--------------------------
begin : February 2018
copyright : (C) 2018 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsalgorithmmultiringbuffer.h"

///@cond PRIVATE

QString QgsMultiRingBufferAlgorithm::name() const
{
return QStringLiteral( "multiringbuffer" );
}

QString QgsMultiRingBufferAlgorithm::displayName() const
{
return QObject::tr( "Multi-ring buffer" );
}

QStringList QgsMultiRingBufferAlgorithm::tags() const
{
return QObject::tr( "buffer,grow,multiple,rings,distance,donut" ).split( ',' );
}

QString QgsMultiRingBufferAlgorithm::group() const
{
return QObject::tr( "Vector geometry" );
}

QString QgsMultiRingBufferAlgorithm::groupId() const
{
return QStringLiteral( "vectorgeometry" );
}

QString QgsMultiRingBufferAlgorithm::outputName() const
{
return QObject::tr( "Multi-ring buffer" );
}

QString QgsMultiRingBufferAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm computes multi-ring ('donuts') buffer for all the features in an input layer, using a fixed or dynamic distance and rings number." );
}

QgsMultiRingBufferAlgorithm *QgsMultiRingBufferAlgorithm::createInstance() const
{
return new QgsMultiRingBufferAlgorithm();
}

void QgsMultiRingBufferAlgorithm::initParameters( const QVariantMap & )
{
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ), QList< int >() << QgsProcessing::TypeVectorPoint ) );

auto ringsParam = qgis::make_unique < QgsProcessingParameterNumber >( QStringLiteral( "RINGS" ), QObject::tr( "Number of rings" ), QgsProcessingParameterNumber::Integer, 1, false, 1 );
//ringsParam->setIsDynamic( true );
//ringsParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Number of rings" ), QObject::tr( "Number of rings" ), QgsPropertyDefinition::Integer ) );
//ringsParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
addParameter( ringsParam.release() );

auto distanceParam = qgis::make_unique < QgsProcessingParameterNumber >( QStringLiteral( "DISTANCE" ), QObject::tr( "Distance between rings" ), QgsProcessingParameterNumber::Double, 1 );
//distanceParam->setIsDynamic( true );
//distanceParam->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Distance between rings" ), QObject::tr( "Distance between rings" ), QgsPropertyDefinition::Double ) );
//distanceParam->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
addParameter( distanceParam.release() );
}

bool QgsMultiRingBufferAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
{
mRingsNumber = parameterAsInt( parameters, QStringLiteral( "RINGS" ), context );
mDistance = parameterAsDouble( parameters, QStringLiteral( "DISTANCE" ), context );
return true;
}

QgsFields QgsMultiRingBufferAlgorithm::outputFields( const QgsFields &inputFields ) const
{
QgsFields fields = inputFields;
fields.append( QgsField( QStringLiteral( "ringId" ), QVariant::Int, QString(), 10, 0 ) );
fields.append( QgsField( QStringLiteral( "distance" ), QVariant::Double, QString(), 20, 6 ) );
return fields;
}

QgsFeatureList QgsMultiRingBufferAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback *feedback )
{
double currentDistance = 0;
QgsGeometry outputGeometry, previousGeometry;

QgsFeatureList outputs;

for ( int i = 1; i <= mRingsNumber; ++i )
{
QgsFeature out;
currentDistance = i * mDistance;
outputGeometry = feature.geometry().buffer( currentDistance, 40 );
if ( !outputGeometry )
{
feedback->reportError( QObject::tr( "Error calculating buffer for feature %1" ).arg( feature.id() ) );
continue;
}

if ( i == 1 )
{
out.setGeometry( outputGeometry );
}
else
{
out.setGeometry( outputGeometry.symDifference( previousGeometry ) );
}
previousGeometry = outputGeometry;
QgsAttributes attrs = feature.attributes();
attrs << i << currentDistance;
out.setAttributes( attrs );
outputs.append( out );
}
return outputs;
}

///@endcond
64 changes: 64 additions & 0 deletions src/analysis/processing/qgsalgorithmmultiringbuffer.h
@@ -0,0 +1,64 @@
/***************************************************************************
qgsalgorithmmultiringbuffer.h
-------------------------
begin : February 2018
copyright : (C) 2018 by Alexander Bruy
email : alexander dot bruy at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSALGORITHMMULTIRINGBUFFER_H
#define QGSALGORITHMMULTIRINGBUFFER_H

#define SIP_NO_FILE

#include "qgis.h"
#include "qgsprocessingalgorithm.h"

///@cond PRIVATE

/**
* Native multiring buffer algorithm.
*/
class QgsMultiRingBufferAlgorithm : public QgsProcessingFeatureBasedAlgorithm
{

public:

QgsMultiRingBufferAlgorithm() = default;
QString name() const override;
QString displayName() const override;
QStringList tags() const override;
QString group() const override;
QString groupId() const override;
QString shortHelpString() const override;
QgsMultiRingBufferAlgorithm *createInstance() const override SIP_FACTORY;
void initParameters( const QVariantMap &configuration = QVariantMap() ) override;

protected:

QString outputName() const override;
QgsFields outputFields( const QgsFields &inputFields ) const override;
QgsProcessing::SourceType outputLayerType() const override { return QgsProcessing::TypeVectorPolygon; }
QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const override { Q_UNUSED( inputWkbType ); return QgsWkbTypes::Polygon; }
bool prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;

private:
int mRingsNumber = 0;
double mDistance = 0.0;
};

///@endcond PRIVATE

#endif // QGSALGORITHMMULTIRINGBUFFER_H


2 changes: 2 additions & 0 deletions src/analysis/processing/qgsnativealgorithms.cpp
Expand Up @@ -44,6 +44,7 @@
#include "qgsalgorithmmergevector.h"
#include "qgsalgorithmminimumenclosingcircle.h"
#include "qgsalgorithmmultiparttosinglepart.h"
#include "qgsalgorithmmultiringbuffer.h"
#include "qgsalgorithmorderbyexpression.h"
#include "qgsalgorithmorientedminimumboundingbox.h"
#include "qgsalgorithmpackage.h"
Expand Down Expand Up @@ -134,6 +135,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
addAlgorithm( new QgsMergeVectorAlgorithm() );
addAlgorithm( new QgsMinimumEnclosingCircleAlgorithm() );
addAlgorithm( new QgsMultipartToSinglepartAlgorithm() );
addAlgorithm( new QgsMultiRingBufferAlgorithm() );
addAlgorithm( new QgsOrderByExpressionAlgorithm() );
addAlgorithm( new QgsOrientedMinimumBoundingBoxAlgorithm() );
addAlgorithm( new QgsPackageAlgorithm() );
Expand Down

0 comments on commit 04ce435

Please sign in to comment.