QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 
25 QString QgsExtractVerticesAlgorithm::name() const
26 {
27  return QStringLiteral( "extractvertices" );
28 }
29 
30 QString QgsExtractVerticesAlgorithm::displayName() const
31 {
32  return QObject::tr( "Extract vertices" );
33 }
34 
35 QStringList QgsExtractVerticesAlgorithm::tags() const
36 {
37  return QObject::tr( "points,vertex,nodes" ).split( ',' );
38 }
39 
40 QString QgsExtractVerticesAlgorithm::group() const
41 {
42  return QObject::tr( "Vector geometry" );
43 }
44 
45 QString QgsExtractVerticesAlgorithm::groupId() const
46 {
47  return QStringLiteral( "vectorgeometry" );
48 }
49 
50 QString QgsExtractVerticesAlgorithm::shortHelpString() const
51 {
52  return QObject::tr( "This algorithm takes a line or polygon layer and generates a point layer with points representing the vertices in the input lines or polygons. The attributes associated to each point are the same ones associated to the line or polygon 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 
57 QString QgsExtractVerticesAlgorithm::outputName() const
58 {
59  return QObject::tr( "Vertices" );
60 }
61 
62 QgsExtractVerticesAlgorithm *QgsExtractVerticesAlgorithm::createInstance() const
63 {
64  return new QgsExtractVerticesAlgorithm();
65 }
66 
67 QgsProcessing::SourceType QgsExtractVerticesAlgorithm::outputLayerType() const
68 {
70 }
71 
72 QgsFields 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 == QgsWkbTypes::PolygonGeometry )
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 
88 QgsWkbTypes::Type QgsExtractVerticesAlgorithm::outputWkbType( QgsWkbTypes::Type inputWkbType ) const
89 {
90  QgsWkbTypes::Type outputWkbType = QgsWkbTypes::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 
103 QgsProcessingFeatureSource::Flag QgsExtractVerticesAlgorithm::sourceFlags() const
104 {
106 }
107 
108 QgsFeatureSink::SinkFlags QgsExtractVerticesAlgorithm::sinkFlags() const
109 {
111 }
112 
113 bool 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 
120 QgsFeatureList QgsExtractVerticesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
121 {
122  QgsFeatureList outputFeatures;
123 
124  QgsFeature f = feature;
125  QgsGeometry inputGeom = f.geometry();
126  if ( inputGeom.isNull() )
127  {
128  QgsAttributes attrs = f.attributes();
129  attrs << QVariant()
130  << QVariant();
131  if ( mGeometryType == QgsWkbTypes::PolygonGeometry )
132  {
133  attrs << QVariant();
134  }
135  attrs << QVariant()
136  << QVariant()
137  << QVariant();
138 
139  f.setAttributes( attrs );
140  outputFeatures << f;
141  }
142  else
143  {
145  double cumulativeDistance = 0.0;
146  int vertexPos = 0;
147  while ( vi != inputGeom.constGet()->vertices_end() )
148  {
149  QgsVertexId vertexId = vi.vertexId();
150  double angle = inputGeom.constGet()->vertexAngle( vertexId ) * 180 / M_PI;
151  QgsAttributes attrs = f.attributes();
152  attrs << vertexPos
153  << vertexId.part;
154  if ( mGeometryType == QgsWkbTypes::PolygonGeometry )
155  {
156  attrs << vertexId.ring;
157  }
158  attrs << vertexId.vertex
159  << cumulativeDistance
160  << angle;
161 
162  QgsFeature outputFeature = QgsFeature();
163  outputFeature.setAttributes( attrs );
164  outputFeature.setGeometry( QgsGeometry( ( *vi ).clone() ) );
165  outputFeatures << outputFeature;
166  vi++;
167  vertexPos++;
168 
169  // calculate distance to next vertex
170  double distanceToNext = inputGeom.constGet()->segmentLength( vertexId );
171  cumulativeDistance += distanceToNext;
172  }
173  }
174 
175  return outputFeatures;
176 }
177 
QgsAbstractGeometry::vertices_end
vertex_iterator vertices_end() const
Returns STL-style iterator pointing to the imaginary vertex after the last vertex of the geometry.
Definition: qgsabstractgeometry.h:924
QgsVertexId::part
int part
Part number.
Definition: qgsabstractgeometry.h:1131
QgsVertexId::vertex
int vertex
Vertex number.
Definition: qgsabstractgeometry.h:1137
QgsWkbTypes::Point
@ Point
Definition: qgswkbtypes.h:72
qgsalgorithmextractvertices.h
QgsProcessingFeedback
Base class for providing feedback from a processing algorithm.
Definition: qgsprocessingfeedback.h:38
QgsGeometry::isNull
Q_GADGET bool isNull
Definition: qgsgeometry.h:126
QgsFields
Container of fields for a vector layer.
Definition: qgsfields.h:45
QgsWkbTypes::addZ
static Type addZ(Type type) SIP_HOLDGIL
Adds the z dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1139
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:67
QgsProcessingFeatureSource::FlagSkipGeometryValidityChecks
@ FlagSkipGeometryValidityChecks
Invalid geometry checks should always be skipped. This flag can be useful for algorithms which always...
Definition: qgsprocessingutils.h:477
QgsWkbTypes::Type
Type
The WKB type describes the number of dimensions a geometry has.
Definition: qgswkbtypes.h:70
QgsFields::append
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
QgsProcessing::TypeVectorPoint
@ TypeVectorPoint
Vector point layers.
Definition: qgsprocessing.h:48
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsAbstractGeometry::vertexAngle
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
QgsWkbTypes::addM
static Type addM(Type type) SIP_HOLDGIL
Adds the m dimension to a WKB type and returns the new type.
Definition: qgswkbtypes.h:1164
QgsFeature::setGeometry
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
Definition: qgsfeature.cpp:139
QgsProcessingContext
Contains information about the context in which a processing algorithm is executed.
Definition: qgsprocessingcontext.h:44
QgsAbstractGeometry::vertices_begin
vertex_iterator vertices_begin() const
Returns STL-style iterator pointing to the first vertex of the geometry.
Definition: qgsabstractgeometry.h:911
QgsFeatureList
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:583
QgsWkbTypes::hasM
static bool hasM(Type type) SIP_HOLDGIL
Tests whether a WKB type contains m values.
Definition: qgswkbtypes.h:1093
QgsAbstractGeometry::vertex_iterator::vertexId
QgsVertexId vertexId() const
Returns vertex ID of the current item.
Definition: qgsabstractgeometry.cpp:362
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsFeatureSink::RegeneratePrimaryKey
@ RegeneratePrimaryKey
This flag indicates, that a primary key field cannot be guaranteed to be unique and the sink should i...
Definition: qgsfeaturesink.h:55
QgsFeature::attributes
QgsAttributes attributes
Definition: qgsfeature.h:65
qgsgeometryutils.h
QgsProcessingFeatureSource::Flag
Flag
Flags controlling how QgsProcessingFeatureSource fetches features.
Definition: qgsprocessingutils.h:476
QgsAbstractGeometry::vertex_iterator
The vertex_iterator class provides STL-style iterator for vertices.
Definition: qgsabstractgeometry.h:856
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsAbstractGeometry::segmentLength
virtual double segmentLength(QgsVertexId startVertex) const =0
Returns the length of the segment of the geometry which begins at startVertex.
QgsVertexId
Utility class for identifying a unique vertex within a geometry.
Definition: qgsabstractgeometry.h:1059
QgsVertexId::ring
int ring
Ring number.
Definition: qgsabstractgeometry.h:1134
QgsWkbTypes::geometryType
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:938
QgsWkbTypes::hasZ
static bool hasZ(Type type) SIP_HOLDGIL
Tests whether a WKB type contains the z-dimension.
Definition: qgswkbtypes.h:1043
QgsAttributes
A vector of attributes.
Definition: qgsattributes.h:58
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsFeature::setAttributes
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
Definition: qgsfeature.cpp:129
MathUtils::angle
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:786
QgsProcessing::SourceType
SourceType
Data source types enum.
Definition: qgsprocessing.h:45
qgsabstractgeometry.h
QgsField
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:50