Skip to content

feat: offer Nominatim entrance nodes as routing targets - #504

Open
DennisOSRM wants to merge 1 commit into
gh-pagesfrom
feat/nominatim-entrance-points
Open

feat: offer Nominatim entrance nodes as routing targets#504
DennisOSRM wants to merge 1 commit into
gh-pagesfrom
feat/nominatim-entrance-points

Conversation

@DennisOSRM

@DennisOSRM DennisOSRM commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

A geocoded place drops its waypoint on the centroid. For a large site that is nowhere a traveller can reach — BER's centroid sits on the airfield, 1.5 km from the terminal doors, and the route ends on a slip road — Nominatim's entrance nodes are now offered as an alternative.

Clicking a door routes to it while the pin stays on the place that was searched for, joined by a dashed line. Every door stays on the map, the chosen one marked; clicking it again routes back to the place.

before after
BER, driving 23.1 km, 34 min, ends on the A 113 slip road 24.5 km, 29 min, at the terminal door
Pergamonmuseum, walking 1.6 km, 22 min, behind the museum 1.5 km, 20 min, at the entrance

Nothing is chosen for the user

entrance=main records how a building is laid out, not what a router can reach. The Pergamonmuseum tags a main door that the walking network stops 90 m short of, while its side door is on the path — so acting on the tag would be confidently wrong about as often as right. Every door is offered; the waypoint stays put until one is clicked.

Which doors are offered

Direction, from the wiki's one-way values:

value wiki usable at
exit "a one-way out of a building" origin only
entrance "an entrance only, a one-way in" destination only
main, yes, secondary, shop, home enter or leave anywhere
service, emergency, staircase, garage, no never

A via point is both arrived at and left from, so it takes only the two-way doors. Hardenbergstraße 36 has six mapped doors and offers 5 / 5 / 4 as origin / destination / via.

Travel mode, from the door's own OSM access tags, following the access hierarchy (motor_vehiclevehicleaccess; footaccess). Only no and private forbid — permissive, customers and designated are usable, and an untagged door is open to everyone. Read live, so switching profile re-applies the rules to what is already on screen.

Labels

Doors take their OSM name where they have one (Alexa Berlin: Haupteingang Alexanderplatz, Eingang Ravelinplatz…), shown permanently rather than on hover. Where labels collide the whole colliding run collapses into one listing every door in it; zooming in separates them again. Overlap is transitive — showing A and C while hiding B would be arbitrary.

Labels sit in a pane below the marker pane. A zIndexOffset cannot do this: Leaflet derives a marker's z-index from its latitude, so a label on a northerly door outranks a dot on a southerly one however the offsets are set.

Also here

  • Site outline beneath the doors, fetched only when the picker opens. Thinned with Visvalingam–Whyatt, stopping as soon as the smallest surviving triangle would be visible on screen, rather than with Nominatim's polygon_threshold — that tolerance is absolute degrees, so a value that usefully thins a 5 km airport flattens a 170 m building into five stray corners. Measured: the museum keeps 31 of 32 points, BER sheds 33%, neither bounding box moves by a pixel.
  • The gap between where a route can reach and its waypoint is dashed throughout. LRM's default draws it as a solid black casing and solid white core with thin dashes on top, which against this app's heavy blue route reads as more route.
  • continue_straight=true, so OSRM leaves a via by a different way rather than doubling back — 1575 m against 1524 m on a via at Hardenbergstraße 36. A no-op without via points, and it still routes where the u-turn is unavoidable.
  • Cache key → v2. Existing entries predate the entrance data, the OSM identifiers and the access tags.

Tests

465 tests, 32 suites. New modules are at 100% line coverage (entrance_picker, entrance_waypoints, simplify, lrm_options); the remaining branch misses are defensive fallbacks. The entrance-specific geocoder paths — both request paths, forward and reverse, and the persisted-cache round trip — are covered too.

Verified against the live Nominatim and OSRM services throughout, not only against fakes.

Known gap

A waypoint that becomes a via — by appending a waypoint after it — keeps a door the via rules would not have offered. The role changes; the existing selection is not re-validated. Re-typing the address recovers it. Fixing it properly means retaining per-waypoint place state across splices, which the picker deliberately does not keep today, so I have left it rather than bolt on a half-measure.

🤖 Claude Code, Claude Opus 5

@DennisOSRM
DennisOSRM force-pushed the feat/nominatim-entrance-points branch from 7d76323 to fe34635 Compare August 31, 2026 11:15
A geocoded place drops its waypoint on the centroid, which for a large
site is nowhere a traveller can reach: BER's centroid sits on the
airfield, 1.5 km from the terminal doors, and the route ends on a slip
road. Nominatim reports a place's entrance nodes when asked
(`entrances=1`), so they are now offered as an alternative.

Clicking a door routes to it while the waypoint's pin stays on the place
that was searched for, joined by a dashed line. Every door stays on the
map, the chosen one marked, and clicking it again routes back to the
place.

The picker never chooses for the user. `entrance=main` records how a
building is laid out, not what a router can reach — the Pergamonmuseum
tags a main door the walking network stops 90 m short of, while its side
door is on the path — so acting on the tag would be confidently wrong
about as often as right.

Which doors are offered depends on two things:

  - Direction, from the wiki's one-way values. `entrance=exit` is "a
    one-way out" and so only usable at an origin; `entrance=entrance` is
    "a one-way in" and only at a destination. A via point is both
    arrived at and left from, so it takes neither.
  - The travel mode, from the door's own OSM access tags, following the
    access hierarchy (`motor_vehicle` > `vehicle` > `access`). Read live,
    so switching profile re-applies the rules to what is on screen.

Doors are named from their OSM `name` tag where they have one, and
labelled permanently. Where labels collide the whole colliding run
collapses into one listing every door in it; zooming in separates them
again. Labels live in a pane below the marker pane, because Leaflet
derives a marker's z-index from its latitude and a zIndexOffset alone
cannot keep a dot above them.

Also here:

  - The site outline is drawn beneath the doors, fetched only when the
    picker opens. It is thinned with Visvalingam-Whyatt, stopping as soon
    as the smallest surviving triangle would be visible, rather than with
    Nominatim's polygon_threshold: that tolerance is absolute degrees, so
    a value that usefully thins a 5 km airport flattens a 170 m building
    into five stray corners.
  - The gap between where a route can reach and its waypoint is now
    dashed throughout. Leaflet Routing Machine's default draws it as a
    solid casing with dashes on top, which against this app's heavy blue
    route reads as more route.
  - `continue_straight=true`, so OSRM leaves a via point by a different
    way instead of doubling back. Measured at 1575 m against 1524 m on a
    via at Hardenbergstrasse 36; a no-op without via points, and it still
    routes where the u-turn is unavoidable.
  - The persisted geocode cache moves to v2: entries predate the entrance
    data, the OSM identifiers and the access tags.
@DennisOSRM
DennisOSRM force-pushed the feat/nominatim-entrance-points branch from fe34635 to 1042822 Compare August 31, 2026 11:30
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.

1 participant