5.6. Urban Comparison and Network Outputs#
5.6.1. Learning objectives#
By the end of this section, you should be able to:
document a comparison protocol so that cities are compared like with like;
explain how the area rule alone can reverse a ranking of cities;
compare travel modes without treating node and edge counts as quality scores;
associate non-routable features with graph nodes and check the snap;
choose export formats and verify that they round-trip; and
review a graph with a short, repeatable report before presenting a result.
Section goal
Close the chapter by making network results comparable, exportable, and reviewable. Small synthetic networks show what can reverse a comparison or corrupt an export, and the same code then runs on Missouri cities.
5.6.2. Compare like with like#
Network statistics can support an urban comparison, but only when the input choices are controlled. For each city, document the boundary source, retrieval date, query method, network type, simplification, component retention, projection, and area rule. Use the same protocol for every city. Table 5.18 says why each choice must be held constant.
Choice |
Why it must be held constant |
How it drifts |
|---|---|---|
Boundary source |
It decides which land and which streets are inside |
One boundary includes farmland or water, another a built-up core |
Query method and date |
OpenStreetMap is edited continuously |
Cities downloaded months apart |
Network type |
Each type has different inclusion rules |
A walking graph for one city and a driving graph for another |
Simplification and component retention |
Both change every count |
|
Projection |
It sets the metric lengths and areas |
Using a geographic CRS for one city |
Area rule |
It is the denominator of every density |
A hull for one city and a boundary for another |
The area rule is the quietest of these, so the toy below tests it. City A has a compact 9 by 9 grid of 100 m blocks inside a large boundary that includes empty land. City B has a 7 by 7 grid of 150 m blocks inside a tight boundary. Their intersection densities are computed twice, once with the convex hull of the nodes as the area and once with the boundary.
hull km² density boundary km² density
City A 0.64 126.6 3.24 25.0
City B 0.81 60.5 1.00 49.0
denser by the hull rule: City A
denser by the boundary rule: City B
The ranking reverses. City A is the denser city by the hull rule, at 127 intersections per square kilometre against 60, and City B is the denser one by the boundary rule, at 49 against 25, because City A’s boundary holds much empty land. Neither rule is wrong, but a comparison that used one rule for one city and the other for the second would be meaningless, which is why the protocol fixes it. On Missouri cities the loop below applies one protocol to each place. A large city such as Kansas City or St. Louis can take a long time and a lot of memory to download as a walking network, so enable caching and test the loop on a small place first:
The loop stores its results as a list of records. Convert them to a table to read them side by side:
| place | nodes | edges | street_density_km | intersection_density_km | circuity_avg | |
|---|---|---|---|---|---|---|
| 0 | Columbia, Missouri, USA | 32228 | 92112 | 12625.1 | 130.2 | 1.2 |
Normalize counts and lengths by a comparable area when appropriate, but do not reduce walkability or connectivity to a single score without explaining the weighting. Different boundaries and OpenStreetMap completeness can matter as much as urban form.
5.6.3. Compare modes and features#
Driving, walking, and cycling graphs answer different movement questions:
{'walk': {'nodes': 32228, 'edges': 92112}, 'drive': {'nodes': 15000, 'edges': 40000}, 'bike': {'nodes': 25000, 'edges': 70000}}
Raw counts are not quality scores. A walking graph may include paths excluded from a driving graph, and a mode may have incomplete source coverage. Compare structure instead, such as the share of each kind of street, or run the same routing and service-area question on each graph.
OSM features that are not routable can be queried separately. They come back as a table that can mix points, lines, and polygons, since a café may be mapped as a point or as a building outline:
Point 29
Polygon 9
Name: count, dtype: int64
A café, station, or hospital becomes part of an accessibility analysis only after it is associated with a graph node or a network distance. The association has two steps. A polygon first needs one point to stand for it, and the representative point from Chapter 4 is the safe choice because it always lies inside the polygon, unlike a centroid. The point is then snapped to the nearest node, and the snap distance shows whether the feature is actually on the network. The toy below has four cafes on a walking grid: two points, a building footprint, and a point well outside the network.
cafe geometry node snap m note
Corner Point 11 53.9
Bakery Polygon 40 70.7
Roastery Point 30 10.0
Kiosk Point 76 700.0 off the network
Three cafes snap within 71 m, and the kiosk snaps 700 m away to the edge of the grid, so it should be excluded or reported, not counted as served. The polygon needed its representative point before it could be snapped. The same two steps on the Columbia cafes use the walking graph and flag every cafe that snaps more than 100 m away:
cafes: 38 | snapped more than 100 m away: 0
5.6.4. Export graph and spatial representations#
A graph can be saved as spatial layers, as a graph file, or as a table, and each keeps something different. Table 5.19 compares the three.
Format |
Preserves |
Loses or risks |
Use for |
|---|---|---|---|
GeoPackage layers of nodes and edges |
Geometry, attributes, and CRS |
The graph structure, and list-valued attributes become text |
GIS inspection and mapping |
GraphML |
Graph structure, direction, parallel edges, and attribute types |
It is not read directly by GIS software |
Reloading into NetworkX, OSMnx, and other network tools |
Edge list in a table |
|
Geometry, unless saved separately, and the parallel-edge key |
Exchange with non-spatial tools |
OpenStreetMap attributes are not always single values: a street that was merged by
simplification can carry several osmid values, and a street with two names can carry a
list of names. The toy graph below has both, and the cell exports it two ways and reads
each export back.
original graph: 3 nodes, 4 edges
GeoPackage edges: 4 rows, osmid column holds ['[101, 102]', '[101, 102]', '103']
GraphML reload: 3 nodes, 4 edges, MultiDiGraph
GraphML osmid: [101, 102] | length type: float | CRS: EPSG:4326
The GeoPackage holds the four edges as rows, but it cannot hold the graph itself, and its
osmid column is text for any list-valued row. The GraphML file reloads as the same directed
multigraph with the list restored and the lengths still numbers. Attribute writers differ
between library versions: some raise a type error on list or mixed-type columns, which is
why the surrounding text recommends normalizing them, and the OSMnx helper
ox.save_graph_geopackage writes both layers to one file with that conversion done
deliberately. Verify any export by reading it back, as above. The exports for Columbia are:
GeoPackage is convenient for GIS inspection; GraphML preserves graph structure for NetworkX and other network tools. GraphML has stricter attribute serialization rules, so normalize list, dictionary, or mixed-type attributes before exporting if the writer reports a type error. Keep the source query and graph metadata with the exports.
5.6.5. Applications and review questions#
Use network comparisons to investigate questions such as:
Which neighborhoods have fewer reachable destinations within a walking threshold?
Which edges are potential bottlenecks under a chosen cost?
How does a new facility change service coverage?
Which differences persist when the boundary, mode, or threshold changes?
Before presenting a result, review node and edge counts, connected components, route success, units, source coverage, and the assumptions that make cities comparable. Table 5.20 turns that list into a checklist that draws on the whole chapter.
Item |
What to check |
Introduced in |
|---|---|---|
Node and edge counts |
A plausible size, produced by the same protocol for every graph |
S01 |
Connected components |
The share of nodes in the largest weak and strong component |
S02 |
Units and projection |
Metres from a projected graph, with the area rule stated |
S03 |
Route success |
The share of origin and destination pairs that connect, and the snap distances |
S04 |
Service-area representation |
Which representation, buffer distance, and walking speed were used |
S05 |
Source coverage |
OpenStreetMap completeness, retrieval date, and licence |
S01 |
Most of the first four rows can be produced by one function, which makes the review repeatable. The cell below runs it on a toy graph with a two-node island attached.
nodes 83
edges 290
weak components 2
largest weak share 0.976
strong components 2
largest strong share 0.976
one-way share 0.0
total length (km) 29.0
edges without length 0
The island splits the graph into two weak components, and the largest holds 97.6% of the nodes.
A comparison made with retain_all=True would carry such islands into every statistic,
which is another reason the protocol fixes component retention. The same report on the
Columbia graph is:
nodes 32228
edges 92112
weak components 1
largest weak share 1.0
strong components 1
largest strong share 1.0
one-way share 0.0
total length (km) 5122.9
edges without length 0
5.6.6. Summary#
Urban network comparisons are reproducible only when query, mode, boundary, and metric choices are held constant, and the area rule alone can reverse a ranking. Keep graph and spatial exports together and verify them by reading them back, distinguish routable networks from nearby features and check how far each feature snaps from the graph, and run a repeatable review before reporting uncertainty from source coverage and model assumptions.