QGIS API Documentation 3.99.0-Master (2fe06baccd8)
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
20#include "qgscircularstring.h"
21#include "qgscompoundcurve.h"
22#include "qgscurve.h"
24#include "qgslinestring.h"
25
27
28QString QgsExplodeAlgorithm::name() const
29{
30 return QStringLiteral( "explodelines" );
31}
32
33QString QgsExplodeAlgorithm::displayName() const
34{
35 return QObject::tr( "Explode lines" );
36}
37
38QStringList QgsExplodeAlgorithm::tags() const
39{
40 return QObject::tr( "segments,parts" ).split( ',' );
41}
42
43QString QgsExplodeAlgorithm::group() const
44{
45 return QObject::tr( "Vector geometry" );
46}
47
48QString QgsExplodeAlgorithm::groupId() const
49{
50 return QStringLiteral( "vectorgeometry" );
51}
52
53QString QgsExplodeAlgorithm::shortHelpString() const
54{
55 return QObject::tr( "This algorithm takes a lines layer and creates a new one in which each line is replaced by a set of "
56 "lines representing the segments in the original line. Each line in the resulting layer contains only a "
57 "start and an end point, with no intermediate nodes between them.\n\n"
58 "If the input layer consists of CircularStrings or CompoundCurves, the output layer will be of the "
59 "same type and contain only single curve segments." );
60}
61
62QString QgsExplodeAlgorithm::shortDescription() const
63{
64 return QObject::tr( "Creates a line layer in which each feature represents a segment from an input line layer." );
65}
66
67Qgis::ProcessingAlgorithmDocumentationFlags QgsExplodeAlgorithm::documentationFlags() const
68{
70}
71
72QList<int> QgsExplodeAlgorithm::inputLayerTypes() const
73{
74 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorLine );
75}
76
77Qgis::ProcessingSourceType QgsExplodeAlgorithm::outputLayerType() const
78{
80}
81
82QgsExplodeAlgorithm *QgsExplodeAlgorithm::createInstance() const
83{
84 return new QgsExplodeAlgorithm();
85}
86
87QString QgsExplodeAlgorithm::outputName() const
88{
89 return QObject::tr( "Exploded" );
90}
91
92Qgis::WkbType QgsExplodeAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
93{
94 return QgsWkbTypes::singleType( inputWkbType );
95}
96
97QgsFeatureList QgsExplodeAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback * )
98{
99 if ( !f.hasGeometry() )
100 {
101 return QgsFeatureList() << f;
102 }
103 else
104 {
105 const std::vector<QgsGeometry> parts = extractAsParts( f.geometry() );
106 QgsFeature outputFeature;
107 QgsFeatureList features;
108 features.reserve( parts.size() );
109 for ( const QgsGeometry &part : parts )
110 {
111 outputFeature.setAttributes( f.attributes() );
112 outputFeature.setGeometry( part );
113 features << outputFeature;
114 }
115 return features;
116 }
117}
118
119Qgis::ProcessingFeatureSourceFlags QgsExplodeAlgorithm::sourceFlags() const
120{
122}
123
124QgsFeatureSink::SinkFlags QgsExplodeAlgorithm::sinkFlags() const
125{
127}
128
129std::vector<QgsGeometry> QgsExplodeAlgorithm::extractAsParts( const QgsGeometry &geometry ) const
130{
131 if ( geometry.isMultipart() )
132 {
133 std::vector<QgsGeometry> parts;
134 const QgsGeometryCollection *collection = qgis::down_cast< const QgsGeometryCollection * >( geometry.constGet() );
135 for ( int part = 0; part < collection->numGeometries(); ++part )
136 {
137 std::vector<QgsGeometry> segments = curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( collection->geometryN( part ) ) );
138 parts.reserve( parts.size() + segments.size() );
139 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
140 }
141 return parts;
142 }
143 else
144 {
145 return curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( geometry.constGet() ) );
146 }
147}
148
149std::vector<QgsGeometry> QgsExplodeAlgorithm::curveAsSingleSegments( const QgsCurve *curve, bool useCompoundCurves ) const
150{
151 std::vector<QgsGeometry> parts;
152 if ( !curve )
153 return parts;
154 switch ( QgsWkbTypes::flatType( curve->wkbType() ) )
155 {
157 {
159 for ( int i = 0; i < line->numPoints() - 1; ++i )
160 {
161 const QgsPoint ptA = line->pointN( i );
162 const QgsPoint ptB = line->pointN( i + 1 );
163 auto ls = std::make_unique<QgsLineString>( QVector<QgsPoint>() << ptA << ptB );
164 if ( !useCompoundCurves )
165 {
166 parts.emplace_back( QgsGeometry( std::move( ls ) ) );
167 }
168 else
169 {
170 auto cc = std::make_unique<QgsCompoundCurve>();
171 cc->addCurve( ls.release() );
172 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
173 }
174 }
175 break;
176 }
177
179 {
181 for ( int i = 0; i < string->numPoints() - 2; i += 2 )
182 {
183 const QgsPoint ptA = string->pointN( i );
184 const QgsPoint ptB = string->pointN( i + 1 );
185 const QgsPoint ptC = string->pointN( i + 2 );
186 auto cs = std::make_unique<QgsCircularString>();
187 cs->setPoints( QgsPointSequence() << ptA << ptB << ptC );
188 if ( !useCompoundCurves )
189 {
190 parts.emplace_back( QgsGeometry( std::move( cs ) ) );
191 }
192 else
193 {
194 auto cc = std::make_unique<QgsCompoundCurve>();
195 cc->addCurve( cs.release() );
196 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
197 }
198 }
199 break;
200 }
201
203 {
204 const QgsCompoundCurve *compoundCurve = qgsgeometry_cast<const QgsCompoundCurve *>( curve );
205 for ( int i = 0; i < compoundCurve->nCurves(); ++i )
206 {
207 std::vector<QgsGeometry> segments = curveAsSingleSegments( compoundCurve->curveAt( i ), true );
208 parts.reserve( parts.size() + segments.size() );
209 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
210 }
211 break;
212 }
213
214 default:
215 break;
216 }
217 return parts;
218}
219
ProcessingSourceType
Processing data source types.
Definition qgis.h:3531
@ VectorLine
Vector line layers.
Definition qgis.h:3535
@ RegeneratesPrimaryKey
Algorithm always drops any existing primary keys or FID values and regenerates them in outputs.
Definition qgis.h:3619
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
Definition qgis.h:3630
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition qgis.h:3711
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:277
@ CompoundCurve
CompoundCurve.
Definition qgis.h:288
@ LineString
LineString.
Definition qgis.h:280
@ CircularString
CircularString.
Definition qgis.h:287
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3722
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:36
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.
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence
QList< QgsFeature > QgsFeatureList