QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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>() << static_cast< int >( Qgis::ProcessingSourceType::VectorLine );
64}
65
66Qgis::ProcessingSourceType 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
ProcessingSourceType
Processing data source types.
Definition: qgis.h:2858
@ VectorLine
Vector line layers.
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:182
@ CompoundCurve
CompoundCurve.
@ LineString
LineString.
@ CircularString
CircularString.
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: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
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:162
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.
Definition: qgslinestring.h:45
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.
Definition: qgswkbtypes.h:628
QVector< QgsPoint > QgsPointSequence
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:917