QGIS API Documentation 3.32.0-Lima (311a8cb8a6)
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
61QList<int> QgsExplodeAlgorithm::inputLayerTypes() const
62{
63 return QList<int>() << QgsProcessing::TypeVectorLine;
64}
65
66QgsProcessing::SourceType QgsExplodeAlgorithm::outputLayerType() const
67{
69}
70
71QgsExplodeAlgorithm *QgsExplodeAlgorithm::createInstance() const
72{
73 return new QgsExplodeAlgorithm();
74}
75
76QString QgsExplodeAlgorithm::outputName() const
77{
78 return QObject::tr( "Exploded" );
79}
80
81Qgis::WkbType QgsExplodeAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
82{
83 return QgsWkbTypes::singleType( inputWkbType );
84}
85
86QgsFeatureList QgsExplodeAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback * )
87{
88 if ( !f.hasGeometry() )
89 {
90 return QgsFeatureList() << f;
91 }
92 else
93 {
94 const std::vector<QgsGeometry> parts = extractAsParts( f.geometry() );
95 QgsFeature outputFeature;
96 QgsFeatureList features;
97 features.reserve( parts.size() );
98 for ( const QgsGeometry &part : parts )
99 {
100 outputFeature.setAttributes( f.attributes() );
101 outputFeature.setGeometry( part );
102 features << outputFeature;
103 }
104 return features;
105 }
106}
107
108QgsFeatureSink::SinkFlags QgsExplodeAlgorithm::sinkFlags() const
109{
111}
112
113std::vector<QgsGeometry> QgsExplodeAlgorithm::extractAsParts( const QgsGeometry &geometry ) const
114{
115 if ( geometry.isMultipart() )
116 {
117 std::vector<QgsGeometry> parts;
118 const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( geometry.constGet() );
119 for ( int part = 0; part < collection->numGeometries(); ++part )
120 {
121 std::vector<QgsGeometry> segments = curveAsSingleSegments( qgsgeometry_cast< const QgsCurve * >( collection->geometryN( part ) ) );
122 parts.reserve( parts.size() + segments.size() );
123 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
124 }
125 return parts;
126 }
127 else
128 {
129 return curveAsSingleSegments( qgsgeometry_cast< const QgsCurve * >( geometry.constGet() ) );
130 }
131}
132
133std::vector<QgsGeometry> QgsExplodeAlgorithm::curveAsSingleSegments( const QgsCurve *curve, bool useCompoundCurves ) const
134{
135 std::vector<QgsGeometry> parts;
136 if ( !curve )
137 return parts;
138 switch ( QgsWkbTypes::flatType( curve->wkbType() ) )
139 {
141 {
142 const QgsLineString *line = qgsgeometry_cast< const QgsLineString * >( curve );
143 for ( int i = 0; i < line->numPoints() - 1; ++i )
144 {
145 const QgsPoint ptA = line->pointN( i );
146 const QgsPoint ptB = line->pointN( i + 1 );
147 std::unique_ptr< QgsLineString > ls = std::make_unique< QgsLineString >( QVector< QgsPoint >() << ptA << ptB );
148 if ( !useCompoundCurves )
149 {
150 parts.emplace_back( QgsGeometry( std::move( ls ) ) );
151 }
152 else
153 {
154 std::unique_ptr< QgsCompoundCurve > cc = std::make_unique< QgsCompoundCurve >();
155 cc->addCurve( ls.release() );
156 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
157 }
158 }
159 break;
160 }
161
163 {
164 const QgsCircularString *string = qgsgeometry_cast< const QgsCircularString * >( curve );
165 for ( int i = 0; i < string->numPoints() - 2; i += 2 )
166 {
167 const QgsPoint ptA = string->pointN( i );
168 const QgsPoint ptB = string->pointN( i + 1 );
169 const QgsPoint ptC = string->pointN( i + 2 );
170 std::unique_ptr< QgsCircularString > cs = std::make_unique< QgsCircularString >();
171 cs->setPoints( QgsPointSequence() << ptA << ptB << ptC );
172 if ( !useCompoundCurves )
173 {
174 parts.emplace_back( QgsGeometry( std::move( cs ) ) );
175 }
176 else
177 {
178 std::unique_ptr< QgsCompoundCurve > cc = std::make_unique< QgsCompoundCurve >();
179 cc->addCurve( cs.release() );
180 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
181 }
182 }
183 break;
184 }
185
187 {
188 const QgsCompoundCurve *compoundCurve = qgsgeometry_cast< QgsCompoundCurve * >( curve );
189 for ( int i = 0; i < compoundCurve->nCurves(); ++i )
190 {
191 std::vector<QgsGeometry> segments = curveAsSingleSegments( compoundCurve->curveAt( i ), true );
192 parts.reserve( parts.size() + segments.size() );
193 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
194 }
195 break;
196 }
197
198 default:
199 break;
200
201 }
202 return parts;
203}
204
206
207
208
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:154
@ CompoundCurve
CompoundCurve.
@ LineString
LineString.
@ CircularString
CircularString.
Qgis::WkbType wkbType() const SIP_HOLDGIL
Returns the WKB type of the geometry.
Circular string geometry type.
Compound curve geometry type.
const QgsCurve * curveAt(int i) const SIP_HOLDGIL
Returns the curve at the specified index.
int nCurves() const SIP_HOLDGIL
Returns the number of curves in the geometry.
Abstract base class for curved geometry type.
Definition: qgscurve.h:36
@ 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:56
QgsAttributes attributes
Definition: qgsfeature.h:65
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:160
QgsGeometry geometry
Definition: qgsfeature.h:67
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:167
Geometry collection.
int numGeometries() const SIP_HOLDGIL
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.
Definition: qgsgeometry.h:164
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
bool isMultipart() const SIP_HOLDGIL
Returns true if WKB of the geometry is of WKBMulti* type.
Line string geometry type, with support for z-dimension and m-values.
Definition: qgslinestring.h:45
int numPoints() const override SIP_HOLDGIL
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.
SourceType
Data source types enum.
Definition: qgsprocessing.h:47
@ TypeVectorLine
Vector line layers.
Definition: qgsprocessing.h:51
static Qgis::WkbType singleType(Qgis::WkbType type) SIP_HOLDGIL
Returns the single type for a WKB type.
Definition: qgswkbtypes.h:54
static Qgis::WkbType flatType(Qgis::WkbType type) SIP_HOLDGIL
Returns the flat type for a WKB type.
Definition: qgswkbtypes.h:629
QVector< QgsPoint > QgsPointSequence
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:920