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
67 return QObject::tr(
"This algorithm extracts the end points (nodes) from a network line layer.\n\n"
68 "Two definitions are available for identifying end points:\n\n"
69 "1. Nodes with only all incoming or all outgoing edges: Identifies 'Source' or 'Sink' nodes "
70 "based on the direction of flow. These are nodes where flow can start (only outgoing) or stop "
72 "2. Nodes connected to a single edge: Identifies topological 'dead-ends' or 'dangles', regardless "
73 "of directionality. This checks if the node is connected to only one other distinct node." );
76QgsExtractNetworkEndpointsAlgorithm *QgsExtractNetworkEndpointsAlgorithm::createInstance()
const
78 return new QgsExtractNetworkEndpointsAlgorithm();
88void QgsExtractNetworkEndpointsAlgorithm::initAlgorithm(
const QVariantMap & )
93 removeParameter( u
"STRATEGY"_s );
94 removeParameter( u
"SPEED_FIELD"_s );
95 removeParameter( u
"DEFAULT_SPEED"_s );
97 QStringList definitions;
98 definitions << QObject::tr(
"Extract Nodes with only All Incoming or All Outgoing Edges" )
99 << QObject::tr(
"Extract Nodes Connected to a Single Edge" );
101 auto strategyParam = std::make_unique<QgsProcessingParameterEnum>( u
"ENDPOINT_DEFINITION"_s, QObject::tr(
"End point definition" ), definitions,
false, 1 );
102 addParameter( strategyParam.release() );
105 addParameter( outputPoints.release() );
111 multiFeedback.setStepWeights( { 80, 20 } );
112 multiFeedback.setCurrentStep( 0 );
114 loadCommonParams( parameters, context, &multiFeedback );
116 const int definition = parameterAsEnum( parameters, u
"ENDPOINT_DEFINITION"_s, context );
119 outFields.
append(
QgsField( u
"node_id"_s, QMetaType::Type::Int ) );
122 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u
"OUTPUT"_s, context, dest, outFields,
Qgis::WkbType::Point, mNetwork->sourceCrs() ) );
126 multiFeedback.pushInfo( QObject::tr(
"Building graph…" ) );
127 QVector<QgsPointXY> snappedPoints;
128 mDirector->makeGraph( mBuilder.get(), {}, snappedPoints, &multiFeedback );
129 if ( multiFeedback.isCanceled() )
132 multiFeedback.setCurrentStep( 1 );
133 multiFeedback.pushInfo( QObject::tr(
"Calculating endpoints…" ) );
134 std::unique_ptr<QgsGraph> graph( mBuilder->takeGraph() );
136 const int vertexCount = graph->vertexCount();
137 double step = vertexCount > 0 ? 20.0 / vertexCount : 1;
138 long endpointsFound = 0;
140 for (
int i = 0; i < vertexCount; ++i )
142 if ( multiFeedback.isCanceled() )
146 bool isEndPoint =
false;
148 if ( definition == 0 )
153 if ( ( hasIncoming && !hasOutgoing ) || ( hasOutgoing && !hasIncoming ) )
162 QSet<int> adjacentNodeIndices;
165 adjacentNodeIndices.insert( graph->edge( edgeId ).toVertex() );
169 adjacentNodeIndices.insert( graph->edge( edgeId ).fromVertex() );
171 if ( adjacentNodeIndices.count() == 1 )
189 multiFeedback.setProgress( i * step );
193 multiFeedback.pushInfo( QObject::tr(
"Found %1 end points." ).arg( endpointsFound ) );
197 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.