Branch data Line data Source code
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 : 0 : QString QgsWedgeBuffersAlgorithm::name() const
25 : : {
26 : 0 : return QStringLiteral( "wedgebuffers" );
27 : : }
28 : :
29 : 0 : QString QgsWedgeBuffersAlgorithm::displayName() const
30 : : {
31 : 0 : return QObject::tr( "Create wedge buffers" );
32 : : }
33 : :
34 : 0 : QStringList QgsWedgeBuffersAlgorithm::tags() const
35 : : {
36 : 0 : return QObject::tr( "arc,segment,circular,circle,slice" ).split( ',' );
37 : 0 : }
38 : :
39 : 0 : QString QgsWedgeBuffersAlgorithm::group() const
40 : : {
41 : 0 : return QObject::tr( "Vector geometry" );
42 : : }
43 : :
44 : 0 : QString QgsWedgeBuffersAlgorithm::groupId() const
45 : : {
46 : 0 : return QStringLiteral( "vectorgeometry" );
47 : : }
48 : :
49 : 0 : QString QgsWedgeBuffersAlgorithm::outputName() const
50 : : {
51 : 0 : return QObject::tr( "Buffers" );
52 : : }
53 : :
54 : 0 : QgsWkbTypes::Type QgsWedgeBuffersAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
55 : : {
56 : 0 : QgsWkbTypes::Type out = QgsWkbTypes::CurvePolygon;
57 : 0 : if ( QgsWkbTypes::hasZ( inputWkbType ) )
58 : 0 : out = QgsWkbTypes::addZ( out );
59 : 0 : if ( QgsWkbTypes::hasM( inputWkbType ) )
60 : 0 : out = QgsWkbTypes::addM( out );
61 : 0 : if ( QgsWkbTypes::isMultiType( inputWkbType ) )
62 : 0 : out = QgsWkbTypes::multiType( out );
63 : 0 : return out;
64 : : }
65 : :
66 : 0 : QString QgsWedgeBuffersAlgorithm::shortHelpString() const
67 : : {
68 : 0 : 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 : 0 : QList<int> QgsWedgeBuffersAlgorithm::inputLayerTypes() const
79 : : {
80 : 0 : return QList<int>() << QgsProcessing::TypeVectorPoint;
81 : 0 : }
82 : :
83 : 0 : QgsProcessing::SourceType QgsWedgeBuffersAlgorithm::outputLayerType() const
84 : : {
85 : 0 : return QgsProcessing::TypeVectorPolygon;
86 : : }
87 : :
88 : 0 : QgsWedgeBuffersAlgorithm *QgsWedgeBuffersAlgorithm::createInstance() const
89 : : {
90 : 0 : return new QgsWedgeBuffersAlgorithm();
91 : 0 : }
92 : :
93 : 0 : void QgsWedgeBuffersAlgorithm::initParameters( const QVariantMap & )
94 : : {
95 : 0 : std::unique_ptr< QgsProcessingParameterNumber > azimuth = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "AZIMUTH" ), QObject::tr( "Azimuth (degrees from North)" ), QgsProcessingParameterNumber::Double, 0, false );
96 : 0 : azimuth->setIsDynamic( true );
97 : 0 : azimuth->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Azimuth" ), QObject::tr( "Azimuth (degrees from North)" ), QgsPropertyDefinition::Double ) );
98 : 0 : azimuth->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
99 : 0 : addParameter( azimuth.release() );
100 : :
101 : 0 : std::unique_ptr< QgsProcessingParameterNumber > width = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "WIDTH" ), QObject::tr( "Wedge width (in degrees)" ), QgsProcessingParameterNumber::Double, 45, false, 0, 360.0 );
102 : 0 : width->setIsDynamic( true );
103 : 0 : width->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Width" ), QObject::tr( "Wedge width (in degrees)" ), QgsPropertyDefinition::DoublePositive ) );
104 : 0 : width->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
105 : 0 : addParameter( width.release() );
106 : :
107 : 0 : std::unique_ptr< QgsProcessingParameterNumber > outerRadius = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "OUTER_RADIUS" ), QObject::tr( "Outer radius" ), QgsProcessingParameterNumber::Double, 1, false, 0 );
108 : 0 : outerRadius->setIsDynamic( true );
109 : 0 : outerRadius->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Outer radius" ), QObject::tr( "Outer radius" ), QgsPropertyDefinition::DoublePositive ) );
110 : 0 : outerRadius->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
111 : 0 : addParameter( outerRadius.release() );
112 : :
113 : 0 : std::unique_ptr< QgsProcessingParameterNumber > innerRadius = std::make_unique< QgsProcessingParameterNumber >( QStringLiteral( "INNER_RADIUS" ), QObject::tr( "Inner radius" ), QgsProcessingParameterNumber::Double, 0, true, 0 );
114 : 0 : innerRadius->setIsDynamic( true );
115 : 0 : innerRadius->setDynamicPropertyDefinition( QgsPropertyDefinition( QStringLiteral( "Inner radius" ), QObject::tr( "Inner radius" ), QgsPropertyDefinition::DoublePositive ) );
116 : 0 : innerRadius->setDynamicLayerParameterName( QStringLiteral( "INPUT" ) );
117 : 0 : addParameter( innerRadius.release() );
118 : 0 : }
119 : :
120 : 0 : QgsProcessingFeatureSource::Flag QgsWedgeBuffersAlgorithm::sourceFlags() const
121 : : {
122 : 0 : return QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks;
123 : : }
124 : :
125 : 0 : bool QgsWedgeBuffersAlgorithm::prepareAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback * )
126 : : {
127 : 0 : mAzimuth = parameterAsDouble( parameters, QStringLiteral( "AZIMUTH" ), context );
128 : 0 : mDynamicAzimuth = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "AZIMUTH" ) );
129 : 0 : if ( mDynamicAzimuth )
130 : 0 : mAzimuthProperty = parameters.value( QStringLiteral( "AZIMUTH" ) ).value< QgsProperty >();
131 : :
132 : 0 : mWidth = parameterAsDouble( parameters, QStringLiteral( "WIDTH" ), context );
133 : 0 : mDynamicWidth = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "WIDTH" ) );
134 : 0 : if ( mDynamicWidth )
135 : 0 : mWidthProperty = parameters.value( QStringLiteral( "WIDTH" ) ).value< QgsProperty >();
136 : :
137 : 0 : mOuterRadius = parameterAsDouble( parameters, QStringLiteral( "OUTER_RADIUS" ), context );
138 : 0 : mDynamicOuterRadius = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "OUTER_RADIUS" ) );
139 : 0 : if ( mDynamicOuterRadius )
140 : 0 : mOuterRadiusProperty = parameters.value( QStringLiteral( "OUTER_RADIUS" ) ).value< QgsProperty >();
141 : :
142 : 0 : mInnerRadius = parameterAsDouble( parameters, QStringLiteral( "INNER_RADIUS" ), context );
143 : 0 : mDynamicInnerRadius = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "INNER_RADIUS" ) );
144 : 0 : if ( mDynamicInnerRadius )
145 : 0 : mInnerRadiusProperty = parameters.value( QStringLiteral( "INNER_RADIUS" ) ).value< QgsProperty >();
146 : :
147 : 0 : return true;
148 : 0 : }
149 : :
150 : 0 : QgsFeatureList QgsWedgeBuffersAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * )
151 : : {
152 : 0 : QgsFeature f = feature;
153 : 0 : if ( f.hasGeometry() && QgsWkbTypes::geometryType( f.geometry().wkbType() ) == QgsWkbTypes::PointGeometry )
154 : : {
155 : 0 : double azimuth = mAzimuth;
156 : 0 : if ( mDynamicAzimuth )
157 : 0 : azimuth = mAzimuthProperty.valueAsDouble( context.expressionContext(), azimuth );
158 : :
159 : 0 : double width = mWidth;
160 : 0 : if ( mDynamicWidth )
161 : 0 : width = mWidthProperty.valueAsDouble( context.expressionContext(), width );
162 : :
163 : 0 : double outerRadius = mOuterRadius;
164 : 0 : if ( mDynamicOuterRadius )
165 : 0 : outerRadius = mOuterRadiusProperty.valueAsDouble( context.expressionContext(), outerRadius );
166 : :
167 : 0 : double innerRadius = mInnerRadius;
168 : 0 : if ( mDynamicInnerRadius )
169 : 0 : innerRadius = mInnerRadiusProperty.valueAsDouble( context.expressionContext(), innerRadius );
170 : :
171 : 0 : QgsGeometry g = f.geometry();
172 : 0 : if ( QgsWkbTypes::isMultiType( g.wkbType() ) )
173 : : {
174 : 0 : const QgsMultiPoint *mp = static_cast< const QgsMultiPoint * >( g.constGet() );
175 : 0 : std::unique_ptr< QgsMultiSurface > result = std::make_unique< QgsMultiSurface >();
176 : 0 : result->reserve( mp->numGeometries() );
177 : 0 : for ( int i = 0; i < mp->numGeometries(); ++i )
178 : : {
179 : 0 : const QgsPoint *p = mp->pointN( i );
180 : 0 : result->addGeometry( QgsGeometry::createWedgeBuffer( *p, azimuth, width, outerRadius, innerRadius ).constGet()->clone() );
181 : 0 : }
182 : 0 : f.setGeometry( QgsGeometry( std::move( result ) ) );
183 : 0 : }
184 : : else
185 : : {
186 : 0 : const QgsPoint *p = static_cast< const QgsPoint * >( g.constGet() );
187 : 0 : f.setGeometry( QgsGeometry::createWedgeBuffer( *p, azimuth, width, outerRadius, innerRadius ) );
188 : : }
189 : 0 : }
190 : :
191 : 0 : return QgsFeatureList() << f;
192 : 0 : }
193 : :
194 : : ///@endcond
195 : :
|