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