Skip to content

Commit b884eb4

Browse files
committedApr 23, 2018
[FEATURE][processing] Native wedge buffer algorithm
This algorithm creates wedge shaped buffers from input points. The azimuth parameter gives the angle (in degrees) for the middle of the wedge to point. The buffer width (in degrees) is specified by the width parameter. Note that the wedge will extend to half of the angular width either side of the azimuth direction. The outer radius of the buffer is specified via outer radius, and optionally an inner radius can also be specified. Supports dynamic parameters for azimuth, width, and radius. The native output from this algorithm is CurvePolygon geometries, but these may be automatically segmentized to Polygons depending on the output format.
1 parent e047738 commit b884eb4

File tree

4 files changed

+274
-0
lines changed

4 files changed

+274
-0
lines changed
 

‎src/analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ SET(QGIS_ANALYSIS_SRCS
7777
processing/qgsalgorithmtransform.cpp
7878
processing/qgsalgorithmtranslate.cpp
7979
processing/qgsalgorithmuniquevalueindex.cpp
80+
processing/qgsalgorithmwedgebuffers.cpp
8081

8182
processing/qgsnativealgorithms.cpp
8283

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
/***************************************************************************
2+
qgsalgorithmwedgebuffers.cpp
3+
---------------------
4+
begin : April 2018
5+
copyright : (C) 2018 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#include "qgsalgorithmwedgebuffers.h"
19+
#include "qgsmultipoint.h"
20+
#include "qgsmultisurface.h"
21+
22+
///@cond PRIVATE
23+
24+
QString QgsWedgeBuffersAlgorithm::name() const
25+
{
26+
return QStringLiteral( "wedgebuffers" );
27+
}
28+
29+
QString QgsWedgeBuffersAlgorithm::displayName() const
30+
{
31+
return QObject::tr( "Create wedge buffers" );
32+
}
33+
34+
QStringList QgsWedgeBuffersAlgorithm::tags() const
35+
{
36+
return QObject::tr( "arc,segment,circular,circle,slice" ).split( ',' );
37+
}
38+
39+
QString QgsWedgeBuffersAlgorithm::group() const
40+
{
41+
return QObject::tr( "Vector geometry" );
42+
}
43+
44+
QString QgsWedgeBuffersAlgorithm::groupId() const
45+
{
46+
return QStringLiteral( "vectorgeometry" );
47+
}
48+
49+
QString QgsWedgeBuffersAlgorithm::outputName() const
50+
{
51+
return QObject::tr( "Buffers" );
52+
}
53+
54+
QgsWkbTypes::Type QgsWedgeBuffersAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
55+
{
56+
QgsWkbTypes::Type out = QgsWkbTypes::CurvePolygon;
57+
if ( QgsWkbTypes::hasZ( inputWkbType ) )
58+
out = QgsWkbTypes::addZ( out );
59+
if ( QgsWkbTypes::hasM( inputWkbType ) )
60+
out = QgsWkbTypes::addM( out );
61+
if ( QgsWkbTypes::isMultiType( inputWkbType ) )
62+
out = QgsWkbTypes::multiType( out );
63+
return out;
64+
}
65+
66+
QString QgsWedgeBuffersAlgorithm::shortHelpString() const
67+
{
68+
return QObject::tr( "This algorithm creates wedge shaped buffers from input points.\n\n"
69+
"The azimuth parameter gives the angle (in degrees) for the middle of the wedge to point. "
70+
"The buffer width (in degrees) is specified by the width parameter. Note that the "
71+
"wedge will extend to half of the angular width either side of the azimuth direction.\n\n"
72+
"The outer radius of the buffer is specified via outer radius, and optionally an "
73+
"inner radius can also be specified.\n\n"
74+
"The native output from this algorithm are CurvePolygon geometries, but these may "
75+
"be automatically segmentized to Polygons depending on the output format." );
76+
}
77+
78+
QList<int> QgsWedgeBuffersAlgorithm::inputLayerTypes() const
79+
{
80+
return QList<int>() << QgsProcessing::TypeVectorPoint;
81+
}
82+
83+
QgsProcessing::SourceType QgsWedgeBuffersAlgorithm::outputLayerType() const
84+
{
85+
return QgsProcessing::TypeVectorPolygon;
86+
}
87+
88+
QgsWedgeBuffersAlgorithm *QgsWedgeBuffersAlgorithm::createInstance() const
89+
{
90+
return new QgsWedgeBuffersAlgorithm();
91+
}
92+
93+
void QgsWedgeBuffersAlgorithm::initParameters( const QVariantMap & )
94+
{
95+
std::unique_ptr< QgsProcessingParameterNumber > azimuth = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "AZIMUTH" ), QObject::tr( "Azimuth (degrees from North)" ), QgsProcessingParameterNumber::Double, 0, false );
96+
azimuth->setIsDynamic( true );
97+
azimuth->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Azimuth" ), QObject::tr( "Azimuth (degrees from North)" ), QgsPropertyDefinition::Double ) );
98+
azimuth->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
99+
addParameter( azimuth.release() );
100+
101+
std::unique_ptr< QgsProcessingParameterNumber > width = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "WIDTH" ), QObject::tr( "Wedge width (in degrees)" ), QgsProcessingParameterNumber::Double, 45, false, 0, 360.0 );
102+
width->setIsDynamic( true );
103+
width->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Width" ), QObject::tr( "Wedge width (in degrees)" ), QgsPropertyDefinition::DoublePositive ) );
104+
width->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
105+
addParameter( width.release() );
106+
107+
std::unique_ptr< QgsProcessingParameterNumber > outerRadius = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "OUTER_RADIUS" ), QObject::tr( "Outer radius" ), QgsProcessingParameterNumber::Double, 1, false, 0 );
108+
outerRadius->setIsDynamic( true );
109+
outerRadius->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Outer radius" ), QObject::tr( "Outer radius" ), QgsPropertyDefinition::DoublePositive ) );
110+
outerRadius->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
111+
addParameter( outerRadius.release() );
112+
113+
std::unique_ptr< QgsProcessingParameterNumber > innerRadius = qgis::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "INNER_RADIUS" ), QObject::tr( "Inner radius" ), QgsProcessingParameterNumber::Double, 0, true, 0 );
114+
innerRadius->setIsDynamic( true );
115+
innerRadius->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Inner radius" ), QObject::tr( "Inner radius" ), QgsPropertyDefinition::DoublePositive ) );
116+
innerRadius->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
117+
addParameter( innerRadius.release() );
118+
}
119+
120+
QgsProcessingFeatureSource::Flag QgsWedgeBuffersAlgorithm::sourceFlags() const
121+
{
122+
return QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks;
123+
}
124+
125+
bool QgsWedgeBuffersAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
126+
{
127+
mAzimuth = parameterAsDouble( parameters, QStringLiteral( "AZIMUTH" ), context );
128+
mDynamicAzimuth = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "AZIMUTH" ) );
129+
if ( mDynamicAzimuth )
130+
mAzimuthProperty = parameters.value( QStringLiteral( "AZIMUTH" ) ).value< QgsProperty >();
131+
132+
mWidth = parameterAsDouble( parameters, QStringLiteral( "WIDTH" ), context );
133+
mDynamicWidth = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "WIDTH" ) );
134+
if ( mDynamicWidth )
135+
mWidthProperty = parameters.value( QStringLiteral( "WIDTH" ) ).value< QgsProperty >();
136+
137+
mOuterRadius = parameterAsDouble( parameters, QStringLiteral( "OUTER_RADIUS" ), context );
138+
mDynamicOuterRadius = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "OUTER_RADIUS" ) );
139+
if ( mDynamicOuterRadius )
140+
mOuterRadiusProperty = parameters.value( QStringLiteral( "OUTER_RADIUS" ) ).value< QgsProperty >();
141+
142+
mInnerRadius = parameterAsDouble( parameters, QStringLiteral( "INNER_RADIUS" ), context );
143+
mDynamicInnerRadius = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "INNER_RADIUS" ) );
144+
if ( mDynamicInnerRadius )
145+
mInnerRadiusProperty = parameters.value( QStringLiteral( "INNER_RADIUS" ) ).value< QgsProperty >();
146+
147+
return true;
148+
}
149+
150+
QgsFeatureList QgsWedgeBuffersAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
151+
{
152+
QgsFeature f = feature;
153+
if ( f.hasGeometry() && QgsWkbTypes::geometryType( f.geometry().wkbType() ) == QgsWkbTypes::PointGeometry )
154+
{
155+
double azimuth = mAzimuth;
156+
if ( mDynamicAzimuth )
157+
azimuth = mAzimuthProperty.valueAsDouble( context.expressionContext(), azimuth );
158+
159+
double width = mWidth;
160+
if ( mDynamicWidth )
161+
width = mWidthProperty.valueAsDouble( context.expressionContext(), width );
162+
163+
double outerRadius = mOuterRadius;
164+
if ( mDynamicOuterRadius )
165+
outerRadius = mOuterRadiusProperty.valueAsDouble( context.expressionContext(), outerRadius );
166+
167+
double innerRadius = mInnerRadius;
168+
if ( mDynamicInnerRadius )
169+
innerRadius = mInnerRadiusProperty.valueAsDouble( context.expressionContext(), innerRadius );
170+
171+
QgsGeometry g = f.geometry();
172+
if ( QgsWkbTypes::isMultiType( g.wkbType() ) )
173+
{
174+
const QgsMultiPoint *mp = static_cast< const QgsMultiPoint * >( g.constGet() );
175+
std::unique_ptr< QgsMultiSurface > result = qgis::make_unique< QgsMultiSurface >();
176+
for ( int i = 0; i < mp->numGeometries(); ++i )
177+
{
178+
const QgsPoint *p = static_cast< const QgsPoint * >( mp->geometryN( i ) );
179+
result->addGeometry( QgsGeometry::createWedgeBuffer( *p, azimuth, width, outerRadius, innerRadius ).constGet()->clone() );
180+
}
181+
f.setGeometry( QgsGeometry( std::move( result ) ) );
182+
}
183+
else
184+
{
185+
const QgsPoint *p = static_cast< const QgsPoint * >( g.constGet() );
186+
f.setGeometry( QgsGeometry::createWedgeBuffer( *p, azimuth, width, outerRadius, innerRadius ) );
187+
}
188+
}
189+
190+
return QgsFeatureList() << f;
191+
}
192+
193+
///@endcond
194+
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/***************************************************************************
2+
qgsalgorithmwedgebuffers.h
3+
---------------------
4+
begin : April 2018
5+
copyright : (C) 2018 by Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
18+
#ifndef QGSALGORITHMWEDGEBUFFERS_H
19+
#define QGSALGORITHMWEDGEBUFFERS_H
20+
21+
#define SIP_NO_FILE
22+
23+
#include "qgis.h"
24+
#include "qgsprocessingalgorithm.h"
25+
26+
///@cond PRIVATE
27+
28+
/**
29+
* Native create wedge buffers algorithm
30+
*/
31+
class QgsWedgeBuffersAlgorithm : public QgsProcessingFeatureBasedAlgorithm
32+
{
33+
34+
public:
35+
36+
QgsWedgeBuffersAlgorithm() = default;
37+
QString name() const override;
38+
QString displayName() const override;
39+
QStringList tags() const override;
40+
QString group() const override;
41+
QString groupId() const override;
42+
QString shortHelpString() const override;
43+
QList<int> inputLayerTypes() const override;
44+
QgsProcessing::SourceType outputLayerType() const override;
45+
QgsWedgeBuffersAlgorithm *createInstance() const override SIP_FACTORY;
46+
47+
protected:
48+
49+
void initParameters( const QVariantMap &configuration = QVariantMap() ) override;
50+
QString outputName() const override;
51+
QgsWkbTypes::Type outputWkbType( QgsWkbTypes::Type inputWkbType ) const override;
52+
QgsProcessingFeatureSource::Flag sourceFlags() const override;
53+
bool prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
54+
QgsFeatureList processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
55+
56+
private:
57+
58+
double mAzimuth = 0.0;
59+
bool mDynamicAzimuth = false;
60+
QgsProperty mAzimuthProperty;
61+
double mWidth = 45.0;
62+
bool mDynamicWidth = false;
63+
QgsProperty mWidthProperty;
64+
double mOuterRadius = 1.0;
65+
bool mDynamicOuterRadius = false;
66+
QgsProperty mOuterRadiusProperty;
67+
double mInnerRadius = 1.0;
68+
bool mDynamicInnerRadius = false;
69+
QgsProperty mInnerRadiusProperty;
70+
71+
};
72+
73+
///@endcond PRIVATE
74+
75+
#endif // QGSALGORITHMWEDGEBUFFERS_H
76+
77+

‎src/analysis/processing/qgsnativealgorithms.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
#include "qgsalgorithmtransform.h"
7575
#include "qgsalgorithmtranslate.h"
7676
#include "qgsalgorithmuniquevalueindex.h"
77+
#include "qgsalgorithmwedgebuffers.h"
7778

7879

7980
///@cond PRIVATE
@@ -175,6 +176,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
175176
addAlgorithm( new QgsTransectAlgorithm() );
176177
addAlgorithm( new QgsTransformAlgorithm() );
177178
addAlgorithm( new QgsTranslateAlgorithm() );
179+
addAlgorithm( new QgsWedgeBuffersAlgorithm() );
178180
}
179181

180182

0 commit comments

Comments
 (0)
Please sign in to comment.