Relations¶
In OpenStreetMap, relations define logical or geographic relationships between other nodes, ways and relations.
The most common relation type is a multipolygon, but all other relations can be imported as well.
Multipolygons¶
Multipolygon relations are used to represent complex polygon geometries. They are also the only way to represent holes in polygons.
Multipolygon relations are automatically handled by Imposm for all polygon
tables.
The following mapping:
tables:
buildings:
type: polygon
mapping:
building: [__any__]
Inserts closed ways if they have a building
tag:
<way id="1001" version="1" timestamp="2011-11-11T00:11:11Z">
<nd ref="1001"/>
...
<nd ref="1001"/>
<tag k="building" v="yes"/>
</way>
It will also insert relations of the type multipolygon
with a building
tag:
<relation id="17101" version="1" timestamp="2011-11-11T00:11:11Z">
<member type="way" ref="17101" role="outer"/>
<member type="way" ref="17102" role="outer"/>
<tag k="type" v="multipolygon"/>
<tag k="building" v="yes"/>
</relation>
The roles are ignored by Imposm as not all holes are correctly tagged as inner
. Imposm uses geometry operations to verify if a member of a multipolygon is a hole, or if it is a separate polygon.
Old-style multipolygon relations with tags on the outer way, instead of the relation are no longer supported.
Other relations¶
OpenStreetMap also uses relations to map more complex features. Some examples:
Administrative areas with boundaries, capitals and label positions.
Bus/tram/train routes with the route itself, stops and platforms.
3D buildings with multiple parts that should not be computed as holes.
These relations can not be mapped to simple linestrings or polygons as they can contain a mix of different geometry types, or would result in invalid geometries (overlapping polygons).
The Imposm table types relation
and relation_member
allow you to import all relevant data for these relations.
relation_member
¶
The relation_member
table type inserts each member of the relation as a separate row. The relation_member
has access to the role and type value of each member. You can also import tags from the relation and from the member node, way or relation.
Example¶
You can use the following mapping:
route_members:
type: relation_member
columns:
- name: osm_id
type: id
- name: member
type: member_id
- name: index
type: member_index
- name: role
type: member_role
- name: type
type: member_type
- name: geometry
type: geometry
- name: relname
key: name
type: string
- name: name
key: name
type: string
from_member: true
- key: ref
name: ref
type: string
relation_types: [route]
mapping:
route: [bus]
to import a bus relation with stops, a platform and the route itself:
<relation id="100901" version="1" timestamp="2015-06-02T04:13:19Z">
<member type="node" ref="100101" role="stop_entry_only"/>
<member type="node" ref="100102" role="stop"/>
<member type="way" ref="100511" role="platform"/>
<member type="node" ref="100103" role="stop_exit_only"/>
<member type="way" ref="100501" role=""/>
<member type="way" ref="100502" role=""/>
<member type="way" ref="100503" role=""/>
<tag k="name" v="Bus 301: A => B"/>
<tag k="network" v="ABC"/>
<tag k="ref" v="301"/>
<tag k="route" v="bus"/>
<tag k="type" v="route"/>
</relation>
This will result in seven rows with the following columns:
Column |
Description |
---|---|
osm_id |
The ID of the relation. 100901 for all members. |
member |
The ID of the member. 100101, 100102, etc. |
index |
The index of the member. From 1 for 100101 to 7 for 100503. This can be used to query the bus stops in the correct order. |
role |
The role of the member. |
type |
0 for nodes, 1 for ways and 2 for other relations. |
geometry |
The geometry of the member. Point for nodes and linestring for ways. |
relname |
The value of the |
name |
The value of the |
ref |
The value of the |
You can insert the tags of the relation in a separate relation
table to avoid duplication and then use joins when querying the data.
Both osm_id
and member_id
columns are indexed in PostgreSQL by default to speed up these joins.
relation
¶
The relation
table type inserts the mapped element regardless of the resulting geometry. For example, this allows you to create a table with the metadata (name, reference, operator, etc.) of all available route relations. The actual geometries need to be joined from the members.
Example¶
The following mapping imports the bus route relation from above:
routes:
type: relation
columns:
- name: osm_id
type: id
- key: ref
name: ref
type: string
- name: network
key: network
type: string
relation_types: [route]
mapping:
route: [bus]
This will create a single row with the mapped columns.
Note
relation
tables do not support geometry columns. Use the geometries of the members, or use a polygon
table if your relations contain multipolygons.