QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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(
60 "This algorithm takes a lines layer and creates a new one in which each line is replaced by a set of "
61 "lines representing the segments in the original line. Each line in the resulting layer contains only a "
62 "start and an end point, with no intermediate nodes between them.\n\n"
63 "If the input layer consists of CircularStrings or CompoundCurves, the output layer will be of the "
64 "same type and contain only single curve segments."
65 );
66}
67
68QString QgsExplodeAlgorithm::shortDescription() const
69{
70 return QObject::tr( "Creates a line layer in which each feature represents a segment from an input line layer." );
71}
72
73Qgis::ProcessingAlgorithmDocumentationFlags QgsExplodeAlgorithm::documentationFlags() const
74{
76}
77
78QList<int> QgsExplodeAlgorithm::inputLayerTypes() const
79{
80 return QList<int>() << static_cast<int>( Qgis::ProcessingSourceType::VectorLine );
81}
82
83Qgis::ProcessingSourceType QgsExplodeAlgorithm::outputLayerType() const
84{
86}
87
88QgsExplodeAlgorithm *QgsExplodeAlgorithm::createInstance() const
89{
90 return new QgsExplodeAlgorithm();
91}
92
93QString QgsExplodeAlgorithm::outputName() const
94{
95 return QObject::tr( "Exploded" );
96}
97
98Qgis::WkbType QgsExplodeAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
99{
100 return QgsWkbTypes::singleType( inputWkbType );
101}
102
103QgsFeatureList QgsExplodeAlgorithm::processFeature( const QgsFeature &f, QgsProcessingContext &, QgsProcessingFeedback * )
104{
105 if ( !f.hasGeometry() )
106 {
107 return QgsFeatureList() << f;
108 }
109 else
110 {
111 const std::vector<QgsGeometry> parts = extractAsParts( f.geometry() );
112 QgsFeature outputFeature;
113 QgsFeatureList features;
114 features.reserve( parts.size() );
115 for ( const QgsGeometry &part : parts )
116 {
117 outputFeature.setAttributes( f.attributes() );
118 outputFeature.setGeometry( part );
119 features << outputFeature;
120 }
121 return features;
122 }
123}
124
125Qgis::ProcessingFeatureSourceFlags QgsExplodeAlgorithm::sourceFlags() const
126{
128}
129
130QgsFeatureSink::SinkFlags QgsExplodeAlgorithm::sinkFlags() const
131{
133}
134
135std::vector<QgsGeometry> QgsExplodeAlgorithm::extractAsParts( const QgsGeometry &geometry ) const
136{
137 if ( geometry.isMultipart() )
138 {
139 std::vector<QgsGeometry> parts;
140 const QgsGeometryCollection *collection = qgis::down_cast< const QgsGeometryCollection * >( geometry.constGet() );
141 for ( int part = 0; part < collection->numGeometries(); ++part )
142 {
143 std::vector<QgsGeometry> segments = curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( collection->geometryN( part ) ) );
144 parts.reserve( parts.size() + segments.size() );
145 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
146 }
147 return parts;
148 }
149 else
150 {
151 return curveAsSingleSegments( qgsgeometry_cast<const QgsCurve *>( geometry.constGet() ) );
152 }
153}
154
155std::vector<QgsGeometry> QgsExplodeAlgorithm::curveAsSingleSegments( const QgsCurve *curve, bool useCompoundCurves ) const
156{
157 std::vector<QgsGeometry> parts;
158 if ( !curve )
159 return parts;
160 switch ( QgsWkbTypes::flatType( curve->wkbType() ) )
161 {
163 {
165 for ( int i = 0; i < line->numPoints() - 1; ++i )
166 {
167 const QgsPoint ptA = line->pointN( i );
168 const QgsPoint ptB = line->pointN( i + 1 );
169 auto ls = std::make_unique<QgsLineString>( QVector<QgsPoint>() << ptA << ptB );
170 if ( !useCompoundCurves )
171 {
172 parts.emplace_back( QgsGeometry( std::move( ls ) ) );
173 }
174 else
175 {
176 auto cc = std::make_unique<QgsCompoundCurve>();
177 cc->addCurve( ls.release() );
178 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
179 }
180 }
181 break;
182 }
183
185 {
187 for ( int i = 0; i < string->numPoints() - 2; i += 2 )
188 {
189 const QgsPoint ptA = string->pointN( i );
190 const QgsPoint ptB = string->pointN( i + 1 );
191 const QgsPoint ptC = string->pointN( i + 2 );
192 auto cs = std::make_unique<QgsCircularString>();
193 cs->setPoints( QgsPointSequence() << ptA << ptB << ptC );
194 if ( !useCompoundCurves )
195 {
196 parts.emplace_back( QgsGeometry( std::move( cs ) ) );
197 }
198 else
199 {
200 auto cc = std::make_unique<QgsCompoundCurve>();
201 cc->addCurve( cs.release() );
202 parts.emplace_back( QgsGeometry( std::move( cc ) ) );
203 }
204 }
205 break;
206 }
207
209 {
210 const QgsCompoundCurve *compoundCurve = qgsgeometry_cast<const QgsCompoundCurve *>( curve );
211 for ( int i = 0; i < compoundCurve->nCurves(); ++i )
212 {
213 std::vector<QgsGeometry> segments = curveAsSingleSegments( compoundCurve->curveAt( i ), true );
214 parts.reserve( parts.size() + segments.size() );
215 std::move( std::begin( segments ), std::end( segments ), std::back_inserter( parts ) );
216 }
217 break;
218 }
219
220 default:
221 break;
222 }
223 return parts;
224}
225
ProcessingSourceType
Processing data source types.
Definition qgis.h:3645
@ VectorLine
Vector line layers.
Definition qgis.h:3649
@ RegeneratesPrimaryKey
Algorithm always drops any existing primary keys or FID values and regenerates them in outputs.
Definition qgis.h:3734
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
Definition qgis.h:3745
@ SkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition qgis.h:3828
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ CompoundCurve
CompoundCurve.
Definition qgis.h:305
@ LineString
LineString.
Definition qgis.h:297
@ CircularString
CircularString.
Definition qgis.h:304
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3839
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: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