A while ago I worked on a project that analysed the road networks in a number of towns and cities in England. Initially, we used the Ordnance Survey’s Integrated Transport Network (ITN). The process to extract an ITN network for a specific town was as follows:
- Using Digimap, extract the ITN network for a bounding box around the specific town.
- Extract the boundary polygon for the town and then trim the network to that polygon
- Tidy the road network – removing nodes (junctions) without edges (links), edges without a node at either end and disconnected islands. Fortunately, these tasks can be carried out within QGIS.
As you can imagine, this process is time-consuming and it limited the number of towns that we could analyse.
Since then OSMNX has been released and it promises:
- the automated downloading of political boundaries
- downloading and constructing of street network data from OpenStreetMap
- the algorithmic correction of network topology
- the ability to save street networks to disk as shapefiles
- the ability to analyze street networks, including calculating routes, projecting and visualizing networks, and calculating metric and topological measures (Boeing, 2017)
The first iteration of the code used OSMNX’s graph_from_place method, which takes, as a parameter, the name of the place of interest, in the format:
Blackpool,United Kingdom Bournemouth,United Kingdom Bristol,United Kingdom
This raises two problems. Firstly, the call to the OSM Nominatem does not always yield a polygon, which graph_from_place requires, but a point. This can be seen by typing Blackpool, United Kingdom into OSM’s search box:
Clicking the first result returns a point, and the second result a polygon. This can be solved by trapping the error and using the which_result=2 parameter value for graph_from_place if the first attempt fails.
The second issue is less easily soluble; many of the OSM boundaries do not match the town’s limits. Consider the neighbouring towns of Harrogate and York:
Here OSM has used the local authority’s boundaries for each of the two towns rather than the urban extent. This was a common occurance amongst many of the towns investigated. Clearly a different set of town boundaries is required.
One solution is to to use the ONS Major Towns and Cities (December 2015) Boundaries. This dataset provides a better match to the built-up areas; for example, with Harrogate:
… and York:
Now that we have a usable set of boundaries we can extract the OSM networks for the towns and cities.
We can supply these boundaries to the OSMNX method graph_from_polygon method but the polygons need to be in lat/lng co-ordinates (specifically EPSG 4326). The output of the script is a dictionary containing the basic statistics for each town’s road network, which is pickled and can be unpickled for examination.
The Python script:
- Reads the town ONS boundaries from a Shapefile
- Convert the boundaries to a EPSG 4326 reference system
- For each town boundary
- get the geometry for the boundary
- extract the network for that geometry (graph_from_polygon)
- save the network(graph) as graphML format
- save the network’s nodes and edges as Shapefiles in OSGB (EPSG 27700) reference system (note that this is not particularly straightforward – see the script for more details).
- add the network’s basic statistics to a dictionary
- Pickle the statistics dictionary to a file
Some issues still remain; consider Barnsley below, where the town is split by a river, and the OSM network gets disconnected.
To process all 112 towns in the ONS dataset, using my laptop, took approximately 100 minutes.