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.
Answer
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:
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:
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)
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)]}
No comments:
Post a Comment