QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsalgorithmextractvertices.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmextractvertices.cpp
3 --------------------------
4 begin : November 2017
5 copyright : (C) 2017 by Mathieu Pellerin
6 email : nirvn dot asia 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
19
20#include "qgsabstractgeometry.h"
21#include "qgsgeometryutils.h"
22
24
25QString QgsExtractVerticesAlgorithm::name() const
26{
27 return QStringLiteral( "extractvertices" );
28}
29
30QString QgsExtractVerticesAlgorithm::displayName() const
31{
32 return QObject::tr( "Extract vertices" );
33}
34
35QStringList QgsExtractVerticesAlgorithm::tags() const
36{
37 return QObject::tr( "points,vertex,nodes" ).split( ',' );
38}
39
40QString QgsExtractVerticesAlgorithm::group() const
41{
42 return QObject::tr( "Vector geometry" );
43}
44
45QString QgsExtractVerticesAlgorithm::groupId() const
46{
47 return QStringLiteral( "vectorgeometry" );
48}
49
50QString QgsExtractVerticesAlgorithm::shortHelpString() const
51{
52 return QObject::tr( "This algorithm takes a vector layer and generates a point layer with points representing the vertices in the input geometries. The attributes associated to each point are the same ones associated to the feature that the point belongs to." ) +
53 QStringLiteral( "\n\n" ) +
54 QObject::tr( "Additional fields are added to the point indicating the vertex index (beginning at 0), the vertex’s part and its index within the part (as well as its ring for polygons), distance along original geometry and bisector angle of vertex for original geometry." );
55}
56
57QString QgsExtractVerticesAlgorithm::outputName() const
58{
59 return QObject::tr( "Vertices" );
60}
61
62QgsExtractVerticesAlgorithm *QgsExtractVerticesAlgorithm::createInstance() const
63{
64 return new QgsExtractVerticesAlgorithm();
65}
66
67Qgis::ProcessingSourceType QgsExtractVerticesAlgorithm::outputLayerType() const
68{
70}
71
72QgsFields QgsExtractVerticesAlgorithm::outputFields( const QgsFields &inputFields ) const
73{
74 QgsFields outputFields = inputFields;
75 outputFields.append( QgsField( QStringLiteral( "vertex_index" ), QVariant::Int, QString(), 10, 0 ) );
76 outputFields.append( QgsField( QStringLiteral( "vertex_part" ), QVariant::Int, QString(), 10, 0 ) );
77 if ( mGeometryType == Qgis::GeometryType::Polygon )
78 {
79 outputFields.append( QgsField( QStringLiteral( "vertex_part_ring" ), QVariant::Int, QString(), 10, 0 ) );
80 }
81 outputFields.append( QgsField( QStringLiteral( "vertex_part_index" ), QVariant::Int, QString(), 10, 0 ) );
82 outputFields.append( QgsField( QStringLiteral( "distance" ), QVariant::Double, QString(), 20, 14 ) );
83 outputFields.append( QgsField( QStringLiteral( "angle" ), QVariant::Double, QString(), 20, 14 ) );
84
85 return outputFields;
86}
87
88Qgis::WkbType QgsExtractVerticesAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
89{
90 Qgis::WkbType outputWkbType = Qgis::WkbType::Point;
91 if ( QgsWkbTypes::hasM( inputWkbType ) )
92 {
93 outputWkbType = QgsWkbTypes::addM( outputWkbType );
94 }
95 if ( QgsWkbTypes::hasZ( inputWkbType ) )
96 {
97 outputWkbType = QgsWkbTypes::addZ( outputWkbType );
98 }
99
100 return outputWkbType;
101}
102
103Qgis::ProcessingFeatureSourceFlags QgsExtractVerticesAlgorithm::sourceFlags() const
104{
106}
107
108QgsFeatureSink::SinkFlags QgsExtractVerticesAlgorithm::sinkFlags() const
109{
111}
112
113bool QgsExtractVerticesAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
114{
115 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
116 mGeometryType = QgsWkbTypes::geometryType( source->wkbType() );
117 return true;
118}
119
120QgsFeatureList QgsExtractVerticesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
121{
122 QgsFeatureList outputFeatures;
123
124 QgsFeature f = feature;
125 const QgsGeometry inputGeom = f.geometry();
126 if ( inputGeom.isEmpty() )
127 {
128 QgsAttributes attrs = f.attributes();
129 attrs << QVariant()
130 << QVariant();
131 if ( mGeometryType == Qgis::GeometryType::Polygon )
132 {
133 attrs << QVariant();
134 }
135 attrs << QVariant()
136 << QVariant()
137 << QVariant();
138
139 f.clearGeometry();
140 f.setAttributes( attrs );
141 outputFeatures << f;
142 }
143 else
144 {
146 double cumulativeDistance = 0.0;
147 int vertexPos = 0;
148 while ( vi != inputGeom.constGet()->vertices_end() )
149 {
150 const QgsVertexId vertexId = vi.vertexId();
151 const double angle = inputGeom.constGet()->vertexAngle( vertexId ) * 180 / M_PI;
152 QgsAttributes attrs = f.attributes();
153 attrs << vertexPos
154 << vertexId.part;
155 if ( mGeometryType == Qgis::GeometryType::Polygon )
156 {
157 attrs << vertexId.ring;
158 }
159 attrs << vertexId.vertex
160 << cumulativeDistance
161 << angle;
162
163 QgsFeature outputFeature = QgsFeature();
164 outputFeature.setAttributes( attrs );
165 outputFeature.setGeometry( QgsGeometry( ( *vi ).clone() ) );
166 outputFeatures << outputFeature;
167 vi++;
168 vertexPos++;
169
170 // calculate distance to next vertex
171 const double distanceToNext = inputGeom.constGet()->segmentLength( vertexId );
172 cumulativeDistance += distanceToNext;
173 }
174 }
175
176 return outputFeatures;
177}
178
ProcessingSourceType
Processing data source types.
Definition: qgis.h:2858
@ VectorPoint
Vector point layers.
@ Polygon
Polygons.
@ 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:182
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition: qgis.h:3011
The vertex_iterator class provides STL-style iterator for vertices.
QgsVertexId vertexId() const
Returns vertex ID of the current item.
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
A vector of attributes.
Definition: qgsattributes.h:59
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
void clearGeometry()
Removes any geometry associated with the feature.
Definition: qgsfeature.cpp:181
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:167
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:53
Container of fields for a vector layer.
Definition: qgsfields.h:45
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Appends a field. The field must have unique name, otherwise it is rejected (returns false)
Definition: qgsfields.cpp:59
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 isEmpty() const
Returns true if the geometry is empty (eg a linestring with no vertices, or a collection with no geom...
Contains information about the context in which a processing algorithm is executed.
Base class for providing feedback from a processing algorithm.
static Qgis::GeometryType geometryType(Qgis::WkbType type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:862
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1092
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1068
static bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:973
static bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1023
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
Definition: MathUtils.cpp:716
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:917
Utility class for identifying a unique vertex within a geometry.
Definition: qgsvertexid.h:30
int vertex
Vertex number.
Definition: qgsvertexid.h:94
int part
Part number.
Definition: qgsvertexid.h:88
int ring
Ring number.
Definition: qgsvertexid.h:91