Skip to content

feat: improvements to road bike routing #2076

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

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft

Conversation

aoles
Copy link
Member

@aoles aoles commented Jun 2, 2025

Pull Request Checklist

  • 1. I have rebased the latest version of the main branch into my feature branch and all conflicts
    have been resolved.
  • 2. I have added information about the change/addition to functionality to the CHANGELOG.md file under the
    [Unreleased] heading.
  • 3. I have documented my code using JDocs tags.
  • 4. I have removed unnecessary commented out code, imports and System.out.println statements.
  • 5. I have written JUnit tests for any new methods/classes and ensured that they pass.
  • 6. I have created API tests for any new functionality exposed to the API.
  • 7. If changes/additions are made to the ors-config.json file, I have added these to the ors config documentation
    along with a short description of what it is for, and documented this in the Pull Request (below).
  • 8. I have built graphs with my code of the Heidelberg.osm.gz file and run the api-tests with all test passing
  • 9. I have referenced the Issue Number in the Pull Request (if the changes were from an issue).
  • 10. For new features or changes involving building of graphs, I have tested on a larger dataset
    (at least Germany), and the graphs build without problems (i.e. no out-of-memory errors).
  • 11. For new features or changes involving the graphbuilding process (i.e. changing encoders, updating the
    importer etc.), I have generated longer distance routes for the affected profiles with different options
    (avoid features, max weight etc.) and compared these with the routes of the same parameters and start/end
    points generated from the current live ORS.
    If there are differences then the reasoning for these MUST be documented in the pull request.
  • 12. I have written in the Pull Request information about the changes made including their intended usage
    and why the change was needed.
  • 13. For changes touching the API documentation, I have tested that the API playground renders correctly.

Original PR: #778.

Information about the changes

  • Key functionality added:
  • Reason for change:

Examples and reasons for differences between live ORS routes, and those generated from this pull request

Required changes to ors config (if applicable)

@aoles aoles force-pushed the feat/road_bike_speeds branch from c803c1e to f7f7afe Compare June 2, 2025 23:24
@aoles aoles changed the title feat: imporve road bike speeds feat: improve road bike speeds Jun 2, 2025
@aoles aoles force-pushed the feat/road_bike_speeds branch from f7f7afe to 0ed8e24 Compare June 2, 2025 23:41
@aoles
Copy link
Member Author

aoles commented Jun 6, 2025

The remaining task is to properly implement cycleway and footway avoidance via adjusted way priority values rather than decreased average speed values. This could be achieved by keeping most of the changes proposed in the original PR, but accompany them with corresponding changes to the priority values. Such approach should hopefully address the routing issues mentioned in the examples from the original PR's comments while keeping the overall road-bike routing experience.

@aoles aoles assigned aoles and unassigned aoles Jun 6, 2025
@aoles aoles force-pushed the feat/road_bike_speeds branch from 0ed8e24 to 3edec3c Compare June 6, 2025 20:02
@aoles
Copy link
Member Author

aoles commented Jul 7, 2025

Route calculated in the now failing API test testBearingsExceptLastPoint

image

vs. the original route:

image

@aoles
Copy link
Member Author

aoles commented Jul 7, 2025

Original examples by @marq24 where the road bike profile (left hand-side in the screens below) is expected to return a different route than the regular bike profile (right hand-side).

  1. Asphalt cycleway vs asphalt roundabout (route, cycleway)

image

  1. Roundabout vs cycleway (cycle relation) & service shortcut (route, cyclepath)

image

@aoles
Copy link
Member Author

aoles commented Jul 17, 2025

Example on the Heidelberg test graph where the road bike profile is expected to return the same route as the car profile.

image

@sfendrich
Copy link
Contributor

Original examples by @marq24 where the road bike profile (left hand-side in the screens below) is expected to return a different route than the regular bike profile (right hand-side).

1. Asphalt cycleway vs asphalt roundabout ([route](https://classic-maps.openrouteservice.org/directions?n1=51.965202&n2=8.244437&n3=18&a=51.965555,8.243968,51.964878,8.245057&b=1c&c=0&k1=en-US&k2=km), [cycleway](https://www.openstreetmap.org/way/26838420#map=17/51.965522/8.247803))

image

2. Roundabout vs cycleway (cycle relation) & service shortcut ([route](https://classic-maps.openrouteservice.org/directions?n1=52.064885&n2=8.386095&n3=18&a=52.065407,8.386171,52.064821,8.386833&b=1c&c=0&k1=en-US&k2=km), [cyclepath](https://www.openstreetmap.org/way/53788009))

image

In Germany, I would expect the routes in the RHS images illegal because cycling on the left side of a street is generally not permitted unless explicitly allowed through street signs.

@aoles
Copy link
Member Author

aoles commented Jul 17, 2025

Thanks @sfendrich, interesting point! The cycleway and path from the examples are not tagged as oneway so technically it should be possible to use them as illustrated (compare e.g. a true oneway cycleway). Please note that the same routes are actually suggested by the recent version of GraphHopper too, see below.

image image

@aoles aoles force-pushed the feat/road_bike_speeds branch 2 times, most recently from 593fb42 to de85392 Compare July 18, 2025 21:56
@aoles aoles changed the title feat: improve road bike speeds feat: improvements to road bike routing Jul 19, 2025
@github-actions github-actions bot added feature and removed feature labels Jul 19, 2025
@aoles
Copy link
Member Author

aoles commented Jul 19, 2025

Dear @marq24,

Long time no see! 😅 I hope things are good at your end 🤞

I'm reaching out regarding this PR which is based on PR #778 from a few years ago by @steventebrinke who tried to improve road bike routing by addressing inconsistent speed assignments where e.g. paved footways had higher speeds than cycleways. I've tried to take over most of his suggested changes while accommodating your comments from the original discussion. In particular, routing on ways shared with pedestrians such as paths or cycleways along sidewalks is now discouraged via a lower priority rather than decreased speed. Such approach will hopefully improve travel time estimates (based on avg. speed) while keeping the overall road bike experience such as cycleway avoidance. You are most welcome to give it a try! 🚀

I'm looking very much for your feedback 🙏

Cheers,
Andrzej

@marq24
Copy link
Contributor

marq24 commented Jul 25, 2025

@aoles - Thanks for waking me up :-D...

Of course I am very interested to support the project! - So even if this all is a long time ago - I hope I can provide valuable feedback...

And Indeed "key" problem was (or might be is), that official cycle path routes will not be "optimal" for roadbikes - specially in roundabout situations (in inner cities)... That's why cyclepath-path's got quite speed "penalty" ... to keep the routing on the street - and ONLY allow cyclepath if there is "no real" alternative "car-wise"...

@aoles
Copy link
Member Author

aoles commented Jul 25, 2025

Thanks a lot @marq24 for getting back to me! ❤️

Do you think you could test a few critical routes / edge cases you know about to check whether the results produced with the code from this PR meet your requirements?

Cheers! 🚀
Andrzej

@marq24
Copy link
Contributor

marq24 commented Jul 25, 2025

Do you think you could test a few critical routes / edge cases you know about to check whether the results produced with the code from this PR meet your requirements?

YES of course - the 'only' thing the grumpy old me needs is either access to a instance (preferred) where the current feature is rolled out (so I can adjust my local client app to use this "dev-backend") - or - and that probably take quite some time - you have to guide me through the current dev install & data import process, so that I am able to run my own backend again... that I did something like that is indeed quite a long time ago...

@aoles
Copy link
Member Author

aoles commented Jul 26, 2025

Dear @marq24,

I very much appreciate your help! 🙏

There have been quite some changes to the setup of openrouteservice over the past few years. It should be now relatively easy and painless for you to run it locally by following these 3 simple steps:

1. Get the code

git clone https://github.com/GIScience/openrouteservice.git
cd openrouteservice
git checkout feat/road_bike_speeds

2. Get the data

wget https://download.geofabrik.de/europe/germany/nordrhein-westfalen-latest.osm.pbf

3. Run ORS

export ORS_ENGINE_PROFILE_DEFAULT_BUILD_SOURCE_FILE=nordrhein-westfalen-latest.osm.pbf
export ORS_ENGINE_PROFILES_DRIVING_CAR_ENABLED=false
export ORS_ENGINE_PROFILES_CYCLING_ROAD_ENABLED=true
export ORS_ENGINE_PROFILES_CYCLING_ROAD_BUILD_PREPARATION_METHODS_LM_ENABLED=false

./mvnw spring-boot:run

Depending on your machine the instance should be up and running within 2-3 minutes. You can verify that by navigating to http://localhost:8082/ors/v2/health.

To easily query for routes you can hook up your local ORS instance against the online maps client. To do so, go to settings (1) expand the "hidden" advanced section (2) and select Local (3). If you now close the settings window and switch to the road-bike profile you should be getting routes within NRW calculated by your local instance.

image

@marq24
Copy link
Contributor

marq24 commented Jul 26, 2025

just as little update - currently the graphs being build - I am doing this for germany-latest (and decided to include the car's - so that I can compare some stuff) - my hardware running in the basement (where the process is executed should be able to handle all that stuff) - not sure if you aware, that I am running my own vector map tile server (on planet pbf base) [https://maps.emac.de (might be currently a bit slow - since "another" process is running :-D]...

I hope I can convince my hosted 'https://route.emacberry.com/' to use my local server - at least the developer options are present - and as long as there is no CORS issue I might have everything ready (once all this generated)

@aoles
Copy link
Member Author

aoles commented Jul 26, 2025

Thanks a lot for the update! 🚀

If you plan on requesting only local routes (say up to 50 km) you might want to disable the preparations for the speed-up algorithms for car as well in order to get faster graph builds.

export ORS_ENGINE_PROFILES_DRIVING_CAR_BUILD_PREPARATION_METHODS_CH_ENABLED=false
export ORS_ENGINE_PROFILES_DRIVING_CAR_BUILD_PREPARATION_METHODS_CORE_ENABLED=false

@marq24
Copy link
Contributor

marq24 commented Jul 27, 2025

building the graphs was/is not an issue - since as I tried to explain - I am using the same hardware to do planet.pdf stuff for my own tiles server...

Nevertheless I am currently still struggle with setting up my client correctly - or better, the client I have (hosted with https of (of course) does not like to communicate with the local just http hosted directions endpoint... So I must somehow also host locally a webfrontent (probably I just need to checkout another repro and so some magic command's - I'll try to find this that in the docs) solved by adding my local server to the 'Insecure origins treated as secure' list [chrome://flags/#unsafely-treat-insecure-origin-as-secure]

[update] - building now also the default bike, mtb and electric profiles to compare the results - also with the current live prod

@marq24
Copy link
Contributor

marq24 commented Jul 27, 2025

... first of all - once again thank you for getting me into the loop...

I can now compare current PROD/LIVE routing with the BranchVersion (running locally)... while the results seams to be fine for roundabouts (my two reference routes) - the overall result of a route from 'home to work' is not the result I would cycle at all...

image

I have extracted the section in question:
/directions?n1=51.904414&n2=8.376516&n3=15&a=51.894358,8.381308,51.914472,8.371742&b=1c&c=0&k1=en-US&k2=km

The road_bike route on the LIVE is returning the route that I do ride - while the new route is keeping me on main-roads - I have not investigated, what's causing this - but the road bike route "should" be almost identical to the regular cycling route in this case... [the only difference between regular & road bike should be the crossing of the main road (Nordring) at the end

@marq24
Copy link
Contributor

marq24 commented Jul 27, 2025

here is another example (don't get me wrong - the overall result is quit nice)...
/directions?n1=51.703789&n2=8.62431&n3=14&a=51.688787,8.615942,51.712326,8.621242,51.714945,8.628087,51.72015,8.632631&b=1c&c=0&k1=en-US&k2=km

image

So I think, that the main roads are boosted too much (or get's just better speed) - but at the end you can't cycle faster (and might be just personal thing - but of course on my 'tiny' routes there is way less traffic)

concerning the screenshot - left is already LOCAL/New - right is PROD... and I just noticed, that even travel time is 13min (LIVE) vs 21min... but fair enough, 4.1 vs 5.5 km distance

@marq24
Copy link
Contributor

marq24 commented Jul 27, 2025

just added two more points to the last route /directions?n1=51.703789&n2=8.62431&n3=14&a=51.688787,8.615942,51.695916,8.6168,51.706502,8.619719,51.712326,8.621242,51.714945,8.628087,51.72015,8.632631&b=1c&c=0&k1=en-US&k2=km

so for sure there is some issue with the speed on the route (I would like to use 1h:29 - seams to be quite a while for 4.1km ;-)

image

@aoles
Copy link
Member Author

aoles commented Jul 27, 2025

Thanks for the update and for providing these interesting examples! ❤️

Both are very valuable and a good starter for further discussion and investigation 👍

I will certainly look into possible causes why your "home to work" route provides so much different results now.

Re the second example, the only difference I observe between the new local setup (left) and production (right) is at the beginning of the route. The screenshots you provided resemble the regular cycling route. What is the actual road bike route you would expect and prefer?

image

@marq24
Copy link
Contributor

marq24 commented Jul 27, 2025

Re the second example, the only difference I observe between the new local setup (left) and production (right) is at the beginning of the route. The screenshots you provided resemble the regular cycling route. What is the actual road bike route you would expect and prefer?

as human I would always ride how it's illustrated in my sample - #2076 (comment) - but of course the current LIVE server will create the result on the "right" and that's the one I would choose - since when I tried (when I can remember correctly) that my "human preferred" route would be returned, then this had so many other negative effects at different places, that I decided for this compromise... Since I could "fix" it (when planing my cycle routes by adding just an additional waypoint like this https://classic-maps.openrouteservice.org/directions?n1=51.704481&n2=8.623452&n3=14&a=51.688787,8.615942,51.706768,8.619633,51.72015,8.632631&b=1c&c=0&k1=en-US&k2=km

So the current LIVE road bike profile is not always "perfect" - here is another example where it has a glitch (just in the opposite direction - 'here' I will stay on the main-road - yes Humans are inconsequent :-D https://classic-maps.openrouteservice.org/directions?n1=51.700973&n2=8.489792&n3=17&a=51.700006,8.487893,51.702646,8.484836&b=1c&c=0&k1=en-US&k2=km - so I cycle this route here very time https://classic-maps.openrouteservice.org/directions?n1=51.700973&n2=8.489792&n3=17&a=51.700006,8.487893,51.700611,8.485844,51.702646,8.484836&b=1c&c=0&k1=en-US&k2=km

I just hope that this is not adding additional confusion - since the general guideline is, that I want to stay on paved road - avoid cycle-ways when there is also a "good" car-based alternative - and small/tiny roads are preferred for anything that is longer then 250-500m (and specially like in the last case, when I need to get on the main-road anyhow (later)) - just to illustrate it a bit more - this is my typical path I take - https://classic-maps.openrouteservice.org/directions?n1=51.700704&n2=8.531055&n3=13&a=51.695398,8.500993,51.700611,8.485844,51.747864,8.448744&b=1c&c=0&k1=en-US&k2=km

@aoles
Copy link
Member Author

aoles commented Jul 27, 2025

Awesome, thanks for the clarification and providing some additional context! 👍

@sfendrich
Copy link
Contributor

I would appreciate if the road bike flag encoder would be refactored such that common bike flag encoder does not need reflection. I am willing to do this refactoring but am busy with other stuff currently.

steventebrinke and others added 8 commits August 2, 2025 00:29
…fied ways

According to OSM wiki both `highway = unclassified` and `highway = road` are synonyms and can be used interchangeably as "The word 'unclassified' is a historical artefact of the UK road system and does not mean that the classification is unknown; you can use highway=road for that."
…road bike behaviour

The first example with "asphalt cycleway vs asphalt roundabout" did not work as expected.
… used by vehicle profiles

The original "walking speed" of 6 km/h was unrealistically low for a road bike.
@aoles aoles force-pushed the feat/road_bike_speeds branch from 3782dc9 to f4fa4d4 Compare August 1, 2025 23:08
Copy link

sonarqubecloud bot commented Aug 1, 2025

@aoles
Copy link
Member Author

aoles commented Aug 1, 2025

Dear @marq24,

thanks again for all your feedback so far! ❤️ I've looked into the reported differences as compared to the original (production) road bike profile and did some small adjustments in order to address these issues.

The routes from the examples above should be now consistent between production and the feature branch. Please feel free to give it a try 😉

Cheers! 🚀

@marq24
Copy link
Contributor

marq24 commented Aug 16, 2025

I have to admit, that I am clueless HOW I could miss this note once again - the new build is preparing graphs right now...

@marq24
Copy link
Contributor

marq24 commented Aug 16, 2025

Initial tests looks good - I am not sure - why is here the new route taking the L937 - while using the "Unterer Weg" would be the road-bike route I would choose (and the old routing does)?

https://route.emacberry.com/directions?n1=51.909186&n2=8.87543&n3=15&a=51.91861,8.858285,51.910497,8.872511&b=1c&c=0&k1=en-US&k2=km

@aoles
Copy link
Member Author

aoles commented Aug 17, 2025

Initial tests looks good - I am not sure - why is here the new route taking the L937 - while using the "Unterer Weg" would be the road-bike route I would choose (and the old routing does)?

https://route.emacberry.com/directions?n1=51.909186&n2=8.87543&n3=15&a=51.91861,8.858285,51.910497,8.872511&b=1c&c=0&k1=en-US&k2=km

Thanks a lot for taking the time to set up the instance and to run some tests! 👍

The provided example is indeed very interesting: I would also expect the routing to prefer Unterer Weg over L937 considering that it is

  • shorter
  • tagged with bicycle = designated
  • part of multiple bike routes

I will definitely follow up on it 🧐 Have you found any other unexpected routes? Cheers!

@marq24
Copy link
Contributor

marq24 commented Aug 17, 2025

... Have you found any other unexpected routes? Cheers!

as soon as I found "more" - I will share the links here

@aoles
Copy link
Member Author

aoles commented Aug 17, 2025

Awesome, I really appreciate your help! 👍

@marq24
Copy link
Contributor

marq24 commented Aug 17, 2025

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants