Skip to content

Commit b87b4c4

Browse files
authored
Merge pull request #1744 from joto/flex-config-examples-insert
Update/add some flex config example files using the new insert()
2 parents 707af52 + 323b8fc commit b87b4c4

File tree

5 files changed

+310
-245
lines changed

5 files changed

+310
-245
lines changed

flex-config/addresses.lua

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
-- This config example file is released into the Public Domain.
2+
3+
-- Get a location for all objects with addresses. If mapped as a polygon or
4+
-- multipolygon, the centroid will be used.
5+
6+
local addrs = osm2pgsql.define_table({
7+
name = 'addrs',
8+
ids = { type = 'any', id_column = 'osm_id', type_column = 'osm_type' },
9+
columns = {
10+
{ column = 'name', type = 'text' },
11+
{ column = 'country', type = 'text' },
12+
{ column = 'state', type = 'text' },
13+
{ column = 'postcode', type = 'text' },
14+
{ column = 'city', type = 'text' },
15+
{ column = 'place', type = 'text' },
16+
{ column = 'street', type = 'text' },
17+
{ column = 'housenumber', type = 'text' },
18+
{ column = 'geom', type = 'point', projection = 4326, not_null = true }
19+
}
20+
})
21+
22+
function get_address(tags)
23+
local addr = {}
24+
local count = 0
25+
26+
for _, key in ipairs({'housenumber', 'street', 'city', 'postcode', 'country', 'state', 'place'}) do
27+
local a = tags['addr:' .. key]
28+
if a then
29+
addr[key] = a
30+
count = count + 1
31+
end
32+
end
33+
34+
return count > 1, addr
35+
end
36+
37+
function osm2pgsql.process_node(object)
38+
local any, addr = get_address(object.tags)
39+
if any then
40+
addr.name = object.tags.name
41+
addr.geom = object:as_point()
42+
addrs:insert(addr)
43+
end
44+
end
45+
46+
function osm2pgsql.process_way(object)
47+
if object.is_closed then
48+
local any, addr = get_address(object.tags)
49+
if any then
50+
addr.name = object.tags.name
51+
addr.geom = object:as_polygon():centroid()
52+
addrs:insert(addr)
53+
end
54+
end
55+
end
56+
57+
function osm2pgsql.process_relation(object)
58+
if object.tags.type == 'multipolygon' then
59+
local any, addr = get_address(object.tags)
60+
if any then
61+
addr.name = object.tags.name
62+
addr.geom = object:as_multipolygon():centroid()
63+
addrs:insert(addr)
64+
end
65+
end
66+
end
67+

flex-config/generic.lua

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,28 @@ local tables = {}
1111

1212
tables.points = osm2pgsql.define_node_table('points', {
1313
{ column = 'tags', type = 'jsonb' },
14-
{ column = 'geom', type = 'point', projection = srid },
14+
{ column = 'geom', type = 'point', projection = srid, not_null = true },
1515
})
1616

1717
tables.lines = osm2pgsql.define_way_table('lines', {
1818
{ column = 'tags', type = 'jsonb' },
19-
{ column = 'geom', type = 'linestring', projection = srid },
19+
{ column = 'geom', type = 'linestring', projection = srid, not_null = true },
2020
})
2121

2222
tables.polygons = osm2pgsql.define_area_table('polygons', {
2323
{ column = 'tags', type = 'jsonb' },
24-
{ column = 'geom', type = 'geometry', projection = srid },
24+
{ column = 'geom', type = 'geometry', projection = srid, not_null = true },
2525
{ column = 'area', type = 'area' },
2626
})
2727

2828
tables.routes = osm2pgsql.define_relation_table('routes', {
2929
{ column = 'tags', type = 'jsonb' },
30-
{ column = 'geom', type = 'multilinestring', projection = srid },
30+
{ column = 'geom', type = 'multilinestring', projection = srid, not_null = true },
3131
})
3232

3333
tables.boundaries = osm2pgsql.define_relation_table('boundaries', {
3434
{ column = 'tags', type = 'jsonb' },
35-
{ column = 'geom', type = 'multilinestring', projection = srid },
35+
{ column = 'geom', type = 'multilinestring', projection = srid, not_null = true },
3636
})
3737

3838
-- These tag keys are generally regarded as useless for most rendering. Most
@@ -225,8 +225,9 @@ function osm2pgsql.process_node(object)
225225
return
226226
end
227227

228-
tables.points:add_row({
229-
tags = object.tags
228+
tables.points:insert({
229+
tags = object.tags,
230+
geom = object:as_point()
230231
})
231232
end
232233

@@ -236,13 +237,14 @@ function osm2pgsql.process_way(object)
236237
end
237238

238239
if object.is_closed and has_area_tags(object.tags) then
239-
tables.polygons:add_row({
240+
tables.polygons:insert({
240241
tags = object.tags,
241-
geom = { create = 'area' }
242+
geom = object:as_polygon()
242243
})
243244
else
244-
tables.lines:add_row({
245-
tags = object.tags
245+
tables.lines:insert({
246+
tags = object.tags,
247+
geom = object:as_linestring()
246248
})
247249
end
248250
end
@@ -255,25 +257,25 @@ function osm2pgsql.process_relation(object)
255257
end
256258

257259
if relation_type == 'route' then
258-
tables.routes:add_row({
260+
tables.routes:insert({
259261
tags = object.tags,
260-
geom = { create = 'line' }
262+
geom = object:as_multilinestring()
261263
})
262264
return
263265
end
264266

265267
if relation_type == 'boundary' or (relation_type == 'multipolygon' and object.tags.boundary) then
266-
tables.boundaries:add_row({
268+
tables.boundaries:insert({
267269
tags = object.tags,
268-
geom = { create = 'line' }
270+
geom = object:as_multilinestring():line_merge()
269271
})
270272
return
271273
end
272274

273275
if relation_type == 'multipolygon' then
274-
tables.polygons:add_row({
276+
tables.polygons:insert({
275277
tags = object.tags,
276-
geom = { create = 'area' }
278+
geom = object:as_multipolygon()
277279
})
278280
end
279281
end
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
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+
--
8+
-- This is the new version of the file "geometries.lua". It uses the new
9+
-- "insert()" call available from version 1.7.0.
10+
11+
local tables = {}
12+
13+
tables.pois = osm2pgsql.define_node_table('pois', {
14+
{ column = 'tags', type = 'jsonb' },
15+
-- Create a geometry column for point geometries. The geometry will be
16+
-- in web mercator, EPSG 3857.
17+
--
18+
-- Usually we want to declare all geometry columns as "NOT NULL". If
19+
-- osm2pgsql encounters an invalid geometry (for whatever reason) it will
20+
-- generate a null geometry which will not be written to the database if
21+
-- "not_null" is set. The result is that broken geometries will just be
22+
-- silently ignored.
23+
{ column = 'geom', type = 'point', not_null = true },
24+
})
25+
26+
tables.ways = osm2pgsql.define_way_table('ways', {
27+
{ column = 'tags', type = 'jsonb' },
28+
-- Create a geometry column for linestring geometries. The geometry will
29+
-- be in latlong (WGS84), EPSG 4326.
30+
{ column = 'geom', type = 'linestring', projection = 4326, not_null = true },
31+
})
32+
33+
tables.polygons = osm2pgsql.define_area_table('polygons', {
34+
{ column = 'tags', type = 'jsonb' },
35+
-- If we don't set "not_null = true", we'll get NULL columns for invalid
36+
-- geometries. This can be useful if we want to detect those cases or
37+
-- if we have multiple geometry columns and some of them can be valid
38+
-- and others not.
39+
{ column = 'geom', type = 'geometry', projection = 4326 },
40+
{ column = 'area', type = 'real' },
41+
})
42+
43+
tables.boundaries = osm2pgsql.define_relation_table('boundaries', {
44+
{ column = 'type', type = 'text' },
45+
{ column = 'tags', type = 'jsonb' },
46+
-- Boundaries will be stitched together from relation members into long
47+
-- linestrings. This is a multilinestring column because sometimes the
48+
-- boundaries are not contiguous.
49+
{ column = 'geom', type = 'multilinestring', not_null = true },
50+
})
51+
52+
-- Tables don't have to have a geometry column. This one will only collect
53+
-- all the names of pubs but without any location information.
54+
tables.pubs = osm2pgsql.define_node_table('pubs', {
55+
{ column = 'name', type = 'text' }
56+
})
57+
58+
-- Helper function to remove some of the tags we usually are not interested in.
59+
-- Returns true if there are no tags left.
60+
function clean_tags(tags)
61+
tags.odbl = nil
62+
tags.created_by = nil
63+
tags.source = nil
64+
tags['source:ref'] = nil
65+
66+
return next(tags) == nil
67+
end
68+
69+
-- Helper function that looks at the tags and decides if this is possibly
70+
-- an area.
71+
function has_area_tags(tags)
72+
if tags.area == 'yes' then
73+
return true
74+
end
75+
if tags.area == 'no' then
76+
return false
77+
end
78+
79+
return tags.aeroway
80+
or tags.amenity
81+
or tags.building
82+
or tags.harbour
83+
or tags.historic
84+
or tags.landuse
85+
or tags.leisure
86+
or tags.man_made
87+
or tags.military
88+
or tags.natural
89+
or tags.office
90+
or tags.place
91+
or tags.power
92+
or tags.public_transport
93+
or tags.shop
94+
or tags.sport
95+
or tags.tourism
96+
or tags.water
97+
or tags.waterway
98+
or tags.wetland
99+
or tags['abandoned:aeroway']
100+
or tags['abandoned:amenity']
101+
or tags['abandoned:building']
102+
or tags['abandoned:landuse']
103+
or tags['abandoned:power']
104+
or tags['area:highway']
105+
end
106+
107+
function osm2pgsql.process_node(object)
108+
if clean_tags(object.tags) then
109+
return
110+
end
111+
112+
local geom = object:as_point()
113+
114+
tables.pois:insert({
115+
tags = object.tags,
116+
geom = geom -- the point will be automatically be projected to 3857
117+
})
118+
119+
if object.tags.amenity == 'pub' then
120+
tables.pubs:insert({
121+
name = object.tags.name
122+
})
123+
end
124+
end
125+
126+
function osm2pgsql.process_way(object)
127+
if clean_tags(object.tags) then
128+
-- return
129+
end
130+
131+
-- A closed way that also has the right tags for an area is a polygon.
132+
if object.is_closed and has_area_tags(object.tags) then
133+
-- Creating the polygon geometry takes time, so we do it once here
134+
-- and later store it in the table and use it to calculate the area.
135+
local geom = object:as_polygon()
136+
tables.polygons:insert({
137+
tags = object.tags,
138+
geom = geom,
139+
-- Calculate the area in Mercator projection and store in the
140+
-- area column
141+
area = geom:transform(3857):area()
142+
})
143+
else
144+
-- We want to split long lines into smaller segments. We can use
145+
-- the "segmentize" function for that. The parameter specifies the
146+
-- maximum length the pieces should have. This length is in map units,
147+
-- so it depends on the projection used.
148+
-- "Traditional" osm2pgsql sets this to 1 for 4326 geometries and
149+
-- 100000 for 3857 (web mercator) geometries.
150+
--
151+
-- Because the result of the segmentation is a multigeometry, we'll
152+
-- have to iterate over all the member geometries to be able to insert
153+
-- the data into a the 'geom' column of the 'ways' table which is of
154+
-- type 'linestring'. (We could have used a multilinestring geometry
155+
-- in our table instead.)
156+
local multi_geom = object:as_multilinestring():segmentize(1)
157+
for g in multi_geom:geometries() do
158+
tables.ways:insert({
159+
tags = object.tags,
160+
geom = g
161+
})
162+
end
163+
end
164+
end
165+
166+
function osm2pgsql.process_relation(object)
167+
if clean_tags(object.tags) then
168+
return
169+
end
170+
171+
local relation_type = object:grab_tag('type')
172+
173+
-- Store boundary relations as multilinestrings
174+
if relation_type == 'boundary' then
175+
tables.boundaries:insert({
176+
type = object:grab_tag('boundary'),
177+
tags = object.tags,
178+
-- For relations there is no clear definition what their geometry
179+
-- is, so you have to decide on the geometry transformation you
180+
-- want. In this case we want the boundary as multilinestring
181+
-- and we want lines merged as much as possible.
182+
geom = object:as_multilinestring():line_merge()
183+
})
184+
return
185+
end
186+
187+
-- Store multipolygon relations as polygons
188+
if relation_type == 'multipolygon' then
189+
local geom = object:as_multipolygon()
190+
tables.polygons:insert({
191+
tags = object.tags,
192+
-- For relations there is no clear definition what their geometry
193+
-- is, so you have to decide on the geometry transformation.
194+
-- In this case we know from the type tag its a (multi)polygon.
195+
geom = geom,
196+
-- Calculate the area in Mercator projection and store in the
197+
-- area column
198+
area = geom:transform(3857):area()
199+
})
200+
end
201+
end
202+

0 commit comments

Comments
 (0)