1-- This config example file is released into the Public Domain.
2
3-- This file shows how to use multi-stage processing to bring tags from
4-- relations into ways.
5
6-- This will only import ways tagged as highway. The 'rel_refs' text column
7-- will contain a comma-separated list of all ref tags found in parent
8-- relations with type=route and route=road. The 'rel_ids' column will be
9-- an integer array containing the relation ids. These could be used, for
10-- instance, to look up other relation tags from the 'routes' table.
11
12local tables = {}
13
14tables.highways = osm2pgsql.define_way_table('highways', {
15    { column = 'tags',     type = 'jsonb' },
16    { column = 'rel_refs', type = 'text' }, -- for the refs from the relations
17    { column = 'rel_ids',  sql_type = 'int8[]' }, -- array with integers (for relation IDs)
18    { column = 'geom',     type = 'linestring' },
19})
20
21-- Tables don't have to have a geometry column
22tables.routes = osm2pgsql.define_relation_table('routes', {
23    { column = 'tags', type = 'jsonb' },
24})
25
26-- This will be used to store information about relations queryable by member
27-- way id. It is a table of tables. The outer table is indexed by the way id,
28-- the inner table indexed by the relation id. This way even if the information
29-- about a relation is added twice, it will be in there only once. It is
30-- always good to write your osm2pgsql Lua code in an idempotent way, i.e.
31-- it can be called any number of times and will lead to the same result.
32local w2r = {}
33
34function clean_tags(tags)
35    tags.odbl = nil
36    tags.created_by = nil
37    tags.source = nil
38    tags['source:ref'] = nil
39
40    return next(tags) == nil
41end
42
43function osm2pgsql.process_way(object)
44    -- We are only interested in highways
45    if not object.tags.highway then
46        return
47    end
48
49    clean_tags(object.tags)
50
51    -- Data we will store in the "highways" table always has the tags from
52    -- the way
53    local row = {
54        tags = object.tags
55    }
56
57    -- If there is any data from parent relations, add it in
58    local d = w2r[object.id]
59    if d then
60        local refs = {}
61        local ids = {}
62        for rel_id, rel_ref in pairs(d) do
63            refs[#refs + 1] = rel_ref
64            ids[#ids + 1] = rel_id
65        end
66        table.sort(refs)
67        table.sort(ids)
68        row.rel_refs = table.concat(refs, ',')
69        row.rel_ids = '{' .. table.concat(ids, ',') .. '}'
70    end
71
72    tables.highways:add_row(row)
73end
74
75-- This function is called for every added, modified, or deleted relation.
76-- Its only job is to return the ids of all member ways of the specified
77-- relation we want to see in stage 2 again. It MUST NOT store any information
78-- about the relation!
79function osm2pgsql.select_relation_members(relation)
80    -- Only interested in relations with type=route, route=road and a ref
81    if relation.tags.type == 'route' and relation.tags.route == 'road' and relation.tags.ref then
82        return { ways = osm2pgsql.way_member_ids(relation) }
83    end
84end
85
86-- The process_relation() function should store all information about way
87-- members that might be needed in stage 2.
88function osm2pgsql.process_relation(object)
89    if object.tags.type == 'route' and object.tags.route == 'road' and object.tags.ref then
90        tables.routes:add_row({
91            tags = object.tags
92        })
93
94        -- Go through all the members and store relation ids and refs so they
95        -- can be found by the way id.
96        for _, member in ipairs(object.members) do
97            if member.type == 'w' then
98                if not w2r[member.ref] then
99                    w2r[member.ref] = {}
100                end
101                w2r[member.ref][object.id] = object.tags.ref
102            end
103        end
104    end
105end
106
107