13.4 Nodes
Nodes are points. Broadly are two main types of transport nodes:
- Origins and destinations such as houses and workplaces
- Intersections between pathways (junctions) and points for entering or exiting a transport network such as bus stops and train stations
The network then consists of edges and nodes.
A common barrier preventing people from switching away from cars for commuting to work is that the distance from home to work is too far to walk or cycle. Public transport can reduce this barrier by providing a fast and high-volume option for common routes into cities. From an active travel perspective, public transport ‘legs’ of longer journeys divide trips into three:
- The origin leg, typically from residential areas to public transport stations
- The public transport leg, which typically goes from the station nearest a trip’s origin to the station nearest its destination
- The destination leg, from the station of alighting to the destination
Public transport nodes can be used to construct three-part desire lines for trips that can be taken by bus and rail.
Let’s look at rail:
= dplyr::slice_max(desire_lines, n = 10, order_by = train) desire_rail
three stages: - matrix creation (of origins, destinations and the ‘via’ points representing rail stations), - identification of nearest neighbors - conversion to multilinestrings.
Using the stplanr
line_via()
function
<- line_via(desire_rail, bristol_stations)) (desire_rail
## Simple feature collection with 10 features and 8 fields
## Active geometry column: geometry
## Geometry type: LINESTRING
## Dimension: XY
## Bounding box: xmin: -2.785131 ymin: 51.40862 xmax: -2.536041 ymax: 51.53713
## Geodetic CRS: WGS 84
## o d all bicycle foot car_driver train Active
## 1 E02003104 E02006887 143 6 1 57 58 4.895105
## 2 E02003106 E02006887 221 8 3 113 54 4.977376
## 3 E02003072 E02006887 163 3 2 75 49 3.067485
## 4 E02003073 E02006887 144 7 0 65 46 4.861111
## 5 E02003098 E02006887 192 4 2 102 45 3.125000
## 6 E02006887 E02003106 147 13 6 59 42 12.925170
## 7 E02003106 E02003043 365 24 5 176 41 7.945205
## 8 E02003107 E02006887 181 20 9 70 38 16.022099
## 9 E02003101 E02006887 210 10 2 131 36 5.714286
## 10 E02003075 E02006887 139 10 1 74 34 7.913669
## geometry leg_orig
## 1 LINESTRING (-2.551731 51.52... LINESTRING (-2.551731 51.52...
## 2 LINESTRING (-2.536041 51.50... LINESTRING (-2.536041 51.50...
## 3 LINESTRING (-2.785131 51.42... LINESTRING (-2.785131 51.42...
## 4 LINESTRING (-2.754764 51.42... LINESTRING (-2.754764 51.42...
## 5 LINESTRING (-2.546061 51.53... LINESTRING (-2.546061 51.53...
## 6 LINESTRING (-2.578791 51.45... LINESTRING (-2.578791 51.45...
## 7 LINESTRING (-2.536041 51.50... LINESTRING (-2.536041 51.50...
## 8 LINESTRING (-2.573264 51.51... LINESTRING (-2.573264 51.51...
## 9 LINESTRING (-2.55124 51.532... LINESTRING (-2.55124 51.532...
## 10 LINESTRING (-2.71725 51.408... LINESTRING (-2.71725 51.408...
## leg_via leg_dest
## 1 LINESTRING (-2.562345 51.52... LINESTRING (-2.579529 51.44...
## 2 LINESTRING (-2.542979 51.51... LINESTRING (-2.579529 51.44...
## 3 LINESTRING (-2.74969 51.419... LINESTRING (-2.579529 51.44...
## 4 LINESTRING (-2.74969 51.419... LINESTRING (-2.579529 51.44...
## 5 LINESTRING (-2.562345 51.52... LINESTRING (-2.579529 51.44...
## 6 LINESTRING (-2.579529 51.44... LINESTRING (-2.542979 51.51...
## 7 LINESTRING (-2.542979 51.51... LINESTRING (-2.605539 51.44...
## 8 LINESTRING (-2.563826 51.50... LINESTRING (-2.579529 51.44...
## 9 LINESTRING (-2.562345 51.52... LINESTRING (-2.579529 51.44...
## 10 LINESTRING (-2.74969 51.419... LINESTRING (-2.579529 51.44...
Note each of the legs
<- st_centroid(zones_od) zone_cents
## Warning: st_centroid assumes attributes are constant over geometries
## Warning in st_centroid.sfc(st_geometry(x), of_largest_polygon =
## of_largest_polygon): st_centroid does not give correct centroids for
## longitude/latitude data
<- zone_cents[desire_rail, ] zone_cents_rail
## although coordinates are longitude/latitude, st_intersects assumes that they
## are planar
<- tmaptools::bb(desire_rail, ext = 1.1)
bb
= rbind(
desire_rail_plot st_sf(data.frame(Geometry = "Desire line (original)"), geometry = desire_rail$geometry),
st_sf(data.frame(Geometry = "Leg 1 (origin to station)"), geometry = desire_rail$leg_orig),
st_sf(data.frame(Geometry = "Leg 2 (station to station)"), geometry = desire_rail$leg_via),
st_sf(data.frame(Geometry = "Leg 3 (station to destination)"), geometry = desire_rail$leg_dest)
)
= desire_rail_plot |>
desire_rail_plot mutate(lty = case_when(Geometry == "Desire line (original)" ~ 2, TRUE ~ 1)) |>
mutate(size = case_when(Geometry == "Desire line (original)" ~ 1, TRUE ~ 2))
= rbind(
bristol_rail_points st_sf(data.frame(
Node = "Origin and destination locations",
col = "black"
geometry = zone_cents_rail$geometry),
), st_sf(data.frame(
Node = "Public transport node",
col = "red"
geometry = bristol_stations$geometry)
),
)
tm_shape(desire_rail_plot, bbox = bb) +
tm_lines(col = "Geometry", palette = "Set2", lwd = "size", scale = 3, legend.lwd.show = FALSE) +
tm_shape(bristol_rail_points) +
tm_dots(col = "col", size = 0.05) +
tm_scale_bar()