QGIS API Documentation 3.43.0-Master (a93bf8b6462)
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 of the input geometries. The attributes associated to each point are the same ones associated to the feature that the point belongs to." ) + QStringLiteral( "\n\n" ) + 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." );
53}
54
55QString QgsExtractVerticesAlgorithm::shortDescription() const
56{
57 return QObject::tr( "Generates a point layer with points representing the vertices of the input geometries." );
58}
59
60Qgis::ProcessingAlgorithmDocumentationFlags QgsExtractVerticesAlgorithm::documentationFlags() const
61{
63}
64
65QString QgsExtractVerticesAlgorithm::outputName() const
66{
67 return QObject::tr( "Vertices" );
68}
69
70QgsExtractVerticesAlgorithm *QgsExtractVerticesAlgorithm::createInstance() const
71{
72 return new QgsExtractVerticesAlgorithm();
73}
74
75Qgis::ProcessingSourceType QgsExtractVerticesAlgorithm::outputLayerType() const
76{
78}
79
80QgsFields QgsExtractVerticesAlgorithm::outputFields( const QgsFields &inputFields ) const
81{
82 QgsFields newFields;
83 newFields.append( QgsField( QStringLiteral( "vertex_index" ), QMetaType::Type::Int, QString(), 10, 0 ) );
84 newFields.append( QgsField( QStringLiteral( "vertex_part" ), QMetaType::Type::Int, QString(), 10, 0 ) );
85 if ( mGeometryType == Qgis::GeometryType::Polygon )
86 {
87 newFields.append( QgsField( QStringLiteral( "vertex_part_ring" ), QMetaType::Type::Int, QString(), 10, 0 ) );
88 }
89 newFields.append( QgsField( QStringLiteral( "vertex_part_index" ), QMetaType::Type::Int, QString(), 10, 0 ) );
90 newFields.append( QgsField( QStringLiteral( "distance" ), QMetaType::Type::Double, QString(), 20, 14 ) );
91 newFields.append( QgsField( QStringLiteral( "angle" ), QMetaType::Type::Double, QString(), 20, 14 ) );
92
93 return QgsProcessingUtils::combineFields( inputFields, newFields );
94}
95
96Qgis::WkbType QgsExtractVerticesAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
97{
98 Qgis::WkbType outputWkbType = Qgis::WkbType::Point;
99 if ( QgsWkbTypes::hasM( inputWkbType ) )
100 {
101 outputWkbType = QgsWkbTypes::addM( outputWkbType );
102 }
103 if ( QgsWkbTypes::hasZ( inputWkbType ) )
104 {
105 outputWkbType = QgsWkbTypes::addZ( outputWkbType );
106 }
107
108 return outputWkbType;
109}
110
111Qgis::ProcessingFeatureSourceFlags QgsExtractVerticesAlgorithm::sourceFlags() const
112{
114}
115
116QgsFeatureSink::SinkFlags QgsExtractVerticesAlgorithm::sinkFlags() const
117{
119}
120
121bool QgsExtractVerticesAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
122{
123 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
124 if ( !source )
125 throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
126
127 mGeometryType = QgsWkbTypes::geometryType( source->wkbType() );
128 return true;
129}
130
131QgsFeatureList QgsExtractVerticesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
132{
133 QgsFeatureList outputFeatures;
134
135 QgsFeature f = feature;
136 const QgsGeometry inputGeom = f.geometry();
137 if ( inputGeom.isEmpty() )
138 {
139 QgsAttributes attrs = f.attributes();
140 attrs << QVariant()
141 << QVariant();
142 if ( mGeometryType == Qgis::GeometryType::Polygon )
143 {
144 attrs << QVariant();
145 }
146 attrs << QVariant()
147 << QVariant()
148 << QVariant();
149
150 f.clearGeometry();
151 f.setAttributes( attrs );
152 outputFeatures << f;
153 }
154 else
155 {
157 double cumulativeDistance = 0.0;
158 int vertexPos = 0;
159 while ( vi != inputGeom.constGet()->vertices_end() )
160 {
161 const QgsVertexId vertexId = vi.vertexId();
162 const double angle = inputGeom.constGet()->vertexAngle( vertexId ) * 180 / M_PI;
163 QgsAttributes attrs = f.attributes();
164 attrs << vertexPos
165 << vertexId.part;
166 if ( mGeometryType == Qgis::GeometryType::Polygon )
167 {
168 attrs << vertexId.ring;
169 }
170 attrs << vertexId.vertex
171 << cumulativeDistance
172 << angle;
173
174 QgsFeature outputFeature = QgsFeature();
175 outputFeature.setAttributes( attrs );
176 outputFeature.setGeometry( QgsGeometry( ( *vi ).clone() ) );
177 outputFeatures << outputFeature;
178 vi++;
179 vertexPos++;
180
181 // calculate distance to next vertex
182 const double distanceToNext = inputGeom.constGet()->segmentLength( vertexId );
183 cumulativeDistance += distanceToNext;
184 }
185 }
186
187 return outputFeatures;
188}
189
ProcessingSourceType
Processing data source types.
Definition qgis.h:3415
@ VectorPoint
Vector point layers.
@ Polygon
Polygons.
@ 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:3512
@ 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
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3604
The vertex_iterator class provides an 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.
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
void clearGeometry()
Removes any geometry associated with the feature.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Encapsulate a field in an attribute table or data source.
Definition qgsfield.h:53
Container of fields for a vector layer.
Definition qgsfields.h:46
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
Definition qgsfields.cpp:70
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 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.
Custom exception class for processing related exceptions.
Base class for providing feedback from a processing algorithm.
static QgsFields combineFields(const QgsFields &fieldsA, const QgsFields &fieldsB, const QString &fieldsBPrefix=QString())
Combines two field lists, avoiding duplicate field names (in a case-insensitive manner).
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...
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
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)
QList< QgsFeature > QgsFeatureList
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