1-- This config example file is released into the Public Domain.
2
3-- This is a very simple Lua config for the Flex output not intended for
4-- real-world use. Look at and understand "simple.lua" first, before looking
5-- at this file. This file will show some options around geometry processing.
6-- After you have understood this file, go on to "data-types.lua".
7
8local tables = {}
9
10tables.pois = osm2pgsql.define_node_table('pois', {
11    { column = 'tags', type = 'jsonb' },
12    -- Create a geometry column for point geometries. The geometry will be
13    -- in web mercator, EPSG 3857.
14    { column = 'geom', type = 'point' },
15})
16
17tables.ways = osm2pgsql.define_way_table('ways', {
18    { column = 'tags', type = 'jsonb' },
19    -- Create a geometry column for linestring geometries. The geometry will
20    -- be in latlong (WGS84), EPSG 4326.
21    { column = 'geom', type = 'linestring', projection = 4326 },
22})
23
24tables.polygons = osm2pgsql.define_area_table('polygons', {
25    { column = 'tags', type = 'jsonb' },
26    { column = 'geom', type = 'geometry' },
27    -- The 'area' type is used to store the calculated area of a polygon
28    -- feature. This can be used in style sheets to only render larger polygons
29    -- in small zoom levels. This will use the area in web mercator projection,
30    -- you can set 'projection = 4326' to calculate the area in WGS84. Other
31    -- projections are currently not supported.
32    { column = 'area', type = 'area' },
33})
34
35tables.boundaries = osm2pgsql.define_relation_table('boundaries', {
36    { column = 'type', type = 'text' },
37    { column = 'tags', type = 'jsonb' },
38    -- Boundaries will be stitched together from relation members into long
39    -- linestrings. This is a multilinestring column because sometimes the
40    -- boundaries are not contiguous.
41    { column = 'geom', type = 'multilinestring' },
42})
43
44-- Tables don't have to have a geometry column. This one will only collect
45-- all the names of pubs but without any location information.
46tables.pubs = osm2pgsql.define_node_table('pubs', {
47    { column = 'name', type = 'text' }
48})
49
50-- Helper function to remove some of the tags we usually are not interested in.
51-- Returns true if there are no tags left.
52function clean_tags(tags)
53    tags.odbl = nil
54    tags.created_by = nil
55    tags.source = nil
56    tags['source:ref'] = nil
57
58    return next(tags) == nil
59end
60
61-- Helper function that looks at the tags and decides if this is possibly
62-- an area.
63function has_area_tags(tags)
64    if tags.area == 'yes' then
65        return true
66    end
67    if tags.area == 'no' then
68        return false
69    end
70
71    return tags.aeroway
72        or tags.amenity
73        or tags.building
74        or tags.harbour
75        or tags.historic
76        or tags.landuse
77        or tags.leisure
78        or tags.man_made
79        or tags.military
80        or tags.natural
81        or tags.office
82        or tags.place
83        or tags.power
84        or tags.public_transport
85        or tags.shop
86        or tags.sport
87        or tags.tourism
88        or tags.water
89        or tags.waterway
90        or tags.wetland
91        or tags['abandoned:aeroway']
92        or tags['abandoned:amenity']
93        or tags['abandoned:building']
94        or tags['abandoned:landuse']
95        or tags['abandoned:power']
96        or tags['area:highway']
97end
98
99function osm2pgsql.process_node(object)
100    if clean_tags(object.tags) then
101        return
102    end
103
104    -- The 'geom' column is not mentioned here. So the default geometry
105    -- transformation for a column of type 'point' will be used and the
106    -- node location will be written as Point geometry into the database.
107    tables.pois:add_row({
108        tags = object.tags
109    })
110
111    if object.tags.amenity == 'pub' then
112        tables.pubs:add_row({
113            name = object.tags.name
114        })
115    end
116end
117
118function osm2pgsql.process_way(object)
119    if clean_tags(object.tags) then
120        return
121    end
122
123    -- A closed way that also has the right tags for an area is a polygon.
124    if object.is_closed and has_area_tags(object.tags) then
125        tables.polygons:add_row({
126            tags = object.tags,
127            -- The 'geom' column of the 'polygons' table is of type 'geometry'.
128            -- There are several ways a way geometry could be converted to
129            -- a geometry so you have to specify the geometry transformation.
130            -- In this case we want to convert the way data to an area.
131            geom = { create = 'area' }
132        })
133    else
134        -- The 'geom' column of the 'ways' table is of type 'linestring'.
135        -- Osm2pgsql knows how to create a linestring from a way, but
136        -- if you want to specify extra parameters to this conversion,
137        -- you have to do this explicitly. In this case we want to split
138        -- long linestrings.
139        --
140        -- Set "split_at" to the maximum length the pieces should have. This
141        -- length is in map units, so it depends on the projection used.
142        -- "Traditional" osm2pgsql sets this to 1 for 4326 geometries and
143        -- 100000 for 3857 (web mercator) geometries. The default is 0.0, which
144        -- means no splitting.
145        --
146        -- Note that if a way is split this will automatically create
147        -- multiple rows that are identical except for the geometry.
148        tables.ways:add_row({
149            tags = object.tags,
150            geom = { create = 'line', split_at = 1 }
151        })
152    end
153end
154
155function osm2pgsql.process_relation(object)
156    if clean_tags(object.tags) then
157        return
158    end
159
160    local type = object:grab_tag('type')
161
162    -- Store boundary relations as multilinestrings
163    if type == 'boundary' then
164        tables.boundaries:add_row({
165            type = object:grab_tag('boundary'),
166            tags = object.tags,
167            -- For relations there is no clear definition what their geometry
168            -- is, so you have to declare the geometry transformation
169            -- explicitly.
170            geom = { create = 'line' }
171        })
172        return
173    end
174
175    -- Store multipolygon relations as polygons
176    if type == 'multipolygon' then
177        tables.polygons:add_row({
178            tags = object.tags,
179            -- For relations there is no clear definition what their geometry
180            -- is, so you have to declare the geometry transformation
181            -- explicitly.
182            geom = { create = 'area' }
183        })
184    end
185end
186
187