QGIS API Documentation 3.99.0-Master (357b655ed83)
Loading...
Searching...
No Matches
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
23#include <QString>
24
25using namespace Qt::StringLiterals;
26
28
29QString QgsExtractVerticesAlgorithm::name() const
30{
31 return u"extractvertices"_s;
32}
33
34QString QgsExtractVerticesAlgorithm::displayName() const
35{
36 return QObject::tr( "Extract vertices" );
37}
38
39QStringList QgsExtractVerticesAlgorithm::tags() const
40{
41 return QObject::tr( "points,vertex,nodes" ).split( ',' );
42}
43
44QString QgsExtractVerticesAlgorithm::group() const
45{
46 return QObject::tr( "Vector geometry" );
47}
48
49QString QgsExtractVerticesAlgorithm::groupId() const
50{
51 return u"vectorgeometry"_s;
52}
53
54QString QgsExtractVerticesAlgorithm::shortHelpString() const
55{
56 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." ) + u"\n\n"_s + 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." );
57}
58
59QString QgsExtractVerticesAlgorithm::shortDescription() const
60{
61 return QObject::tr( "Generates a point layer with points representing the vertices of the input geometries." );
62}
63
64Qgis::ProcessingAlgorithmDocumentationFlags QgsExtractVerticesAlgorithm::documentationFlags() const
65{
67}
68
69QString QgsExtractVerticesAlgorithm::outputName() const
70{
71 return QObject::tr( "Vertices" );
72}
73
74QgsExtractVerticesAlgorithm *QgsExtractVerticesAlgorithm::createInstance() const
75{
76 return new QgsExtractVerticesAlgorithm();
77}
78
79Qgis::ProcessingSourceType QgsExtractVerticesAlgorithm::outputLayerType() const
80{
82}
83
84QgsFields QgsExtractVerticesAlgorithm::outputFields( const QgsFields &inputFields ) const
85{
86 QgsFields newFields;
87 newFields.append( QgsField( u"vertex_index"_s, QMetaType::Type::Int, QString(), 10, 0 ) );
88 newFields.append( QgsField( u"vertex_part"_s, QMetaType::Type::Int, QString(), 10, 0 ) );
89 if ( mGeometryType == Qgis::GeometryType::Polygon )
90 {
91 newFields.append( QgsField( u"vertex_part_ring"_s, QMetaType::Type::Int, QString(), 10, 0 ) );
92 }
93 newFields.append( QgsField( u"vertex_part_index"_s, QMetaType::Type::Int, QString(), 10, 0 ) );
94 newFields.append( QgsField( u"distance"_s, QMetaType::Type::Double, QString(), 20, 14 ) );
95 newFields.append( QgsField( u"angle"_s, QMetaType::Type::Double, QString(), 20, 14 ) );
96
97 return QgsProcessingUtils::combineFields( inputFields, newFields );
98}
99
100Qgis::WkbType QgsExtractVerticesAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
101{
102 Qgis::WkbType outputWkbType = Qgis::WkbType::Point;
103 if ( QgsWkbTypes::hasM( inputWkbType ) )
104 {
105 outputWkbType = QgsWkbTypes::addM( outputWkbType );
106 }
107 if ( QgsWkbTypes::hasZ( inputWkbType ) )
108 {
109 outputWkbType = QgsWkbTypes::addZ( outputWkbType );
110 }
111
112 return outputWkbType;
113}
114
115Qgis::ProcessingFeatureSourceFlags QgsExtractVerticesAlgorithm::sourceFlags() const
116{
118}
119
120QgsFeatureSink::SinkFlags QgsExtractVerticesAlgorithm::sinkFlags() const
121{
123}
124
125bool QgsExtractVerticesAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
126{
127 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u"INPUT"_s, context ) );
128 if ( !source )
129 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
130
131 mGeometryType = QgsWkbTypes::geometryType( source->wkbType() );
132 return true;
133}
134
135QgsFeatureList QgsExtractVerticesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
136{
137 QgsFeatureList outputFeatures;
138
139 QgsFeature f = feature;
140 const QgsGeometry inputGeom = f.geometry();
141 if ( inputGeom.isEmpty() )
142 {
143 QgsAttributes attrs = f.attributes();
144 attrs << QVariant()
145 << QVariant();
146 if ( mGeometryType == Qgis::GeometryType::Polygon )
147 {
148 attrs << QVariant();
149 }
150 attrs << QVariant()
151 << QVariant()
152 << QVariant();
153
154 f.clearGeometry();
155 f.setAttributes( attrs );
156 outputFeatures << f;
157 }
158 else
159 {
161 double cumulativeDistance = 0.0;
162 int vertexPos = 0;
163 while ( vi != inputGeom.constGet()->vertices_end() )
164 {
165 const QgsVertexId vertexId = vi.vertexId();
166 const double angle = inputGeom.constGet()->vertexAngle( vertexId ) * 180 / M_PI;
167 QgsAttributes attrs = f.attributes();
168 attrs << vertexPos
169 << vertexId.part;
170 if ( mGeometryType == Qgis::GeometryType::Polygon )
171 {
172 attrs << vertexId.ring;
173 }
174 attrs << vertexId.vertex
175 << cumulativeDistance
176 << angle;
177
178 QgsFeature outputFeature = QgsFeature();
179 outputFeature.setAttributes( attrs );
180 outputFeature.setGeometry( QgsGeometry( ( *vi ).clone() ) );
181 outputFeatures << outputFeature;
182 vi++;
183 vertexPos++;
184
185 // calculate distance to next vertex
186 const double distanceToNext = inputGeom.constGet()->segmentLength( vertexId );
187 cumulativeDistance += distanceToNext;
188 }
189 }
190
191 return outputFeatures;
192}
193
ProcessingSourceType
Processing data source types.
Definition qgis.h:3602
@ VectorPoint
Vector point layers.
Definition qgis.h:3605
@ Polygon
Polygons.
Definition qgis.h:368
@ 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
@ Point
Point.
Definition qgis.h:282
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3793
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:60
QgsAttributes attributes
Definition qgsfeature.h:69
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
QgsGeometry geometry
Definition qgsfeature.h:71
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:56
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:76
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:34
int vertex
Vertex number.
Definition qgsvertexid.h:98
int part
Part number.
Definition qgsvertexid.h:92
int ring
Ring number.
Definition qgsvertexid.h:95