Skip to content
Permalink
Browse files

[processing][FEATURE] multiring buffer algorithm

  • Loading branch information
alexbruy committed Mar 2, 2018
1 parent b61882f commit 04ce43569e6a0c9bb6238cbb8a7c93fe3389bed2
@@ -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
@@ -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
@@ -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


@@ -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"
@@ -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() );

0 comments on commit 04ce435

Please sign in to comment.
You can’t perform that action at this time.