Skip to content

Commit 7cb15c0

Browse files
committedNov 13, 2017
Optimize extract nodes algorithm
1 parent 82644fb commit 7cb15c0

File tree

6 files changed

+196
-124
lines changed

6 files changed

+196
-124
lines changed
 

‎python/plugins/processing/algs/qgis/ExtractNodes.py

Lines changed: 0 additions & 122 deletions
This file was deleted.

‎python/plugins/processing/algs/qgis/QGISAlgorithmProvider.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@
6464
from .ExportGeometryInfo import ExportGeometryInfo
6565
from .ExtendLines import ExtendLines
6666
from .ExtentFromLayer import ExtentFromLayer
67-
from .ExtractNodes import ExtractNodes
6867
from .ExtractSpecificNodes import ExtractSpecificNodes
6968
from .FieldPyculator import FieldsPyculator
7069
from .FieldsCalculator import FieldsCalculator
@@ -190,7 +189,6 @@ def getAlgs(self):
190189
ExportGeometryInfo(),
191190
ExtendLines(),
192191
ExtentFromLayer(),
193-
ExtractNodes(),
194192
ExtractSpecificNodes(),
195193
FieldsCalculator(),
196194
FieldsMapper(),

‎src/analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ SET(QGIS_ANALYSIS_SRCS
3535
processing/qgsalgorithmextractbyexpression.cpp
3636
processing/qgsalgorithmextractbyextent.cpp
3737
processing/qgsalgorithmextractbylocation.cpp
38+
processing/qgsalgorithmextractnodes.cpp
3839
processing/qgsalgorithmfiledownloader.cpp
3940
processing/qgsalgorithmfixgeometries.cpp
4041
processing/qgsalgorithmjoinbyattribute.cpp
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/***************************************************************************
2+
qgsalgorithmextractnodes.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+
18+
#include "qgsalgorithmextractnodes.h"
19+
20+
///@cond PRIVATE
21+
22+
QString QgsExtractNodesAlgorithm::name() const
23+
{
24+
return QStringLiteral( "extractnodes" );
25+
}
26+
27+
QString QgsExtractNodesAlgorithm::displayName() const
28+
{
29+
return QObject::tr( "Extract nodes" );
30+
}
31+
32+
QStringList QgsExtractNodesAlgorithm::tags() const
33+
{
34+
return QObject::tr( "points,vertex,vertices" ).split( ',' );
35+
}
36+
37+
QString QgsExtractNodesAlgorithm::group() const
38+
{
39+
return QObject::tr( "Vector geometry" );
40+
}
41+
42+
QString QgsExtractNodesAlgorithm::shortHelpString() const
43+
{
44+
return QObject::tr( "This algorithm takes a line or polygon layer and generates a point layer with points representing the nodes 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." ) +
45+
QStringLiteral( "\n\n" ) +
46+
QObject::tr( "Additional fields are added to the nodes indicating the node index (beginning at 0), distance along original geometry and bisector angle of node for original geometry." );
47+
}
48+
49+
QgsExtractNodesAlgorithm *QgsExtractNodesAlgorithm::createInstance() const
50+
{
51+
return new QgsExtractNodesAlgorithm();
52+
}
53+
54+
void QgsExtractNodesAlgorithm::initAlgorithm( const QVariantMap & )
55+
{
56+
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
57+
58+
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Nodes" ) ) );
59+
}
60+
61+
QVariantMap QgsExtractNodesAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
62+
{
63+
std::unique_ptr< QgsFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
64+
if ( !featureSource )
65+
return QVariantMap();
66+
67+
QgsWkbTypes::Type outputWkbType = QgsWkbTypes::Point;
68+
if ( QgsWkbTypes::hasM( featureSource->wkbType() ) )
69+
{
70+
outputWkbType = QgsWkbTypes::addM( outputWkbType );
71+
}
72+
if ( QgsWkbTypes::hasZ( featureSource->wkbType() ) )
73+
{
74+
outputWkbType = QgsWkbTypes::addZ( outputWkbType );
75+
}
76+
77+
QgsFields outputFields = featureSource->fields();
78+
outputFields.append( QgsField( QStringLiteral( "node_index" ), QVariant::Int, QString(), 10, 0 ) );
79+
outputFields.append( QgsField( QStringLiteral( "distance" ), QVariant::Double, QString(), 20, 6 ) );
80+
outputFields.append( QgsField( QStringLiteral( "angle" ), QVariant::Double, QString(), 20, 6 ) );
81+
82+
QString dest;
83+
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, outputFields, outputWkbType, featureSource->sourceCrs() ) );
84+
if ( !sink )
85+
return QVariantMap();
86+
87+
double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1;
88+
QgsFeatureIterator it = featureSource->getFeatures( QgsFeatureRequest() );
89+
QgsFeature f;
90+
int i = -1;
91+
while ( it.nextFeature( f ) )
92+
{
93+
i++;
94+
if ( feedback->isCanceled() )
95+
{
96+
break;
97+
}
98+
99+
QgsGeometry inputGeom = f.geometry();
100+
if ( inputGeom.isNull() )
101+
{
102+
sink->addFeature( f, QgsFeatureSink::FastInsert );
103+
}
104+
else
105+
{
106+
const QgsCoordinateSequence sequence = inputGeom.constGet()->coordinateSequence();
107+
for ( const QgsRingSequence &part : sequence )
108+
{
109+
int vertexPos = 0;
110+
for ( const QgsPointSequence &ring : part )
111+
{
112+
for ( int j = 0; j < ring.count(); ++ j )
113+
{
114+
double distance = inputGeom.distanceToVertex( vertexPos );
115+
double angle = inputGeom.angleAtVertex( vertexPos ) * 180 / M_PI_2;
116+
QgsAttributes attrs = f.attributes();
117+
attrs << vertexPos
118+
<< distance
119+
<< angle;
120+
QgsFeature outputFeature = QgsFeature();
121+
outputFeature.setAttributes( attrs );
122+
outputFeature.setGeometry( QgsGeometry( ring.at( j ).clone() ) );
123+
sink->addFeature( outputFeature, QgsFeatureSink::FastInsert );
124+
vertexPos++;
125+
}
126+
}
127+
}
128+
}
129+
feedback->setProgress( i * step );
130+
}
131+
132+
QVariantMap outputs;
133+
outputs.insert( QStringLiteral( "OUTPUT" ), dest );
134+
return outputs;
135+
}
136+
137+
///@endcond
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/***************************************************************************
2+
qgsalgorithmextractnodes.h
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+
18+
#ifndef QGSALGORITHMEXTRACTNODES_H
19+
#define QGSALGORITHMEXTRACTNODES_H
20+
21+
#define SIP_NO_FILE
22+
23+
#include "qgis.h"
24+
#include "qgsprocessingalgorithm.h"
25+
26+
///@cond PRIVATE
27+
28+
/**
29+
* Native extract nodes algorithm.
30+
*/
31+
class QgsExtractNodesAlgorithm : public QgsProcessingAlgorithm
32+
{
33+
34+
public:
35+
36+
QgsExtractNodesAlgorithm() = default;
37+
void initAlgorithm( const QVariantMap &configuration = QVariantMap() ) override;
38+
QString name() const override;
39+
QString displayName() const override;
40+
virtual QStringList tags() const override;
41+
QString group() const override;
42+
QString shortHelpString() const override;
43+
QgsExtractNodesAlgorithm *createInstance() const override SIP_FACTORY;
44+
45+
protected:
46+
47+
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
48+
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) override;
49+
50+
};
51+
52+
///@endcond PRIVATE
53+
54+
#endif // QGSALGORITHMEXTRACTNODES_H
55+
56+

‎src/analysis/processing/qgsnativealgorithms.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "qgsalgorithmextractbyexpression.h"
3333
#include "qgsalgorithmextractbyextent.h"
3434
#include "qgsalgorithmextractbylocation.h"
35+
#include "qgsalgorithmextractnodes.h"
3536
#include "qgsalgorithmfiledownloader.h"
3637
#include "qgsalgorithmfixgeometries.h"
3738
#include "qgsalgorithmjoinbyattribute.h"
@@ -106,6 +107,7 @@ void QgsNativeAlgorithms::loadAlgorithms()
106107
addAlgorithm( new QgsExtractByExpressionAlgorithm() );
107108
addAlgorithm( new QgsExtractByExtentAlgorithm() );
108109
addAlgorithm( new QgsExtractByLocationAlgorithm() );
110+
addAlgorithm( new QgsExtractNodesAlgorithm() );
109111
addAlgorithm( new QgsFileDownloaderAlgorithm() );
110112
addAlgorithm( new QgsFixGeometriesAlgorithm() );
111113
addAlgorithm( new QgsJoinByAttributeAlgorithm() );

0 commit comments

Comments
 (0)
Please sign in to comment.