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() );
112 multiFeedback.setStepWeights( { 80, 20 } );
113 multiFeedback.setCurrentStep( 0 );
115 loadCommonParams( parameters, context, &multiFeedback );
117 const int definition = parameterAsEnum( parameters, u
"ENDPOINT_DEFINITION"_s, context );
120 outFields.
append(
QgsField( u
"node_id"_s, QMetaType::Type::Int ) );
123 std::unique_ptr<QgsFeatureSink> sink( parameterAsSink( parameters, u
"OUTPUT"_s, context, dest, outFields,
Qgis::WkbType::Point, mNetwork->sourceCrs() ) );
127 multiFeedback.pushInfo( QObject::tr(
"Building graph…" ) );
128 QVector<QgsPointXY> snappedPoints;
129 mDirector->makeGraph( mBuilder.get(), {}, snappedPoints, &multiFeedback );
130 if ( multiFeedback.isCanceled() )
133 multiFeedback.setCurrentStep( 1 );
134 multiFeedback.pushInfo( QObject::tr(
"Calculating endpoints…" ) );
135 std::unique_ptr<QgsGraph> graph( mBuilder->takeGraph() );
137 const int vertexCount = graph->vertexCount();
138 double step = vertexCount > 0 ? 20.0 / vertexCount : 1;
139 long endpointsFound = 0;
141 for (
int i = 0; i < vertexCount; ++i )
143 if ( multiFeedback.isCanceled() )
147 bool isEndPoint =
false;
149 if ( definition == 0 )
154 if ( ( hasIncoming && !hasOutgoing ) || ( hasOutgoing && !hasIncoming ) )
163 QSet<int> adjacentNodeIndices;
166 adjacentNodeIndices.insert( graph->edge( edgeId ).toVertex() );
170 adjacentNodeIndices.insert( graph->edge( edgeId ).fromVertex() );
172 if ( adjacentNodeIndices.count() == 1 )
190 multiFeedback.setProgress( i * step );
194 multiFeedback.pushInfo( QObject::tr(
"Found %1 end points." ).arg( endpointsFound ) );
198 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.