QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
Loading...
Searching...
No Matches
qgsalgorithmextractspecificvertices.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsalgorithmextractspecificvertices.cpp
3 --------------------------
4 begin : November 2019
5 copyright : (C) 2019 by Alexander Bruy
6 email : alexander dot bruy 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 QgsExtractSpecificVerticesAlgorithm::name() const
30{
31 return u"extractspecificvertices"_s;
32}
33
34QString QgsExtractSpecificVerticesAlgorithm::displayName() const
35{
36 return QObject::tr( "Extract specific vertices" );
37}
38
39QStringList QgsExtractSpecificVerticesAlgorithm::tags() const
40{
41 return QObject::tr( "points,vertex,nodes" ).split( ',' );
42}
43
44QString QgsExtractSpecificVerticesAlgorithm::group() const
45{
46 return QObject::tr( "Vector geometry" );
47}
48
49QString QgsExtractSpecificVerticesAlgorithm::groupId() const
50{
51 return u"vectorgeometry"_s;
52}
53
54QString QgsExtractSpecificVerticesAlgorithm::shortHelpString() const
55{
56 return QObject::tr(
57 "This algorithm takes a vector layer and generates a point layer with points "
58 "representing specific vertices in the input geometries. For instance, this algorithm "
59 "can be used to extract the first or last vertices in the geometry. The attributes associated "
60 "to each point are the same ones associated to the feature that the point belongs to."
61 )
62 + u"\n\n"_s
63 + QObject::tr(
64 "The vertex indices parameter accepts a comma separated string specifying the indices of the "
65 "vertices to extract. The first vertex corresponds to an index of 0, the second vertex has an "
66 "index of 1, etc. Negative indices can be used to find vertices at the end of the geometry, "
67 "e.g., an index of -1 corresponds to the last vertex, -2 corresponds to the second last vertex, etc."
68 )
69 + u"\n\n"_s
70 + QObject::tr(
71 "Additional fields are added to the points indicating the specific vertex position (e.g., 0, -1, etc), "
72 "the original vertex index, the vertex’s part and its index within the part (as well as its ring for "
73 "polygons), distance along the original geometry and bisector angle of vertex for the original geometry."
74 );
75}
76
77QString QgsExtractSpecificVerticesAlgorithm::shortDescription() const
78{
79 return QObject::tr( "Generates a point layer with points representing specific vertices in the input geometries." );
80}
81
82Qgis::ProcessingAlgorithmDocumentationFlags QgsExtractSpecificVerticesAlgorithm::documentationFlags() const
83{
85}
86
87QString QgsExtractSpecificVerticesAlgorithm::outputName() const
88{
89 return QObject::tr( "Vertices" );
90}
91
92QgsExtractSpecificVerticesAlgorithm *QgsExtractSpecificVerticesAlgorithm::createInstance() const
93{
94 return new QgsExtractSpecificVerticesAlgorithm();
95}
96
97Qgis::ProcessingSourceType QgsExtractSpecificVerticesAlgorithm::outputLayerType() const
98{
100}
101
102QgsFields QgsExtractSpecificVerticesAlgorithm::outputFields( const QgsFields &inputFields ) const
103{
104 QgsFields newFields;
105 newFields.append( QgsField( u"vertex_pos"_s, QMetaType::Type::Int ) );
106 newFields.append( QgsField( u"vertex_index"_s, QMetaType::Type::Int ) );
107 newFields.append( QgsField( u"vertex_part"_s, QMetaType::Type::Int ) );
108 if ( mGeometryType == Qgis::GeometryType::Polygon )
109 {
110 newFields.append( QgsField( u"vertex_part_ring"_s, QMetaType::Type::Int ) );
111 }
112 newFields.append( QgsField( u"vertex_part_index"_s, QMetaType::Type::Int ) );
113 newFields.append( QgsField( u"distance"_s, QMetaType::Type::Double ) );
114 newFields.append( QgsField( u"angle"_s, QMetaType::Type::Double ) );
115
116 return QgsProcessingUtils::combineFields( inputFields, newFields );
117}
118
119Qgis::WkbType QgsExtractSpecificVerticesAlgorithm::outputWkbType( Qgis::WkbType inputWkbType ) const
120{
121 Qgis::WkbType outputWkbType = Qgis::WkbType::Point;
122 if ( QgsWkbTypes::hasM( inputWkbType ) )
123 {
124 outputWkbType = QgsWkbTypes::addM( outputWkbType );
125 }
126 if ( QgsWkbTypes::hasZ( inputWkbType ) )
127 {
128 outputWkbType = QgsWkbTypes::addZ( outputWkbType );
129 }
130
131 return outputWkbType;
132}
133
134Qgis::ProcessingFeatureSourceFlags QgsExtractSpecificVerticesAlgorithm::sourceFlags() const
135{
137}
138
139QgsFeatureSink::SinkFlags QgsExtractSpecificVerticesAlgorithm::sinkFlags() const
140{
142}
143
144void QgsExtractSpecificVerticesAlgorithm::initParameters( const QVariantMap & )
145{
146 addParameter( new QgsProcessingParameterString( u"VERTICES"_s, QObject::tr( "Vertex indices" ), u"0"_s ) );
147}
148
149bool QgsExtractSpecificVerticesAlgorithm::prepareAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback * )
150{
151 std::unique_ptr<QgsProcessingFeatureSource> source( parameterAsSource( parameters, u"INPUT"_s, context ) );
152 if ( !source )
153 throw QgsProcessingException( invalidSourceError( parameters, u"INPUT"_s ) );
154
155 mGeometryType = QgsWkbTypes::geometryType( source->wkbType() );
156
157 const QString verticesString = parameterAsString( parameters, u"VERTICES"_s, context );
158 const QStringList verticesList = verticesString.split( ',', Qt::SkipEmptyParts );
159 for ( const QString &vertex : verticesList )
160 {
161 bool ok = false;
162 const int i = vertex.toInt( &ok );
163 if ( ok )
164 {
165 mIndices << i;
166 }
167 else
168 {
169 throw QgsProcessingException( QObject::tr( "'%1' is not a valid vertex index" ).arg( vertex ) );
170 }
171 }
172
173 return true;
174}
175
176QgsFeatureList QgsExtractSpecificVerticesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * )
177{
178 QgsFeatureList outputFeatures;
179
180 QgsFeature f = feature;
181 const QgsGeometry inputGeom = f.geometry();
182 if ( inputGeom.isEmpty() )
183 {
184 QgsAttributes attrs = f.attributes();
185 attrs << QVariant() << QVariant() << QVariant();
186 if ( mGeometryType == Qgis::GeometryType::Polygon )
187 {
188 attrs << QVariant();
189 }
190 attrs << QVariant() << QVariant() << QVariant();
191
192 f.clearGeometry();
193 f.setAttributes( attrs );
194 outputFeatures << f;
195 }
196 else
197 {
198 int vertexIndex;
199 const int totalVertices = inputGeom.constGet()->nCoordinates();
200 for ( const int vertex : mIndices )
201 {
202 if ( vertex < 0 )
203 {
204 vertexIndex = totalVertices + vertex;
205 }
206 else
207 {
208 vertexIndex = vertex;
209 }
210
211 if ( vertexIndex < 0 || vertexIndex >= totalVertices )
212 continue;
213
214 QgsVertexId vertexId;
215 inputGeom.vertexIdFromVertexNr( vertexIndex, vertexId );
216
217 const double distance = inputGeom.distanceToVertex( vertexIndex );
218 const double angle = inputGeom.angleAtVertex( vertexIndex ) * 180 / M_PI;
219
220 QgsFeature outFeature = QgsFeature();
221 QgsAttributes attrs = f.attributes();
222 attrs << vertex << vertexIndex << vertexId.part;
223 if ( mGeometryType == Qgis::GeometryType::Polygon )
224 {
225 attrs << vertexId.ring;
226 }
227 attrs << vertexId.vertex << distance << angle;
228
229 outFeature.setAttributes( attrs );
230 const QgsPoint point = inputGeom.vertexAt( vertexIndex );
231 outFeature.setGeometry( QgsGeometry( point.clone() ) );
232 outputFeatures << outFeature;
233 }
234 }
235
236 return outputFeatures;
237}
238
ProcessingSourceType
Processing data source types.
Definition qgis.h:3645
@ VectorPoint
Vector point layers.
Definition qgis.h:3648
@ Polygon
Polygons.
Definition qgis.h:382
@ 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
@ Point
Point.
Definition qgis.h:296
QFlags< ProcessingFeatureSourceFlag > ProcessingFeatureSourceFlags
Flags which control how QgsProcessingFeatureSource fetches features.
Definition qgis.h:3839
virtual int nCoordinates() const
Returns the number of nodes contained in the geometry.
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:75
A geometry is the spatial representation of a feature.
bool vertexIdFromVertexNr(int number, QgsVertexId &id) const
Calculates the vertex ID from a vertex number.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
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...
double distanceToVertex(int vertex) const
Returns the distance along this geometry from its first vertex to the specified vertex.
double angleAtVertex(int vertex) const
Returns the bisector angle for this geometry at the specified vertex.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
QgsPoint * clone() const override
Clones the geometry by performing a deep copy.
Definition qgspoint.cpp:138
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.
A string parameter for processing algorithms.
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:99
int part
Part number.
Definition qgsvertexid.h:93
int ring
Ring number.
Definition qgsvertexid.h:96