3

I have a polyline shapefile for a road network. The roads are split at every intersection (node), e.g. if two roads intersect at one point, then they are split into four links(edges). So using the attribute table of the shapefile, I know this shapefile has 600 edges. But when the shapefile is read in nx_spatial, total edges found is only 497. I would like to know why it is missing other 103 road links (edges). Thanks

import nx_spatial as ns     
roads = ns.read_shp(path)   #path = path to polyline shapefile
roads.number_of_edges()     #output = 497

Hope these info helps: Windows7, Python 2.7 Anaconda 64bit, Eclipse. The problem is related to nx_spatial. But I could not create such tag for low reputation.

1 Answer 1

5

This has nothing to do with your Python version or your os.

The Python Networkx module (nx_spatial is very old, use directly NetworkX: read_shp) do not cut the lines at each intersection and simplify the line geometries into start and end coordinates.

Generates a networkx.DiGraph from shapefiles. Point geometries are translated into nodes, lines into edges. Coordinate tuples are used as keys. Attributes are preserved, line geometries are simplified into start and end coordinates. Accepts a single shapefile or directory of many shapefiles.

Example:

enter image description here

number of features:

import fiona
features = fiona.open('test.shp')
print len(features)
5
for feat in features:
    print feat['geometry']

{'type': 'LineString', 'coordinates': [(3.0, 2.0), (2.0, 3.0), (2.0, 4.0)]}
{'type': 'LineString', 'coordinates': [(1.0, 2.0), (2.0, 3.0), (3.0, 4.0)]}
{'type': 'LineString', 'coordinates': [(2.0, 1.0), (3.0, 2.0), (4.0, 2.0), (4.0, 4.0)]}
{'type': 'LineString', 'coordinates': [(1.0, 1.0), (2.0, 1.0), (3.0, 1.0)]}
{'type': 'LineString', 'coordinates': [(0.0, 0.0), (1.0, 1.0), (1.0, 2.0), (1.0, 4.0)]}

number of nodes and edges:

import networkx as nx
G = nx.read_shp('test.shp')
print G.nodes()
[(1.0, 2.0), (3.0, 2.0), (3.0, 1.0), (4.0, 4.0), (2.0, 1.0), (1.0, 1.0), (0.0, 0.0), (1.0, 4.0), (3.0, 4.0), (2.0, 4.0)]
print len(G.nodes())
10
print G.edges()
[((1.0, 2.0), (3.0, 4.0)), ((3.0, 2.0), (2.0, 4.0)), ((2.0, 1.0), (4.0, 4.0)), ((1.0, 1.0), (3.0, 1.0)), ((0.0, 0.0), (1.0, 4.0))]
print len(G.edges())
5 

Edges of the G graph:

enter image description here

What you want is a Planar Graph:

In graph theory, a planar graph is a graph that can be embedded in the plane, i.e., it can be drawn on the plane in such a way that its edges intersect only at their endpoints. In other words, it can be drawn in such a way that no edges cross each other.

Result with a Planar Graph algorithm (unfortunately, the NetworkX module do not support Planar Graph)

enter image description here

 features = fiona.open('test_Arc.shp')
 len(features)
 11
 for feat in features:
     print feat['geometry']

 {'type': 'LineString', 'coordinates': [(0.0, 0.0), (1.0, 1.0)]}
 {'type': 'LineString', 'coordinates': [(1.0, 1.0), (2.0, 1.0)]}
 {'type': 'LineString', 'coordinates': [(1.0, 1.0), (1.0, 2.0)]}
 {'type': 'LineString', 'coordinates': [(1.0, 2.0), (2.0, 3.0)]}
 {'type': 'LineString', 'coordinates': [(1.0, 2.0), (1.0, 4.0)]}
 {'type': 'LineString', 'coordinates': [(2.0, 1.0), (3.0, 1.0)]}
 {'type': 'LineString', 'coordinates': [(2.0, 1.0), (3.0, 2.0)]}
 {'type': 'LineString', 'coordinates': [(2.0, 3.0), (3.0, 4.0)]}
 {'type': 'LineString', 'coordinates': [(2.0, 3.0), (2.0, 4.0)]}
 {'type': 'LineString', 'coordinates': [(3.0, 2.0), (2.0, 3.0)]}
 {'type': 'LineString', 'coordinates': [(3.0, 2.0), (4.0, 2.0), (4.0, 4.0)]}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.