QGIS API Documentation 3.43.0-Master (e01d6d7c4c0)
qgsalgorithmexplode.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmexplode.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 "qgsalgorithmexplode.h"
19#include "qgscurve.h"
20#include "qgslinestring.h"
21#include "qgscircularstring.h"
22#include "qgscompoundcurve.h"
24
26
27QString QgsExplodeAlgorithm::name() const
28{
29 return QStringLiteral( "explodelines" );
30}
31
32QString QgsExplodeAlgorithm::displayName() const
33{
34 return QObject::tr( "Explode lines" );
35}
36
37QStringList QgsExplodeAlgorithm::tags() const
38{
39 return QObject::tr( "segments,parts" ).split( ',' );
40}
41
42QString QgsExplodeAlgorithm::group() const
43{
44 return QObject::tr( "Vector geometry" );
45}
46
47QString QgsExplodeAlgorithm::groupId() const
48{
49 return QStringLiteral( "vectorgeometry" );
50}
51
52QString QgsExplodeAlgorithm::shortHelpString() const
53{
54 return QObject::tr( "This algorithm takes a lines layer and creates a new one in which each line is replaced by a set of "
55 "lines representing the segments in the original line. Each line in the resulting layer contains only a "
56 "start and an end point, with no intermediate nodes between them.\n\n"
57 "If the input layer consists of CircularStrings or CompoundCurves, the output layer will be of the "
58 "same type and contain only single curve segments." );
59}
60
61QString QgsExplodeAlgorithm::shortDescription() const
62{
63 return QObject::tr( "Creates a line layer in which each feature represents a segment from an input line layer." );
64}
65
66Qgis::ProcessingAlgorithmDocumentationFlags QgsExplodeAlgorithm::documentationFlags() const
67{
69}
70
71QList<int> QgsExplodeAlgorithm::inputLayerTypes() const
72{
73 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorLine );
74}
75
76Qgis::ProcessingSourceType QgsExplodeAlgorithm::outputLayerType() const
77{
79}
80
81QgsExplodeAlgorithm *QgsExplodeAlgorithm::createInstance() const
82{
83 return new QgsExplodeAlgorithm();
84}
85
86QString QgsExplodeAlgorithm::outputName() const
87{
88 return QObject::tr( "Exploded" );
89}
90
91Qgis::WkbType QgsExplodeAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
92{
93 return QgsWkbTypes::singleType( inputWkbType );
94}
95
96QgsFeatureList QgsExplodeAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback * )
97{
98 if ( !f.hasGeometry() )
99 {
100 return QgsFeatureList() << f;
101 }
102 else
103 {
104 const std::vector<QgsGeometry> parts = extractAsParts( f.geometry() );
105 QgsFeature outputFeature;
106 QgsFeatureList features;
107 features.reserve( parts.size() );
108 for ( const QgsGeometry &part : parts )
109 {
110 outputFeature.setAttributes( f.attributes() );
111 outputFeature.setGeometry( part );
112 features << outputFeature;
113 }
114 return features;
115 }
116}
117
118Qgis::ProcessingFeatureSourceFlags QgsExplodeAlgorithm::sourceFlags() const
119{
121}
122
123QgsFeatureSink::SinkFlags QgsExplodeAlgorithm::sinkFlags() const
124{
126}
127
128std::vector<QgsGeometry> QgsExplodeAlgorithm::extractAsParts( const QgsGeometry &geometry ) const
129{
130 if ( geometry.isMultipart() )
131 {
132 std::vector<QgsGeometry> parts;
133 const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geometry.constGet() );
134 for ( int part = 0; part < collection->numGeometries(); ++part )
135 {
136 std::vector<QgsGeometry> segments = curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( collection->geometryN( part ) ) );
137 parts.reserve( parts.size() + segments.size() );
138 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
139 }
140 return parts;
141 }
142 else
143 {
144 return curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( geometry.constGet() ) );
145 }
146}
147
148std::vector<QgsGeometry> QgsExplodeAlgorithm::curveAsSingleSegments( const QgsCurve *curve, bool useCompoundCurves ) const
149{
150 std::vector<QgsGeometry> parts;
151 if ( !curve )
152 return parts;
153 switch ( QgsWkbTypes::flatType( curve->wkbType() ) )
154 {
156 {
157 const QgsLineString *line = qgsgeometry_cast<const QgsLineString *>( curve );
158 for ( int i = 0; i < line->numPoints() - 1; ++i )
159 {
160 const QgsPoint ptA = line->pointN( i );
161 const QgsPoint ptB = line->pointN( i + 1 );
162 auto ls = std::make_unique<QgsLineString>( QVector<QgsPoint>() << ptA << ptB );
163 if ( !useCompoundCurves )
164 {
165 parts.emplace_back( QgsGeometry( std::move( ls ) ) );
166 }
167 else
168 {
169 auto cc = std::make_unique<QgsCompoundCurve>();
170 cc->addCurve( ls.release() );
171 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
172 }
173 }
174 break;
175 }
176
178 {
179 const QgsCircularString *string = qgsgeometry_cast<const QgsCircularString *>( curve );
180 for ( int i = 0; i < string->numPoints() - 2; i += 2 )
181 {
182 const QgsPoint ptA = string->pointN( i );
183 const QgsPoint ptB = string->pointN( i + 1 );
184 const QgsPoint ptC = string->pointN( i + 2 );
185 auto cs = std::make_unique<QgsCircularString>();
186 cs->setPoints( QgsPointSequence() << ptA << ptB << ptC );
187 if ( !useCompoundCurves )
188 {
189 parts.emplace_back( QgsGeometry( std::move( cs ) ) );
190 }
191 else
192 {
193 auto cc = std::make_unique<QgsCompoundCurve>();
194 cc->addCurve( cs.release() );
195 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
196 }
197 }
198 break;
199 }
200
202 {
203 const QgsCompoundCurve *compoundCurve = qgsgeometry_cast<const QgsCompoundCurve *>( curve );
204 for ( int i = 0; i < compoundCurve->nCurves(); ++i )
205 {
206 std::vector<QgsGeometry> segments = curveAsSingleSegments( compoundCurve->curveAt( i ), true );
207 parts.reserve( parts.size() + segments.size() );
208 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
209 }
210 break;
211 }
212
213 default:
214 break;
215 }
216 return parts;
217}
218
ProcessingSourceType
Processing data source types.
Definition qgis.h:3399
@ VectorLine
Vector line layers.
@ RegeneratesPrimaryKey
Algorithm always drops any existing primary keys or FID values and regenerates them in outputs.
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
Definition qgis.h:3496
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:256
@ CompoundCurve
CompoundCurve.
@ LineString
LineString.
@ CircularString
CircularString.
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3588
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
Circular string geometry type.
Compound curve geometry type.
int nCurves() const
Returns the number of curves in the geometry.
const QgsCurve * curveAt(int i) const
Returns the curve at the specified index.
Abstract base class for curved geometry type.
Definition qgscurve.h:35
QFlags< SinkFlag > SinkFlags
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition qgsfeature.h:58
QgsAttributes attributes
Definition qgsfeature.h:67
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
QgsGeometry geometry
Definition qgsfeature.h:69
bool hasGeometry() const
Returns true if the feature has an associated geometry.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
int numGeometries() const
Returns the number of geometries within the collection.
const QgsAbstractGeometry * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
A geometry is the spatial representation of a feature.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
Line string geometry type, with support for z-dimension and m-values.
int numPoints() const override
Returns the number of points in the curve.
QgsPoint pointN(int i) const
Returns the specified point from inside the line string.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
Contains information about the context in which a processing algorithm is executed.
Base class for providing feedback from a processing algorithm.
static Qgis::WkbType singleType(Qgis::WkbType type)
Returns the single type for a WKB type.
Definition qgswkbtypes.h:53
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
QVector< QgsPoint > QgsPointSequence
QList< QgsFeature > QgsFeatureList