Moped routing not working?

Hello,

I’m working on a routing app for Dutch scooters. They are allowed on some specific roads called “bromfietspaden”. I can see there are some tags inside OSM that will listen to this but for some reason its not routing properly, does anybody know why? Any help would be greatly appreciated.

Here you can the route its taking:

And here you can clearly see the moped tag is enabled on this road:

This is the profile I’ve created:

{
“priority”: [
{
“if”: “road_class == MOTORWAY || road_class == TRUNK || max_speed > 60”,
“multiply_by”: 0
},
{
“if”: “road_class == CYCLEWAY && road_access == DESTINATION”,
“multiply_by”: 1
},
{
“if”: “road_class == CYCLEWAY && road_access != DESTINATION”,
“multiply_by”: 0
},
{
“if”: “road_environment == FERRY”,
“multiply_by”: 0.5
}
],
“speed”: [
{
“if”: “true”,
“limit_to”: 45
},
{
“if”: “road_class == CYCLEWAY && road_access == DESTINATION”,
“limit_to”: 30
},
{
“if”: “road_class == RESIDENTIAL || road_class == LIVING_STREET”,
“limit_to”: 30
}
]
}

Did I make a mistake anywhere?

Honestly, I don’t understand the question. Which route do you expect (or not expect) and why?

Hey,

Thanks for your response!

Its sepose to route through ‘Arlandaweg’. Why would I route around ArlandaWeg when its a moped = designated road?

You mean this way? It is tagged as highway=cycleway;moped=designated, but ignored by GraphHopper because cycleways are filtered out for motorized vehicle profiles. This issue also came up recently here

I see highway=cycleway+moped=designated is quite popular in the Netherlands. Can you comment on what kind of vehicles are meant by ‘moped’ there? Are they more like bicycles or actual scooters? Maybe it is possible to customize the bike profile rather than scooter?

The vehicle is called a “bromfiets” here in The Netherlands. Its a motorized scooter allowed to go 45km/h and are mostly required to drive on normal car roads. But sometimes they are allowed on some bike lanes. I’m trying to figure out how I can make it route on roads AND these specified cycleways. I saw the post you linked and there is said that it could be done by running a self hosted instance. I have done this and created a custom profile for the bromfiets but whatever I do it won’t use the moped routes. Do you know any way to do this?

You need to make sure the cycleways are included in the routing graph and they are accessible. For them to be included in the graph they must not be listed in the import.osm.ignored_highways setting in your config file. Unless you restrict access with one of the access encoded values in your model they should already be accessible then. In the GraphHopper maps web UI you can enable the ‘Show Routing Graph’ option in the layers menu to see the routing graph. Use this to check if your desired roads are included and see their attributes.

Thanks for your response. I’ve confirmed that the cycleways are indeed included in the routing graph and visible with their attributes. I’ve removed cycleway from the import.osm.ignored_highways setting and can see the bromfietspaden in the routing graph.
Here’s what I’m seeing in the routing graph for a bromfietspad (Brettenpad) in Amsterdam:

road_class=cycleway
car_access=false
road_access=yes
surface=asphalt]

I’ve tried various combinations in the bromfiets.json custom model, including:

Prioritizing paths where road_class=CYCLEWAY with multiply_by values up to 10
Using car_access=false as an identifier
Combining road_class and road_access conditions
Adding the required encoded values: road_class, road_class_link, road_environment, max_speed, road_access, surface, roundabout, hgv, car_access

Since Peter mentioned it’s possible with a self-hosted instance, I feel like I must be missing something in the configuration. The paths are visible in the routing graph with correct attributes, but GraphHopper still routes around them. Any additional suggestions on how to make GraphHopper prefer these paths?

Here is my current implementation:

{
  "priority": [
    {
      "if": "road_class == MOTORWAY || road_class == TRUNK || max_speed > 60",
      "multiply_by": 0
    },
    {
      "if": "road_class == CYCLEWAY && car_access == false",
      "multiply_by": 10
    },
    {
      "if": "road_class == PRIMARY || road_class == SECONDARY || road_class == TERTIARY",
      "multiply_by": 0.5
    }
  ],
  "speed": [
    {
      "if": "true",
      "limit_to": 45
    },
    {
      "if": "road_class == CYCLEWAY",
      "limit_to": 30
    },
    {
      "if": "road_class == RESIDENTIAL || road_class == LIVING_STREET",
      "limit_to": 30
    }
  ]
}

The route seen in the screenshot still takes the primary (Haarlemmerweg), probably because you still use 45km/h for everything besides cycleway, residential and living street which are significantly slower (30km/h). Did you try to force the road along the cycleway using a via-point? If that works it is probably only about sufficiently reducing the speed/priority of the other roads.

Even while using a via point its still rerouting around the tunnel, its so strange

I would start with a simple model that uses only speed, maybe even only the ‘limit_to: 45’ rule you already have. If the cycleway is still not used then something strange is going on. If it is used you need to make sure the speed and/or priority of the other roads are sufficiently low compared to the cycleway such that no detour occurs, when you make further changes to the model.

car_access == false

Is this really what you want here?

btw: you could try the ModeAccessParser for your use case which can consume any list of access tags (see e.g. bus_access)