QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
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
61Qgis::ProcessingAlgorithmDocumentationFlags QgsExplodeAlgorithm::documentationFlags() const
62{
64}
65
66QList<int> QgsExplodeAlgorithm::inputLayerTypes() const
67{
68 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorLine );
69}
70
71Qgis::ProcessingSourceType QgsExplodeAlgorithm::outputLayerType() const
72{
74}
75
76QgsExplodeAlgorithm *QgsExplodeAlgorithm::createInstance() const
77{
78 return new QgsExplodeAlgorithm();
79}
80
81QString QgsExplodeAlgorithm::outputName() const
82{
83 return QObject::tr( "Exploded" );
84}
85
86Qgis::WkbType QgsExplodeAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
87{
88 return QgsWkbTypes::singleType( inputWkbType );
89}
90
91QgsFeatureList QgsExplodeAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback * )
92{
93 if ( !f.hasGeometry() )
94 {
95 return QgsFeatureList() << f;
96 }
97 else
98 {
99 const std::vector<QgsGeometry> parts = extractAsParts( f.geometry() );
100 QgsFeature outputFeature;
101 QgsFeatureList features;
102 features.reserve( parts.size() );
103 for ( const QgsGeometry &part : parts )
104 {
105 outputFeature.setAttributes( f.attributes() );
106 outputFeature.setGeometry( part );
107 features << outputFeature;
108 }
109 return features;
110 }
111}
112
113Qgis::ProcessingFeatureSourceFlags QgsExplodeAlgorithm::sourceFlags() const
114{
116}
117
118QgsFeatureSink::SinkFlags QgsExplodeAlgorithm::sinkFlags() const
119{
121}
122
123std::vector<QgsGeometry> QgsExplodeAlgorithm::extractAsParts( const QgsGeometry &geometry ) const
124{
125 if ( geometry.isMultipart() )
126 {
127 std::vector<QgsGeometry> parts;
128 const QgsGeometryCollection *collection = qgsgeometry_cast<const QgsGeometryCollection *>( geometry.constGet() );
129 for ( int part = 0; part < collection->numGeometries(); ++part )
130 {
131 std::vector<QgsGeometry> segments = curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( collection->geometryN( part ) ) );
132 parts.reserve( parts.size() + segments.size() );
133 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
134 }
135 return parts;
136 }
137 else
138 {
139 return curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( geometry.constGet() ) );
140 }
141}
142
143std::vector<QgsGeometry> QgsExplodeAlgorithm::curveAsSingleSegments( const QgsCurve *curve, bool useCompoundCurves ) const
144{
145 std::vector<QgsGeometry> parts;
146 if ( !curve )
147 return parts;
148 switch ( QgsWkbTypes::flatType( curve->wkbType() ) )
149 {
151 {
152 const QgsLineString *line = qgsgeometry_cast<const QgsLineString *>( curve );
153 for ( int i = 0; i < line->numPoints() - 1; ++i )
154 {
155 const QgsPoint ptA = line->pointN( i );
156 const QgsPoint ptB = line->pointN( i + 1 );
157 std::unique_ptr<QgsLineString> ls = std::make_unique<QgsLineString>( QVector<QgsPoint>() << ptA << ptB );
158 if ( !useCompoundCurves )
159 {
160 parts.emplace_back( QgsGeometry( std::move( ls ) ) );
161 }
162 else
163 {
164 std::unique_ptr<QgsCompoundCurve> cc = std::make_unique<QgsCompoundCurve>();
165 cc->addCurve( ls.release() );
166 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
167 }
168 }
169 break;
170 }
171
173 {
174 const QgsCircularString *string = qgsgeometry_cast<const QgsCircularString *>( curve );
175 for ( int i = 0; i < string->numPoints() - 2; i += 2 )
176 {
177 const QgsPoint ptA = string->pointN( i );
178 const QgsPoint ptB = string->pointN( i + 1 );
179 const QgsPoint ptC = string->pointN( i + 2 );
180 std::unique_ptr<QgsCircularString> cs = std::make_unique<QgsCircularString>();
181 cs->setPoints( QgsPointSequence() << ptA << ptB << ptC );
182 if ( !useCompoundCurves )
183 {
184 parts.emplace_back( QgsGeometry( std::move( cs ) ) );
185 }
186 else
187 {
188 std::unique_ptr<QgsCompoundCurve> cc = std::make_unique<QgsCompoundCurve>();
189 cc->addCurve( cs.release() );
190 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
191 }
192 }
193 break;
194 }
195
197 {
198 const QgsCompoundCurve *compoundCurve = qgsgeometry_cast<QgsCompoundCurve *>( curve );
199 for ( int i = 0; i < compoundCurve->nCurves(); ++i )
200 {
201 std::vector<QgsGeometry> segments = curveAsSingleSegments( compoundCurve->curveAt( i ), true );
202 parts.reserve( parts.size() + segments.size() );
203 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
204 }
205 break;
206 }
207
208 default:
209 break;
210 }
211 return parts;
212}
213
ProcessingSourceType
Processing data source types.
Definition qgis.h:3315
@ 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:3412
@ 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:3489
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