-
Notifications
You must be signed in to change notification settings - Fork 0
Improve lane column logic in street exporter using additional OSM metadata #186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve lane column logic in street exporter using additional OSM metadata #186
Conversation
|
Two remaining items that we still might consider before I merge here:
|
|
Will let @sudatta-mohanty have a look at the code in case his Java is better than mine, but to answer your questions above:
|
sudatta-mohanty
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Excited to see the impact on capacities and in turn on places.
web-bundle/src/main/java/com/graphhopper/replica/StreetEdgeExporterHelper.java
Outdated
Show resolved
Hide resolved
|
|
||
| // Width override if available; maxWidth will be infinity when the OSM width tag isn't present | ||
| if (maxWidth > 0 && maxWidth < Double.POSITIVE_INFINITY) { | ||
| int estimatedLanes = (int) Math.round(maxWidth / 3.5); // assume average lane width of ~3.5m |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have documentation regarding the 3.5m average? From what I remember reading, average lane width on highways is around that value, but on residential roads, it may be closer to ~3-3.1m. Regardless, don't think it would make a lot of difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what I used 😆 I rounded down a bit in an attempt to better account for smaller roads. But yes, it's very inexact, and we'd need more complicated logic that combined road type + width to better "guess" average lane width.
I'm happy to add this if we think it's important, but my other assumption here is that most roads tagged with maxWidth in OSM are going to be larger, freeway-like road sections, not smaller residential roads. So the higher lane width assumption probably holds pretty well in most cases
web-bundle/src/main/java/com/graphhopper/replica/StreetEdgeExporterHelper.java
Outdated
Show resolved
Hide resolved
|
|
||
| // "Guesses" overall (undirected) lane count for OSM Way based on other OSM tags, in cases where the `lanes` tag isn't present. | ||
| // Note: this function does not take into account whether or not a road is one-way; logic in calculateDirectedLaneCounts handles | ||
| // cases where an inferred ("guessed") overall lane count is applied to one-way roads. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case there is some documentation that guides this guess, it would be good to provide a link to that here.
Otherwise, just a comment saying something like:
"if the road is adjacent a roundabout, then...., if width is provided, then...., if highway type is provided, then..."
would be good for future code readers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No formal documentation here, just some research about what tags are available in OSM and asking chat gpt for some ideas. As far as I could find, there's not a common "formula" people use to deduce lane count info (although if one exists I'd love to use it!)
For now, I added a more informative doc comment to this function to describe the steps better
|
Thanks to you both for taking a look here! @rregue :
Looking around spots like NYC, it does look like most of these links are for toll road entrances, so we probably wouldn't want to cap them artificially. But other spots in the western US look like they might just be OSM errors (I saw some of those last week while testing)....maybe I'll skip applying a hard ceiling for now and see how things work out, it's probably better to err on the side of allowing more lanes (to cover toll booths properly)
|
Background
In order to improve capacities used for traffic assignment, we decided to look upstream and improve the
lanescolumn of the street export table, which is currently used as a fallback for calculating capacities when volumes aren't available. The goal is to limit cases where the value forlanesis-1(our current placeholder for "we don't know the lane count") or0- ie, ensure thatlanesis always positive.Changes
First, I refactored the existing lane count logic into its own function,
calculateDirectedLaneCounts, to make the street exporter code more readable. All the lane calculation logic now lives in a new class,StreetEdgeExporterHelper.Next, I added a new function
guessLaneCountFromTagsthat's used specifically to estimate the "overall" (ie both directions) lane count in cases where the standardlanestag isn't present using other OSM data, like the road width, speed limit, and highway type of the link.Finally, I refactored the overall lane logic to work as follows:
lanes,lanes:forward, andlanes:backwardlanes:forwardandlanes:backwardare present, we output those values (almost) directlylanes:backwardis missing butlanes:forwardis present, we check if the overalllanestag is present. If it is, we set backward lane count toforward - overall; if not, we assumelanes:forwardare the only lanes present and set backward lane count to zero (ie, the road is oneway)lanes:forwardis missing butlanes:backwardis presentlanes:forwardandlanes:backwardare missing, we need to do some additional inferring:lanestag is present. If it's not, we set overall lane count using the newguessLaneCountFromTagsfunctionguessLaneCountFromTagsreturns an overall lane count estimate, so if we use that inferred overall lane count toestimate lanes for a one-way road, we divide it by 2 (giving us an estimate for "lanes in one direction")
lanescolumn and the mode-based accessibility of each link as denoted by theflagscolumn:ALLOWS_CARisn't present gets a lane count of 0 - ie, the link is impassable to carsALLOWS_CARis present must have a minimum lane count of1- ie, the link must have at least one lane passable to carsTesting
With these changes, here's the new distribution of
lanesin the nationwide street export file:Testing old (current
master) street export tablelanescolumn, and the resulting capacities, we see that a lot of network links that allow cars havelanes <= 0, and a lot of resulting capacities are<=-0:Testing new street export table
lanescolumn, and the resulting capacities (capacities_table_2024_Q4_all_links_updated_lanes_column_v2), with changes from this PR, we see that no network links that allow cars havelanes <= 0, and no capacities are<=0now.Spot-checking in Dallas, here are the spots where capacity is currently zero:

And here's the change in capacities between old table (using street export off of

master) and new table, built using this PR, for the same spot in Dallas:This shows that we've "filled in" capacities for all of the links where they'd previously been missing. I did similar checks, with similar results, in other areas of the USA as well.
-> foursquare map with new vs. old capacities for NYC, dallas, and columbus OH
Finally, I added a check to the street exporter unit test to ensure that
lanesis a positive value for all car-accessible roads in the micro nor cal test region we use in this repo