31using namespace Qt::StringLiterals;
35QString QgsExtractNetworkEndpointsAlgorithm::name()
const
37 return u
"extractnetworkendpoints"_s;
40QString QgsExtractNetworkEndpointsAlgorithm::displayName()
const
42 return QObject::tr(
"Extract network end points" );
45QStringList QgsExtractNetworkEndpointsAlgorithm::tags()
const
47 return QObject::tr(
"network,dead,end,node,degree,terminal,dangle" ).split(
',' );
50QIcon QgsExtractNetworkEndpointsAlgorithm::icon()
const
55QString QgsExtractNetworkEndpointsAlgorithm::svgIconPath()
const
60QString QgsExtractNetworkEndpointsAlgorithm::shortDescription()
const
62 return QObject::tr(
"Extracts the end points (nodes) from a network line layer." );
65QString QgsExtractNetworkEndpointsAlgorithm::shortHelpString()
const
68 "This algorithm extracts the end points (nodes) from a network line layer.\n\n"
69 "Two definitions are available for identifying end points:\n\n"
70 "1. Nodes with only all incoming or all outgoing edges: Identifies 'Source' or 'Sink' nodes "
71 "based on the direction of flow. These are nodes where flow can start (only outgoing) or stop "
73 "2. Nodes connected to a single edge: Identifies topological 'dead-ends' or 'dangles', regardless "
74 "of directionality. This checks if the node is connected to only one other distinct node."
78QgsExtractNetworkEndpointsAlgorithm *QgsExtractNetworkEndpointsAlgorithm::createInstance()
const
80 return new QgsExtractNetworkEndpointsAlgorithm();
90void QgsExtractNetworkEndpointsAlgorithm::initAlgorithm(
const QVariantMap & )
95 removeParameter( u
"STRATEGY"_s );
96 removeParameter( u
"SPEED_FIELD"_s );
97 removeParameter( u
"DEFAULT_SPEED"_s );
99 QStringList definitions;
100 definitions << QObject::tr(
"Extract Nodes with only All Incoming or All Outgoing Edges" ) << QObject::tr(
"Extract Nodes Connected to a Single Edge" );
102 auto strategyParam = std::make_unique<QgsProcessingParameterEnum>( u
"ENDPOINT_DEFINITION"_s, QObject::tr(
"End point definition" ), definitions,
false, 1 );
103 addParameter( strategyParam.release() );
106 addParameter( outputPoints.release() );
111 QGS_MARK_ALGORITHM_SOURCE
114 multiFeedback.setStepWeights( { 80, 20 } );
115 multiFeedback.setCurrentStep( 0 );
117 loadCommonParams( parameters, context, &multiFeedback );
119 const int definition = parameterAsEnum( parameters, u
"ENDPOINT_DEFINITION"_s, context );
122 outFields.
append(
QgsField( u
"node_id"_s, QMetaType::Type::Int ) );
125 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u
"OUTPUT"_s, context, dest, outFields,
Qgis::WkbType::Point, mNetwork->sourceCrs() ) );
129 multiFeedback.pushInfo( QObject::tr(
"Building graph…" ) );
130 QVector<QgsPointXY> snappedPoints;
131 mDirector->makeGraph( mBuilder.get(), {}, snappedPoints, &multiFeedback );
132 if ( multiFeedback.isCanceled() )
135 multiFeedback.setCurrentStep( 1 );
136 multiFeedback.pushInfo( QObject::tr(
"Calculating endpoints…" ) );
137 std::unique_ptr<QgsGraph> graph( mBuilder->takeGraph() );
139 const int vertexCount = graph->vertexCount();
140 double step = vertexCount > 0 ? 20.0 / vertexCount : 1;
141 long endpointsFound = 0;
143 for (
int i = 0; i < vertexCount; ++i )
145 if ( multiFeedback.isCanceled() )
149 bool isEndPoint =
false;
151 if ( definition == 0 )
156 if ( ( hasIncoming && !hasOutgoing ) || ( hasOutgoing && !hasIncoming ) )
165 QSet<int> adjacentNodeIndices;
168 adjacentNodeIndices.insert( graph->edge( edgeId ).toVertex() );
172 adjacentNodeIndices.insert( graph->edge( edgeId ).fromVertex() );
174 if ( adjacentNodeIndices.count() == 1 )
192 multiFeedback.setProgress( i * step );
196 multiFeedback.pushInfo( QObject::tr(
"Found %1 end points." ).arg( endpointsFound ) );
200 outputs.insert( u
"OUTPUT"_s, dest );
@ VectorPoint
Vector point layers.
QFlags< ProcessingAlgorithmDocumentationFlag > ProcessingAlgorithmDocumentationFlags
Flags describing algorithm behavior for documentation purposes.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static QString iconPath(const QString &iconFile)
Returns path to the desired icon file.
@ FastInsert
Use faster inserts, at the cost of updating the passed features to reflect changes made at the provid...
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
void setProgress(double progress)
Sets the current progress for the feedback object.
Encapsulate a field in an attribute table or data source.
Container of fields for a vector layer.
bool append(const QgsField &field, Qgis::FieldOrigin origin=Qgis::FieldOrigin::Provider, int originIndex=-1)
Appends a field.
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
Represents vertex in a graph.
QgsGraphEdgeIds outgoingEdges() const
Returns outgoing edge ids, i.e.
QgsGraphEdgeIds incomingEdges() const
Returns the incoming edge ids, i.e.
QgsPointXY point() const
Returns point associated with graph vertex.
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.
Processing feedback object for multi-step operations.