Skip to content

feat: nav-5699 add pedestrian name enricher - #33

Open
remi-lucas-hove wants to merge 1 commit into
release/3.7.0from
feat/pedestrian_name_enricher
Open

feat: nav-5699 add pedestrian name enricher#33
remi-lucas-hove wants to merge 1 commit into
release/3.7.0from
feat/pedestrian_name_enricher

Conversation

@remi-lucas-hove

@remi-lucas-hove remi-lucas-hove commented Jun 17, 2026

Copy link
Copy Markdown

Enrich unnamed sidewalk edges with the name of the nearest street

Motivation

When Valhalla routes a pedestrian along a sidewalk/footway that has its own geometry, the narrative typically falls back to generic wording ("the walkway", "the path") because these OSM ways rarely carry a name=* tag. Users expect to hear the name of the street the sidewalk runs along ("follow boulevard Saint-Germain"), not a generic "walkway".

This is a recurring, well-documented pain point for pedestrian guidance:

The approaches discussed so far rely on OSM tags such as is_sidepath:of:name=* or street:name=* to carry the parallel street's name. Those keys are valuable but still sparse (~30k ways worldwide for is_sidepath:of:name), so they only help where mappers have explicitly added them.

This PR takes a complementary, tag-independent approach: it derives a street name geometrically at tile-build time, so unnamed sidewalk edges can get a meaningful name regardless of whether the sidepath tags are present. Where those tags do exist, they could later be used as an authoritative override on top of this heuristic.

What this PR does

Adds a new tile-build stage that runs after the graph is built and before GraphEnhancer, enriching unnamed edges whose Valhalla use is kSidewalk with the name of the closest matching named road edge, up to a maximum distance of 50 metres.

Placing the stage before GraphEnhancer is deliberate: name_consistency (the per-edge bitfield the enhancer computes to flag neighbouring edges sharing a name, used to penalise name changes during costing) is then computed with the enriched names taken into account, so the enrichment actually influences pedestrian routing/guidance rather than only the textual narrative.

How it works

Each tile is processed by a worker thread in three phases:

  1. BUILD
    Build an R-tree (boost::geometry::index) indexing all named road edges of the tile. Named edges are sampled into points spaced at most 10 m apart and the points (not segments) are indexed for fast nearest-neighbour queries.
  2. SEARCH
    For each unnamed sidewalk edge, query the ~100 nearest indexed points (coarse distance from the sidewalk edge centre), gather the candidate named edges, group them by candidate name, and score each name group by the finer average distance between the sidewalk edge and that group. Grouping by name handles the common case of a long sidewalk running along a road that is split into many short same-named edges.
  3. APPLY
    Rewrite the tile's EdgeInfo and recompute binary offsets for the newly named edges.

Performance notes

  • An R-tree massively outperforms loki::search here (~100x faster for this batch nearest-name workload; loki::search is built for individual queries).
  • Using float instead of double in the R-tree gives a significant speedup.
  • Using a local Cartesian projection instead of geographic coordinates speeds things up further: (lon, lat) is mapped to (lon * cos_lat, lat) with cos_lat a constant computed from the tile-centre latitude.

Full Île-de-France OSM extract near Paris, 40 tiles, 12 threads: ~360k enriched edges, ~70 s total. The dense central-Paris tile dominates (~260k enriched edges, ~50 s enrichment on a single thread), so moving from per-tile to per-edge parallelism is an obvious next win.

Known limitations / future work

  • Naming is per-tile, so edges near tile borders may miss a closer named road that lives in the neighbouring tile.
  • Multithreading is per-tile; per-edge work distribution would balance the dense tiles.
  • This is intentionally a first, purely spatial heuristic limited to kSidewalk edges. It could later be combined with the explicit is_sidepath:of:name / street:name tags from #5594 as an authoritative source when present.
  • Assign multiple street names to a sidewalk edge when its geometry is meaningfully associated with more than one named road.
  • Adjust Odin's maneuver construction to avoid overly verbose instructions when a pedestrian route remains broadly straight but briefly follows short sidewalk segments immediately before and after a pedestrian crossing.

We'd welcome maintainer feedback on the approach and on where the community would prefer this to live in the pipeline.

@remi-lucas-hove
remi-lucas-hove force-pushed the feat/pedestrian_name_enricher branch from dade867 to c97296d Compare June 18, 2026 08:18
@remi-lucas-hove remi-lucas-hove changed the title feat: WiP feat: nav-5699 add pedestrian name enricher Jun 18, 2026
@remi-lucas-hove
remi-lucas-hove force-pushed the feat/pedestrian_name_enricher branch 4 times, most recently from e96b57a to 8ed939b Compare June 19, 2026 08:50
Comment thread src/mjolnir/pedestrian_name_enricher.cc Outdated
Comment thread src/mjolnir/pedestrian_name_enricher.cc Outdated
Comment thread src/mjolnir/pedestrian_name_enricher.cc Outdated
@remi-lucas-hove
remi-lucas-hove force-pushed the feat/pedestrian_name_enricher branch from bb375cd to 83467ec Compare June 22, 2026 13:19
@remi-lucas-hove
remi-lucas-hove requested a review from azime June 23, 2026 08:55
@remi-lucas-hove
remi-lucas-hove force-pushed the feat/pedestrian_name_enricher branch 2 times, most recently from 8112508 to 1c6ea13 Compare June 26, 2026 08:45
@remi-lucas-hove

remi-lucas-hove commented Jun 26, 2026

Copy link
Copy Markdown
Author

L'enrichissement des edges piétons a lieu juste après le build du graph et surtout avant le GraphEnhancement.

En effet, si on veut que ça soit une étape à la fin de la pipeline qui build les tiles, le paramètre name_consistency (bitfield calculé par le GraphEnhancer pour indiquer, pour chaque edge, quelles sont ses edges voisines qui ont le même name) n'aurait pas été correctement calculé. Pendant une requête asgard, les changements de nom entre 2 edges sont pénalisés (5 secondes dans le cost).

Comme l'enrichissement des edges piétonnes a lieu avant le GraphEnhancer, name_consistency tient bien compte de cet enrichissement. Cela a donc un impact réel pour le routing piéton IDFM. Impact très modéré certes, tant qu'on garde le walk_factor à 2.0 (pénalité de 5s qui disparaît si on ne change pas de nom, très mineur à côté d'une multiplication par 2), mais impact quand-même.

@remi-lucas-hove
remi-lucas-hove force-pushed the feat/pedestrian_name_enricher branch from 7022475 to bcab98d Compare July 1, 2026 16:18
@remi-lucas-hove
remi-lucas-hove force-pushed the feat/pedestrian_name_enricher branch 2 times, most recently from 03fecd7 to daec788 Compare July 15, 2026 09:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants