"Complex ways" (this isn't about sidewalks..)

I’ve been thinking too much about pavements recently..

Has anyone proposed/implemented/attempted anything along the lines of a “complex way” or a “way array” in OpenStreetMap (or outside of it)? I’ll explain what I mean.

So currently we have nodes and ways. When we draw one road, we either give it one way (with tags), or we give it one way per carriageway and/or cycle track and/or “sidewalk”. The former is a very limited abstraction, but the latter does not have any context for how it is related to other nearby ways. So e.g. if you have two sidewalks alongside a carriageway, there is no inherent relationship between those ways.

Instead, imagine we created a single way along a road’s centre line, and then added 1-dimensional “ways” that are always positioned relative to the centre line. Something like this:

When you move the dotted centre line, the component ways move around with them - but otherwise the component ways act like normal ways and can be joined up to other normal ways. The important thing is that, to a router, it’s not on any of the component ways - instead it’s on a single, complex way, with a number indicating it’s position (in this case, -2 to +2). The tags that it respects are a combination of the way tags and the component way tags, and so long as those tags allow it, it can “jump” to another way.

Here’s a more complex example:

Here the lanes are mapped separately (something we don’t currently do, but here it’s easy) and the kerb is also mapped. The kerb would have a traversal tag, which defined who could cross (foot=yes, wheelchair=no, etc etc). And of course you’d tell a router that it can cross a kerb but not travel along it (although..). You could also add fences or even lane markers as ways that can (like kerbs) be given traversal rules.

Doing this in current OSM would probably require tag “overloading” e.g. 1:highway=trunk, 2:highway=footway, and wouldn’t be useful unless routers and renderers knew what the numbers at the beginning of the tags were :upside_down_face: Anyway, this has been in my head for a while. Has anyone else proposed/tried something like this?

Here the lanes are mapped separately (something we don’t currently do, but here it’s easy) and the kerb is also mapped. The kerb would have a traversal tag, which defined who could cross (foot=yes, wheelchair=no, etc etc). And of course you’d tell a router that it can cross a kerb but not travel along it (although..). You could also add fences or even lane markers as ways that can (like kerbs) be given traversal rules.

I have proposed something like this but am not currently pursuing this path intensively nor can I offer an implementation ;-)

[

Proposal:Area
wiki.openstreetmap.org

](https://wiki.openstreetmap.org/wiki/Proposal:Area)

Right now the relevant part of the data model is ways have key value pairs and an ordered list of nodes and nodes have coordinates.

I’m not sure what you’re producing. Would ways have some kind of sub-object and each of those sub-object has some properties plus a list of key-value pairs?

So I’ve seen a couple of people propose relations or areas. The problem with that is it would be hard to create an accurate graph out of an area or a set of relationships.

With what I wrote above you can basically imagine that every way is connected internally to every other way through each point - meaning that (subject to the rules the router is following) it can be navigated just like the current map is.

Hmm. You could do it like that. What I was imagining, if I were able to create a new OSM element, would be a “relative-node” - that is, a node which is positioned relative to another node (distance/direction) instead of by an absolute long/lat. The relative-nodes would then form ways in parallel with the “absolute” nodes (the ones we currently use), but at each node cluster the router would be able to switch ways. You could simulate it by adding little roads or paths between a set of nodes placed on the map currently (although in a production implementation you wouldn’t actually add/render these, they would be implied).

Since I’m unlikely to be able to invent a new element type though I was actually thinking you could do this with tags - to humour me:

highway = residential
name = What a street!
surface = asphalt
complex-way:2:highway = footway
complex-way:2:footway = sidewalk
complex-way:1:barrier = kerb
complex-way:-1:barrier = kerb
complex-way:-2:highway = footway
complex-way:-2:footway = sidewalk

complex-way tags are hierarchical, so any tag on the object is inherited unless overridden by a complex way tag. The router can then move up a street as if it’s an array of ways, starting at 0 and then extending in both directions - at each node it can move to any other way (like a junction) so long as it evaluates the rules for entering each way in turn (so, a walker could move from 2 to -2 but a wheelchair user would not, because barrier = kerb implies wheelchair = no.

On dual carriageways it might look more like:

name = What a fast street!
barrier = guard_rail
surface = asphalt
complex-way:5:highway = footway
complex-way:5:footway = sidewalk
complex-way:4:barrier = kerb
complex-way:3:highway = trunk
complex-way:2:divider = dashed_line
complex-way:1:highway = trunk
complex-way:-1:highway = trunk
complex-way:-2:divider = solid_line
complex-way:-3:highway = trunk
complex-way:-3:bus:lanes = yes
complex-way:-4:barrier = kerb
complex-way:-5:highway = footway
complex-way:-5:footway = sidewalk

Then if connecting, say, to a footpath, you would tag on the footpath:

highway = footway
footway = path
complex-way:0:from = -5

Which would tell a router that you can only navigate to the footway from complex way -5 on the connecting road :slight_smile:

(I’m making this up as I go along, this could certainly be improved upon)

What happens when there’s an object between complex-ways that isn’t a line? For example, a 16th century sacristy?

The intention would be to use this for cohesive streets; on something like that you’d keep the roads but count out only in one direction for the additional component ways.

For what it’s worth, the tension between lane-level geometric precision and topological correctness is not new to OSM. Of the proprietary map vendors I’ve looked into, most seem to take a “why not both?” approach. For an extreme example, Mapbox has replaced OSM with Zenrin in Japan for most purposes. As I recall, Zenrin offers multiple layers that don’t really interact with each other, such as:

  • A layer for mid-zoom rendering that represents streets as lines
  • A layer for high-zoom rendering that represents streets as areas while representing lanes and curbs as lines, replete with hints about where to label these features
  • A layer for car navigation that represents actual vehicle trajectories, including lane lines curving at intersections
  • A layer for three-dimensional models of bridges
  • A layer for public transit routing that does a beeline dash between two coordinates whenever none of the intermediate details are relevant to guidance instructions

I don’t know how they keep all these layers consistent internally, but their products are optimized around specific use cases without compromises. This is the kind of thing we’d traditionally expect data consumers to produce based on our data. Maybe that’s a good starting point for understanding any gaps in our current data model.

2 Likes

Man I would so love to have this sort of level of detail separation across many aspects of OSM. Conflicts over micro vs macro mapping styles are so annoying.

Zenrin doesn’t give hints as to where to label features - it gives actual label positions, font sizes, etc. Its format is designed so that you can reproduce their exact cartography but if you want your own cartography you have to convert it.

1 Like

I’m having a hard time envisaging how this works! Trying:

There is a longitudinal central way, which acts as the reference way, representing the entire road.
Other longitudinal elements are defined by set-offs from the reference way.
The measurements on many complex roads I know change all the time, so you’ll have many nodes on this central reference way, each storing the information about relative positions of the longitudinal elements on this road. Thus, the other ways are not strings of actual nodes, but computed from the relative positions given by the nodes.

If this is correct, I think that editors still would ask the mapper to draw the longitudinal lines on the map, then calculate the values to be stored with the nodes.. And you would need a node for every change of every longitudinal line.

Or am I totally misinterpreting the idea?

Don’t we already kind-of have that? Thanks to keys such as shoulder, verge, cycleway, sidewalk, etc.? (and type=connectivity relations) including all their possible variants like :left, :width

Sure that it isn’t optimal and doesn’t cover all the possible cases. But should work the same as your proposal in the more common scenarios? (and has some degree of support already)
Seems as abstract as specifying -1 or +2, minus the possibility of reordering

The biggest issue IMO is that there seems to be no widely supported way of specifying connections between parts where the “sub-ways” are mapped together and separately, which results e.g. in jagged sidewalks. But I don’t see how this proposal would solve that…

I did say I was making it up as I was going along :sweat_smile: sorry if it’s a bit impenetrable.

If we were to create a new element in OSM, yes (actually, while we’re at it, why not two new elements? The relative-node and the complex-way, which is actually a 2-dimensional array of nodes, which allow us to link up the nodes and the relative-nodes into a sort-of fabric?). But that would require a new API version and.. honestly, I can’t see that happening at this point.

So what I proposed above is actually not that - it’s simulating that, but it’s actually just one node and one way that’s constantly changing outfits to pretend that there are more ways :slight_smile: the router would keep a counter handy to store the “position” on the way, and so when reading the tags on the way it gets only the tags relevant to the “position” (and can move one step up and down, subject to the tags, like normal routing).

Yes, something I didn’t include would be a value for “position from the centre line”, which would allow for computing of e.g. crossings, and we’d want to create lots of nodes to store changes in that position - but we do that anyway, with nodes to control the individual ways we currently use. It would probably overall be many less nodes.

No, I think you’re getting it (which validates that I’m not quite at the point of spouting complete rubbish yet :sweat_smile:) - the way this would be implemented would be in the editor, where we’d still place the nodes as normal - but behind the scenes the editor is actually adding tagging information to the centre-line (and on the other side, routers and renderers are unfolding that information to present/traverse).

The advantages would be that:

  • The editor could, once set up with all the component-ways, just “draw” entire multi-part streets, with the user then tweaking the positions of them as they go (or not, if they’re in a hurry).
  • Tags which are common to all components of a complex way would not be duplicated, as we currently do (or do not do) with e.g. sidewalks.
  • Routers would be able to “jump” between components of a complex way, since they’re actually not changing ways (just scrolling up and down the way-array). This would allow us to cross the road without having to find a crossing (or put in “pretend” crossings to enable better routing).
  • We could start mapping lanes individually in a way that allows the router to “pick a lane” and “change lanes”, which currently requires a bunch of assumptions (or other data).

The disadvantages would be that:

  • Anything that didn’t understand what a complex way was would be degraded to whatever we tagged on the centre-line (which would most commonly be a road, but often be the space between two roads).
  • ..it’s fucking weird, isn’t it :joy:

But it feels sort-of like the logical next step to me, so I wondered if it was something anyone else had experimented with.

Sort-of. As you say, it’s not optimal - we just tag on features and then let data consumers “have a guess” at what that all probably means. A data consumer could construct a complex way from the dataset but it would involve a lot of guesswork.

Well if we could create new elements then it would just be a case of linking up the component ways at the relative-nodes, that’s incredibly easy.

If we couldn’t.. yeh, I haven’t come up with a good way of doing that. A simple T-junction could be done with simple complex-way:0:from = -5 sort of syntax but I did leave a big gap there for what the schema would be like if you connected between more than two ways.

Maybe I’ll get out some graph paper :thinking:

This seems pretty fragile, considering how people edit OSM today. Editors would need to really handhold mappers so they don’t get the nodes out of sync as they refine a curve or connect other things to one of the ways.

Incidentally, the wiki did recommend keeping nodes aligned across a dual carriageway at one point, but there wasn’t much appetite for making that recommendation a reality, so it’s gone.

We already include a selection street/road details as tags of the centre way. You could say streets/roads are already complex ways. The main problem with this is that the exact geometry is missing, and that it is increasingly complex to add details of the other elements to the centre way, which gets cut up into a gazillion tiny pieces.
That is why sideroads, separated lanes, sidewalks and sidecycleways are drawn and tagged separately.

Your idea does not make life easier for the mappers - they will still have to map and tag the details. The details are just stored differently. The editor should facilitate this. At the database end, I think all information could be packed into nodes, ways and tags.
The renderer would have to compute a lot to show the virtual nodes and ways each with their own attributes.
The router could probably simply use the centerway and determine from its type and tags if the road user is allowed or not. The profiles would have to know the exact tags used for this complex road system. Renderings of the calculated navigation itinerary, and navigation announcements and instructions could be refined using the information about carriage ways, lanes, sidewalks and cycleways, tram tracks, bus lanes, hgv-lanes and what have you.

This all to facilitate that the street name applies to all the parts, and that routing can switch to a different lane or component way more easily.

Now where did I put my pro-con-scales again?

Yes, this would almost certainly not work “as-is” - the interface would have to present the components and do all the tagging for the user. The tags would also need to go under a namespace for the concept so they don’t interfere with existing tools, which is a bit of a grey area if only one editor, router and renderer supports the tags.

And fwiw I’m not really proposing it, more ideating on it and wondering out loud if there have been any attempts to do this sort of thing. I was hoping someone had attempted it and proven why it doesn’t work :joy:

With that said, if we’re going to do separated sidewalks, why not separated lanes? And if not separated names, why not a schema for complex ways?

Come to think of it, is there a JOSM function or plugin to round a way with extra nodes added as needed? I spend a lot of time grabbing plus signs and moving them half a millimeter.

It’s a fair question to ask. The way we do things is not necessarily how our competitors do things. I recall that Google once gave a journalist an inside look at their internal mapping process, showing a screenshot of their internal editor with lane lines and such. There’s even a whole cottage industry of “HD mapping” platforms that want the automotive industry to believe that OSM’s centerline-based model is obsolete compared to their point clouds and lane-level detail.

In the end, increasing detail comes with tradeoffs, because our fundamental constraint is that our mappers do things by hand. Traffic lanes and bike lanes can certainly have idiosyncratic geometries, but not nearly as often as sidewalks and sidepaths. The recent push for formalizing a road marking tagging scheme facilitates detailed rendering use cases around these idiosyncratic lane geometries when the physical separation principle doesn’t suffice. To the extent that routers need something analogous, it’s only at the most hyperdetailed scale – the scale of pedestrians – hence the focus on sidewalks and sidepaths.

1 Like