Proposed features/traffic signals set 2

From OpenStreetMap Wiki
Jump to navigation Jump to search
traffic signals set 2
Status: Proposed (under way)
Proposed by: Rostaman
Tagging: type=traffic_signals_set
Applies to: relation
Definition: Group of traffic signal devices corresponding to a single intersection
Drafted on: 2021-02-10
RFC start: 2021-02-13


Example of how an intersection should be rendered at medium and high zoom

I propose to add a relation of type=traffic_signals_set which groups all nodes that specify locations of traffic signals in a single intersection (no "green waves"). A road user passing through a set of signals which are members of the same relation can always expect to have to stop at most once (if he/she encounters a red light at the beginning of the intersection), not counting yielding to pedestrians while turning.

The relation contains highway traffic signals (where road traffic stops), crossing traffic signals (where sidewalk traffic stops, or where sidewalk/path ways meet road ways), and non-traffic signal nodes where signal icons should be rendered at lower zoom levels, to reduce low-zoom clutter from intersections mapped in detail.

It can also be used to display a junction name for named junctions.


The name is based on the earlier type=traffic_signals_set proposal. I've decided to write this proposal from scratch to be more creative in my approach.

It's necessary to group traffic signals in the same intersection correctly to give each intersection the correct time penalty when routing traffic. Currently there's no way to determine which traffic lights belong to the same intersection other than heuristics. This is problematic because large intersections on dual carriageways can be longer than the short side of a small city block.

Example 1: compare 1 & 2: a road user has to pass through the highway traffic light on one side of the intersection and travel a long way to the pedestrian traffic light on the other side. Both lights are part of the same phased signal, but a routing engine can assume they're part of two different intersections and give the intersection a double penalty. Alternatively, it can presume that the traffic lights on opposite sides of the small city block are part of the same intersection and give them half the actual penalty.

Example 2: a sidewalk/path user encounters a crossing=traffic_signals. The engine has to use heuristics to determine whether it's a standalone crossing (low penalty), or part of a multi-road intersection (higher penalty).

Having a relation for each intersection avoids some need for heuristics for assessing routing penalties. It also opens a path to further categorization of intersections, for example signalled pedestrian crossings, which need smaller penalties than full-fledged multi-road intersections.

Problems not (yet) solved by this proposal

  • not useful for traffic signal routing penalties for footway/cycleway users when crossing a multiple-carriageway road
  • multiple closely spaced crossing=* nodes sometimes correspond to a single crosswalk (ex. [1], [2], [3])


Nodes at black circles should also be included in the relation. Ideally these nodes shouldn't be tagged with traffic signals (they should be "empty" nodes). It would be best to tag traffic signals at the locations of stop lines

Relation contains nodes without roles. Roles are unnecessary since each node's purpose can be fully determined from its tags. There are three types of nodes in the relation:

This is where road traffic (cars, bicycles, trucks...) stops.
These are signalled crossings for sidewalk traffic (pedestrians, bicycles on paths, horses on bridleways...). If the sidewalk isn't mapped separately, this is a node on the way corresponding to the crossed road. If the sidewalk is mapped separately, this is the node where the path/footway/cycleway and road intersect. Alternatively, if the crossing is mapped as a way with footway=crossing & crossing=traffic_signals or similar, two signal nodes can be placed, one at each end of the crossing way (or a single node if the crossing is one way for all users) - example.
This is where traffic light icons should be rendered at lower zoom. Typically at the node where the main roads intersect. If one or both main roads are dual carriageway, there will be 2 or 4 (respectively) nodes where they intersect (example in the picture right). Sometimes the intersection will be mapped so that highway traffic signals already are at these locations; in other cases, highway traffic signals will be mapped at stop lines, so these nodes have to be specifically added.

Ways with crossing=traffic_signals (example) don't need to be included in the relation, because routing engines don't/can't use these to find signalled crossings when searching along a road (?). Hence this wouldn't be useful for routing. Please correct if this assumption is wrong. Alternatively, ways and areas can be included in the relation but safely ignored by routing engines, since corresponding crossing nodes must always be included.

The relation must contain at least one traffic signal node (preferably multiple to be of some use). It doesn't have to contain empty nodes, but if the intersection is mapped in detail (all traffic signals placed at stop lines instead of intersections of highway ways), it should.

Pedestrian crossing

Relations that describe intersections of multiple roads don't need any other tags than type=traffic_signals_set.

If the intersection only has one road and a path or a pedestrian crossing, then the relation should also be tagged with traffic_signals=pedestrian_crossing. These intersections have faster cycles and need a smaller routing penalty.

Junction name

If the junction has a name, it should be put in the relation's name=* tag, and the place where the name should be rendered on the map should be added as a node with a "label" role.


  • [4] - a pedestrian & bicycle crossing
  • [5], [6] - two separate intersections that are ~45 m from each other. Without the relations they might be heuristically expected to form a single intersection
  • [7] - an incomplete intersection (road traffic signals not marked at each stop line) can still be usefully mapped with this relation
  • [8] - a typical dual carriageway intersection - the road traffic light and the opposite pedestrian crossing for E->W traffic are ~50 m apart.
  • More examples

Possibilities for rendering

This relation lets data users render choose if they want to render traffic lights at incoming ways on stop lines, or in the middle of the intersection. The latter style is used in some print maps.

At stop lines

This relation makes it possible to highlight traffic lights that belong to the same intersection

To use this kind of rendering, the data in the relation can effectively be ignored. Example of an intersection rendered this way:

If the intersection is named, the name can be centered on the "label" node.

In the middle of the intersection

This style of rendering might be preferred at lower zoom levels, and other situations where it's important to display whether an intersection is signalled, but accurate locations of traffic signals are unnecessary.

When using this style, traffic lights are rendered not where they are marked as nodes, but at intersection member node(s) where main roads meet (the above mentioned "empty" nodes). For example, it would be similar to the way this intersection is currently drawn.

Alternatively, if the relation doesn't contain any empty nodes (if the mapper(s) did not map traffic lights at stop lines), one is still able to render the main traffic signal (to show the type of intersection at a glance) by these heuristics:

Features/Pages affected

External discussions


Please comment on the discussion page.