Advanced relationships/Implementation

From OpenStreetMap Wiki
Jump to: navigation, search

This page has ideas on how advanced relationships could be expressed in the data model.

Link tables for ways, nodes, and segments

This is User:rjmunro's original idea.

It would be implimented with 9 new tables in the database:

  • link_node_node
  • link_segment_node
  • link_way_node
  • link_node_segment
  • link_segment_segment
  • link_way_segment
  • link_node_way
  • link_segment_way
  • link_way_way

Each table would have 4 columns:

  • from_id
  • to_id
  • key
  • value

The first two columns would reference the node, segment or way table's ID as appropriate. The primary key would be (from_id,to_id,key)

The value would be optional, and probably not needed very often.

There would need to be extensions to the api to fetch relationships from/to things, and the bbox query would return extra data containing all the relationships that have one or other end inside the area that is being fetched. It may be possible to impliment a backwards compatible mode, where if an old client requests an object with a relationship, they get the relationship expressed as a normal tag:

k=relto:[node|segment|way][id] v="[key]:[value]"

if they were the from_id or:

k="relfrom:[node|segment|way][id]" v="[key]:[value]"

if they were the to_id.

One relationship table, one link table

A suggestion by User:Frederik Ramm:

Have one table for relationships and one for memerships in these:


  • id integer (auto-numbering)
  • type string (e.g. "turn restriction", "is-in", ... / ideally modelled as integer pointing to a list of fixed options, don't like the free-form way all that much but maybe it has to be because of the "spirit"?)
  • maybe tags like we have them elsewhere (to model turn restrictions that only apply to lorries etc.)


  • object_type enum(node,segment(?),way) + possibly more
  • object_id integer (the node id, segment id, way id)
  • relationship_id integer (pointer into relationships)
  • role string (e.g. for a turn restriction: "coming from", "turning at", "going into", or for an is-in relation: "member" and "container" or so - ideally this should also be an integer pointing to a list of fixed options of which only a few are applicable to each type op relationship!)

This would mean that if you have an object and want to find out whether it is part of a relationship, you can find that out with one single "select" statement involving only one table.

There would be some logic behind relationships which may or may not be built into the system - there will be a certain number of known relationship types, and these will have a varying number of "free places" for partners. I imagine a typical turn restriction as having three partners (the way you come in from, the node you turn at, and the way you want to go out on). A "is-on-bridge" relation would have one "special" place for the bridge way itself, and either every way sharing the bridge sets up its own relationship or we have one relationship that may have multiple ways as partners for the bridge way.

If we allow multiple partners (also in an is-in relationship - if you have 5 suburbs of one city, you could have 5 is-in relationships with two partners each, or one is-in relationship with six partners) then we need to define which partners can be removed without destroying the validity of the relationship; a bit complex maybe.