Skip to content
(S)hapefile to(2) (G)raph/network converter in Python
Branch: master
Clone or download
caesar0301 Merge pull request #7 from lobisquit/bugfix
Fixed problematic function
Latest commit e94a5a9 Dec 14, 2018
Type Name Latest commit message Commit time
Failed to load latest commit information.
data Add test cases Dec 15, 2016
s2g Merge pull request #7 from lobisquit/bugfix Dec 14, 2018
tests fix test cases Dec 29, 2016
.gitignore Initial commit Nov 30, 2016
.travis.yml Update .travis.yml Apr 28, 2017
LICENSE Initial commit Nov 30, 2016 Add QA Apr 28, 2017
setup.cfg .travis; update readme Dec 16, 2016 Upgrade to 0.2.7 Aug 5, 2018


(S)hapefile (2) Graph/network converter in Python

Build Status

When we process GIS data, a non-trivial problem is the conversion from shape lines to graph or network data structure. The latter may benefit from these out-of-box graphical libraries such as networkx and igraph. But the conversion is a headache to components open communities. This mostly urges me to finish this tiny but useful library.


Requirements: Python 2.7+ or Python 3.3+

sudo apt-get install python python-pip libgeos-dev

Install s2g,

sudo pip install s2g

Extra utilities to run unittests,

sudo apt-get install python-tk
sudo pip install matplotlib


You have two alternative ways to construct the graph. One is reading from a raw shapefiles with LineString objects. (Under the hood, I involve fiona to read geometries and shapely to analyze the data.). Currently, this tool only supports conversion to undirected graph.

from s2g import ShapeGraph
import networkx as nx

sg = ShapeGraph(shapefile='path/to/roads.shp', to_graph=True)
assert isinstance(sg.graph, nx.Graph)

The other way is designed for programmable usage or time-consuming process where intermediate data could be sniffed or saved. Here is an example to read lines with [fiona]:

from s2g import ShapeGraph
import fiona
from shapely.geometry import shape, LineString

shp = 'path/to/shapefile.shp'

with as source:
    geoms = []
    for r in source:
        s = shape(r['geometry'])
        if isinstance(s, LineString):

# create ShapeGraph object from a list of lines
sg = ShapeGraph(geoms, to_graph=False)

# detect major components
mc = sg.gen_major_components()
# major components are mc[2]

# convert the largest component to networkx Graph
graph = sg.to_networkx()  # equivalently sg.graph

Dive into source doc to discover other functionalities.


  • Why not NetworkX's read_shp function? (Issue)

I endeavored to avoid reinventing the wheel at the beginning. It has several limitations to meet common road network processing:

  1. It is not able to detect the major components when the shapefile has disconneted parts
  2. It has no buffer mechsnisms to determine the connectivities of line-line, line-point or point-point pairs
  3. It does not support parameter controlled sampling of road lines when we convert geometry lines into edges
  4. It has no pesudo edges to fix the disconnectivity of geometry elements


You can’t perform that action at this time.