Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Unreleased
- Changes from 6.0.0
- Profiles:
- ADDED: Use `is_sidepath:of:name` and `street:name` as fallback names for unnamed sidewalks and sidepaths in foot and bicycle profiles [#7259](https://github.com/Project-OSRM/osrm-backend/issues/7259)
- Build:
- FIXED: Reduce MSVC compiler warnings by suppressing informational warnings while preserving bug-indicating warnings [#7253](https://github.com/Project-OSRM/osrm-backend/issues/7253)
- Misc:
Expand Down
36 changes: 30 additions & 6 deletions docs/profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ If you want to prioritize certain streets, increase the rate on these.
A profile should set `api_version` at the top of your profile. This is done to ensure that older profiles are still supported when the api changes. If `api_version` is not defined, 0 will be assumed. The current api version is 4.

### Library files
The folder [profiles/lib/](../profiles/lib/) contains LUA library files for handling many common processing tasks.
The folder [profiles/lib/](../profiles/lib/) contains Lua library files for handling many common processing tasks.

File | Notes
------------------|------------------------------
Expand All @@ -89,7 +89,7 @@ They all return a table of functions when you use `require` to load them. You ca
### setup()
The `setup` function is called once when the profile is loaded and must return a table of configurations. It's also where you can do other global setup, like loading data sources that are used during processing.

Note that processing of data is parallelized and several unconnected LUA interpreters will be running at the same time. The `setup` function will be called once for each. Each LUA interpreter will have its own set of globals.
Note that processing of data is parallelized and several unconnected Lua interpreters will be running at the same time. The `setup` function will be called once for each. Each Lua interpreter will have its own set of globals.

The following global properties can be set under `properties` in the hash you return in the `setup` function:

Expand Down Expand Up @@ -347,10 +347,34 @@ road_classification.road_priority_class | Enum | Guidance: order in priority
road_classification.may_be_ignored | Boolean | Guidance: way is non-highway
road_classification.num_lanes | Unsigned | Guidance: total number of lanes in way

### Way names
The `WayHandlers.names` function in [way_handlers.lua](../profiles/lib/way_handlers.lua) handles extraction of way names for routing instructions. It processes the following OSM tags:

Tag | Notes
----------------------|------------------------------
`name` | Primary name of the way
`name:pronunciation` | Pronunciation hint for text-to-speech
`ref` | Road reference number (e.g., "A1", "I-95")
`junction:ref` | Exit or junction reference number

For unnamed sidewalks and sidepaths (where `highway=footway`, `highway=cycleway`, or `highway=path`), the function also supports fallback name tags when the way is marked as a sidepath:

Tag | Notes
----------------------|------------------------------
`is_sidepath:of:name` | Name of the street the sidepath follows (checked first)
`street:name` | Alternative tag for the associated street name

The fallback is only applied when the way has one of these sidepath markers:
- `footway=sidewalk`
- `cycleway=sidepath`
- `is_sidepath=yes`

This allows routing instructions to show street names for separately mapped sidewalks, e.g., "Turn right onto Main Street" instead of just "Turn right".

### process_segment(profile, segment)
The `process_segment` function is called for every segment of OSM ways. A segment is a straight line between two OSM nodes.

On OpenStreetMap way cannot have different tags on different parts of a way. Instead you would split the way into several smaller ways. However many ways are long. For example, many ways pass hills without any change in tags.
An OpenStreetMap way cannot have different tags on different parts of a way. Instead you would split the way into several smaller ways. However, many ways are long. For example, many ways pass over hills without any change in tags.

Processing each segment of an OSM way makes it possible to have different speeds on different parts of a way based on external data like data about elevation, pollution, noise or scenic value and adjust weight and duration of the segment accordingly.

Expand Down Expand Up @@ -453,10 +477,10 @@ When turning from `a` to `b` via `x`,
* `roads_on_the_left[1]` is the road `xe`
* `roads_on_the_left[2]` is the road `xc`

Note that indices of arrays in lua are 1-based.
Note that indices of arrays in Lua are 1-based.

#### `highway_turn_classification` and `access_turn_classification`
When setting appropriate turn weights and duration, information about the highway and access tags of roads that are involved in the turn are necessary. The lua turn function `process_turn` does not have access to the original osrm tags anymore. However, `highway_turn_classification` and `access_turn_classification` can be set during setup. The classification set during setup can be later used in `process_turn`.
When setting appropriate turn weights and duration, information about the highway and access tags of roads that are involved in the turn are necessary. The Lua turn function `process_turn` does not have access to the original OSM tags anymore. However, `highway_turn_classification` and `access_turn_classification` can be set during setup. The classification set during setup can be later used in `process_turn`.

**Example**

Expand Down Expand Up @@ -513,7 +537,7 @@ function setup()
end
```

The input data must an ASCII file with rows of integers. e.g.:
The input data must be an ASCII file with rows of integers, e.g.:

```
0 0 0 0
Expand Down
77 changes: 77 additions & 0 deletions features/bicycle/sidepath_names.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
@routing @bicycle @sidepath
Feature: Bicycle - Sidepath street names

Background:
Given the profile "bicycle"
Given a grid size of 200 meters

Scenario: Bicycle - Use is_sidepath:of:name for cycleway sidepath
Given the node map
"""
a b c
"""

And the ways
| nodes | highway | cycleway | name | is_sidepath:of:name |
| ab | cycleway | sidepath | | Highway 1 |
| bc | cycleway | sidepath | | Highway 2 |

When I route I should get
| from | to | route |
| a | c | Highway 1,Highway 2,Highway 2 |

Scenario: Bicycle - Use street:name for cycleway sidepath
Given the node map
"""
a b
"""

And the ways
| nodes | highway | cycleway | name | street:name |
| ab | cycleway | sidepath | | Bike Lane |

When I route I should get
| from | to | route |
| a | b | Bike Lane,Bike Lane |

Scenario: Bicycle - Explicit name takes priority
Given the node map
"""
a b
"""

And the ways
| nodes | highway | cycleway | name | is_sidepath:of:name |
| ab | cycleway | sidepath | Named Path | Fallback |

When I route I should get
| from | to | route |
| a | b | Named Path,Named Path |

Scenario: Bicycle - Use is_sidepath=yes with is_sidepath:of:name
Given the node map
"""
a b
"""

And the ways
| nodes | highway | is_sidepath | name | is_sidepath:of:name |
| ab | path | yes | | Cycle Route |

When I route I should get
| from | to | route |
| a | b | Cycle Route,Cycle Route |

Scenario: Bicycle - No fallback without sidepath marker
Given the node map
"""
a b
"""

And the ways
| nodes | highway | name | street:name |
| ab | cycleway | | Should Not Show |

When I route I should get
| from | to | route |
| a | b | , |
48 changes: 48 additions & 0 deletions features/car/sidepath_names.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@routing @car @sidepath
Feature: Car - Sidepath names should not affect car routing

Background:
Given the profile "car"
Given a grid size of 200 meters

Scenario: Car - Does not use sidepath name fallback on roads
Given the node map
"""
a b
"""

And the ways
| nodes | highway | name | street:name |
| ab | primary | | Should Not Show |

When I route I should get
| from | to | route |
| a | b | , |

Scenario: Car - Does not pick up is_sidepath:of:name on roads
Given the node map
"""
a b
"""

And the ways
| nodes | highway | name | is_sidepath:of:name |
| ab | primary | | Should Not Show |

When I route I should get
| from | to | route |
| a | b | , |

Scenario: Car - Sidepath markers do not affect car roads
Given the node map
"""
a b
"""

And the ways
| nodes | highway | footway | name | is_sidepath:of:name |
| ab | primary | sidewalk | | Should Not Show |

When I route I should get
| from | to | route |
| a | b | , |
92 changes: 92 additions & 0 deletions features/foot/sidepath_names.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
@routing @foot @sidepath
Feature: Foot - Sidepath street names

Background:
Given the profile "foot"
Given a grid size of 200 meters

Scenario: Foot - Use is_sidepath:of:name for unnamed sidewalk
Given the node map
"""
a b c
"""

And the ways
| nodes | highway | footway | name | is_sidepath:of:name |
| ab | footway | sidewalk | | Main Street |
| bc | footway | sidewalk | | Oak Avenue |

When I route I should get
| from | to | route |
| a | c | Main Street,Oak Avenue,Oak Avenue |

Scenario: Foot - Use street:name for unnamed sidewalk
Given the node map
"""
a b c
"""

And the ways
| nodes | highway | footway | name | street:name |
| ab | footway | sidewalk | | Elm Street |
| bc | footway | sidewalk | | Pine Road |

When I route I should get
| from | to | route |
| a | c | Elm Street,Pine Road,Pine Road |

Scenario: Foot - is_sidepath:of:name takes priority over street:name
Given the node map
"""
a b
"""

And the ways
| nodes | highway | footway | name | is_sidepath:of:name | street:name |
| ab | footway | sidewalk | | Primary Name | Secondary |

When I route I should get
| from | to | route |
| a | b | Primary Name,Primary Name |

Scenario: Foot - Explicit name tag takes priority over fallback
Given the node map
"""
a b
"""

And the ways
| nodes | highway | footway | name | is_sidepath:of:name |
| ab | footway | sidewalk | Explicit Name | Fallback Name |

When I route I should get
| from | to | route |
| a | b | Explicit Name,Explicit Name |

Scenario: Foot - Use is_sidepath=yes with street:name
Given the node map
"""
a b
"""

And the ways
| nodes | highway | is_sidepath | name | street:name |
| ab | path | yes | | River Path |

When I route I should get
| from | to | route |
| a | b | River Path,River Path |

Scenario: Foot - No fallback without sidepath marker
Given the node map
"""
a b
"""

And the ways
| nodes | highway | name | street:name |
| ab | footway | | Should Not Show |

When I route I should get
| from | to | route |
| a | b | , |
17 changes: 17 additions & 0 deletions profiles/lib/way_handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,23 @@ function WayHandlers.names(profile,way,result,data)
-- Set the name that will be used for instructions
if name then
result.name = name
else
-- Fallback for unnamed sidewalks and sidepaths
-- Use is_sidepath:of:name or street:name when way is marked as a sidepath
local sidepath_name = way:get_value_by_key("is_sidepath:of:name") or
way:get_value_by_key("street:name")
if sidepath_name then
local highway = way:get_value_by_key("highway")
local footway = way:get_value_by_key("footway")
local cycleway = way:get_value_by_key("cycleway")
local is_sidepath = way:get_value_by_key("is_sidepath")
-- Only apply to footway/cycleway/path highway types
if highway == "footway" or highway == "cycleway" or highway == "path" then
if footway == "sidewalk" or cycleway == "sidepath" or is_sidepath == "yes" then
result.name = sidepath_name
end
end
end
end

if ref then
Expand Down
Loading