a-b-street / osm2streets

Convert OSM to street networks with detailed geometry
https://a-b-street.github.io/osm2streets
Apache License 2.0
93 stars 7 forks source link

Feeding a/b streets decomposition/disaggregation of centrelines into other analytical tools #214

Open jamiedtor opened 1 year ago

jamiedtor commented 1 year ago

What a great piece of software! We've been using a combination of a/b streets and open-source routing software to conduct analyses to inform scenarios for active-transport-forward future street-network design. I'm wondering about using a/b street's "decomposed" network representation more directly in other software, such as OTP or R5. Since a/b is able to interpret the attributes associated with the OSM centreline links--splitting them into indvidual unidirectional vehicle lanes, sidewalks and bike lanes, etc.--I'm wondering if that output could be exported or saved into a format that could be directly used as a network by other routing software. In essence, is it possible to use a/b street to systematically disaggregate OSM centrelines into their component parts to, say, split a dual-carriageway into two separate directional lanes?

dabreegster commented 1 year ago

Hi, great to hear it's been helpful! https://github.com/a-b-street/osm2streets (https://osm2streets.org as a quick frontend to try it) is A/B Street's OSM importer, split into a separate library. (So I'll transfer the issue there.)

We could certainly transform a StreetNetwork into another format. I don't know much about OTP or R5; is it designed to take individual lanes and movements between lanes? Or does it assume multi-lane roads?

jamiedtor commented 1 year ago

Very cool! This does work nicely.

In our particular use case, we're editing an osm .pbf in JOSM and then using OTP to route origin-destination pairs over that network (represented by default as a single centreline with attributes for directionality, number of lanes, etc.). For our subsequent analysis, we then sum the number of routes--which have a weighting attribute representing--that overlap on each network segment (essentially a spatial join) to identify aggregate demand. The problem is that that only allows us to see aggregated bi-directional demand. So, for example, if we have a single bi-directional street segment with one lane serving each direction, we might know the total number of passing vehicles, but we don't know how that demand is split (400 in each direction, or 200 in one and 600 in other).

To get around this, we can manually separate a bi-directional street into two separate lines representing each direction of travel (with the corresponding number of lanes), as we've done with Queen Street in the image below. But over large study areas, this manual approach takes an enormous amount of time.

image

We we were wondering if we could leverage osm2streets' ability to read the single link "line" and create a "disaggregated" representation to programmatically split each bi-directional segment into two parallel unidirectional segments (preserving the info we need to estimate hourly capacity (number of lanes and speed) and then save it out to an OSM .pbf or .xml which we could use for routing with OTP. For example, if we had a five-lane east-west street with two lanes in one direction and three in the other, we could use osm2streets to generate an OSM .pbf or .xml that represented the street as two parallel, unidirectional lines, one with a lane attribute value of 2 and the other of 3.

Does that sound like a potentially possible output?

I guess one other consideration would be making sure that the nodes representing the intersections of intervening streets were all preserved/duplicated, so that an intersection that in situations where right and left-turn movements are permitted, routing would still be possible.

dabreegster commented 1 year ago

The process you're following sounds suspiciously similar to overline, so CC @Robinlovelace as FYI.

The most straightforward solution would be to make your summation process track direction, and not have to bother with any OSM modifications at all. I'm assuming OTP returns a LineString with the correct orientation, and there's something about your aggregation process that makes it tough to remember direction?

One complication to using osm2streets is that it doesn't yet output .osm, only read it in. That would be something useful we could add, though. Would you be picky about retaining original node and way IDs?

Another complication is that osm2streets reasons about entire roads or individual lanes, but not half-roads. It sounds like what you need would be a new conversion / view on top of our internal StreetNetwork structure. Making sure that transformation propagates turn restrictions (at the lane level, individual ways, sequence of ways, etc) could get tricky...

Robinlovelace commented 1 year ago

Agreed, this is very similar to what we set-out to do with overline(). Main use case it was developed for: the route network layer in tools like the Propensity to Cycle Tool hosted at www.pct.bike and this work-in-progress tool for Scotland: https://www.npt.scot

Our work simplifies the data and completely ignores direction, counting the number of trips (or other attributes) in either direction to provide only one way and set of values per segment. There are some issues with our implementation and, as we're discovering, it's not feature complete.

jamiedtor commented 1 year ago

@Robinlovelace , stplannr is great! We've actually been using overline() for part of our aggregation. I'm wondering if there's a way to adjust the function to preserve direction across the segment. That would definitely be easier than the approach we'd considered to directly edit the osm.pbf to essentially split into uni-directional ways.

dabreegster commented 1 year ago

We're working on a new implementation of overline currently. At the moment, it always preserves direction; we'll make it optional in the future. The implementation is at https://github.com/actenglabs/overline/tree/master/rust, but it's untested and probably not ready for general use yet

Robinlovelace commented 1 year ago

Wow, great to hear there is a use case for this additional functionality! There are various reasons to port the functionality to Rust, you've just bumped this up the priority list... Will sync with Dustin on more tests today...