Skip to main content
useless comment deleted
Source Link
Detlev
  • 4.7k
  • 19
  • 26

You can use Python module networkx for this.

The following script reads the polyline layers and creates an undirected graph. Networkx function connected_component_subgraphs() determines to which component each edge belongs to. Then all edges are written to a dict with feature id as key and component id as value. So duplicates are automatically removed. Last step is to write this dict to csv file.

You can load this csv file are join it on fid with your road network, and use categorical or rues based renderer to symbolize according comp_id.

import networkx as nx
import csv

# get the network
aLayer = qgis.utils.iface.activeLayer()
G = nx.Graph()

# construct undirected graph
for feat in aLayer.getFeatures():
    line = feat.geometry().asPolyline()
    for i in range(len(line)-1):
        G.add_edges_from([((line[i][0], line[i][1]), (line[i+1][0], line[i+1][1]), 
                          {'fid': feat.id()})])

# evaluate on connected components
connected_components = list(nx.connected_component_subgraphs(G))
# print connected_components

# gather edges and components to which they belong
fid_comp = {}
for i, graph in enumerate(connected_components):
   for edge in graph.edges_iter(data=True):
       fid_comp[edge[2].get('fid', None)] = i
    
# write output to csv file
with open('E:/Temp/Components.csv', 'wb') as f:
    w = csv.DictWriter(f, fieldnames=['fid', 'comp_id'])
    w.writeheader()
    for row in fid_comp.items():
        w.writerow({'fid': row[0], 'comp_id': row[1]})

The test case (hint: line 10 overlaps line 5):

enter image description here

Resulting file Components.csv:

fid,comp_id
1,0
2,0
3,0
4,0
5,0
6,0
7,1
8,1
9,1
10,2

You can use Python module networkx for this.

The following script reads the polyline layers and creates an undirected graph. Networkx function connected_component_subgraphs() determines to which component each edge belongs to. Then all edges are written to a dict with feature id as key and component id as value. So duplicates are automatically removed. Last step is to write this dict to csv file.

You can load this csv file are join it on fid with your road network, and use categorical or rues based renderer to symbolize according comp_id.

import networkx as nx
import csv

# get the network
aLayer = qgis.utils.iface.activeLayer()
G = nx.Graph()

# construct undirected graph
for feat in aLayer.getFeatures():
    line = feat.geometry().asPolyline()
    for i in range(len(line)-1):
        G.add_edges_from([((line[i][0], line[i][1]), (line[i+1][0], line[i+1][1]), 
                          {'fid': feat.id()})])

# evaluate on connected components
connected_components = list(nx.connected_component_subgraphs(G))
# print connected_components

# gather edges and components to which they belong
fid_comp = {}
for i, graph in enumerate(connected_components):
   for edge in graph.edges_iter(data=True):
       fid_comp[edge[2].get('fid', None)] = i
    
# write output to csv file
with open('E:/Temp/Components.csv', 'wb') as f:
    w = csv.DictWriter(f, fieldnames=['fid', 'comp_id'])
    w.writeheader()
    for row in fid_comp.items():
        w.writerow({'fid': row[0], 'comp_id': row[1]})

The test case (hint: line 10 overlaps line 5):

enter image description here

Resulting file Components.csv:

fid,comp_id
1,0
2,0
3,0
4,0
5,0
6,0
7,1
8,1
9,1
10,2

You can use Python module networkx for this.

The following script reads the polyline layers and creates an undirected graph. Networkx function connected_component_subgraphs() determines to which component each edge belongs to. Then all edges are written to a dict with feature id as key and component id as value. So duplicates are automatically removed. Last step is to write this dict to csv file.

You can load this csv file are join it on fid with your road network, and use categorical or rues based renderer to symbolize according comp_id.

import networkx as nx
import csv

# get the network
aLayer = qgis.utils.iface.activeLayer()
G = nx.Graph()

# construct undirected graph
for feat in aLayer.getFeatures():
    line = feat.geometry().asPolyline()
    for i in range(len(line)-1):
        G.add_edges_from([((line[i][0], line[i][1]), (line[i+1][0], line[i+1][1]), 
                          {'fid': feat.id()})])

# evaluate on connected components
connected_components = list(nx.connected_component_subgraphs(G))

# gather edges and components to which they belong
fid_comp = {}
for i, graph in enumerate(connected_components):
   for edge in graph.edges_iter(data=True):
       fid_comp[edge[2].get('fid', None)] = i
    
# write output to csv file
with open('E:/Temp/Components.csv', 'wb') as f:
    w = csv.DictWriter(f, fieldnames=['fid', 'comp_id'])
    w.writeheader()
    for row in fid_comp.items():
        w.writerow({'fid': row[0], 'comp_id': row[1]})

The test case (hint: line 10 overlaps line 5):

enter image description here

Resulting file Components.csv:

fid,comp_id
1,0
2,0
3,0
4,0
5,0
6,0
7,1
8,1
9,1
10,2
Source Link
Detlev
  • 4.7k
  • 19
  • 26

You can use Python module networkx for this.

The following script reads the polyline layers and creates an undirected graph. Networkx function connected_component_subgraphs() determines to which component each edge belongs to. Then all edges are written to a dict with feature id as key and component id as value. So duplicates are automatically removed. Last step is to write this dict to csv file.

You can load this csv file are join it on fid with your road network, and use categorical or rues based renderer to symbolize according comp_id.

import networkx as nx
import csv

# get the network
aLayer = qgis.utils.iface.activeLayer()
G = nx.Graph()

# construct undirected graph
for feat in aLayer.getFeatures():
    line = feat.geometry().asPolyline()
    for i in range(len(line)-1):
        G.add_edges_from([((line[i][0], line[i][1]), (line[i+1][0], line[i+1][1]), 
                          {'fid': feat.id()})])

# evaluate on connected components
connected_components = list(nx.connected_component_subgraphs(G))
# print connected_components

# gather edges and components to which they belong
fid_comp = {}
for i, graph in enumerate(connected_components):
   for edge in graph.edges_iter(data=True):
       fid_comp[edge[2].get('fid', None)] = i
    
# write output to csv file
with open('E:/Temp/Components.csv', 'wb') as f:
    w = csv.DictWriter(f, fieldnames=['fid', 'comp_id'])
    w.writeheader()
    for row in fid_comp.items():
        w.writerow({'fid': row[0], 'comp_id': row[1]})

The test case (hint: line 10 overlaps line 5):

enter image description here

Resulting file Components.csv:

fid,comp_id
1,0
2,0
3,0
4,0
5,0
6,0
7,1
8,1
9,1
10,2