Skip to content

Commit 49d3282

Browse files
committed
Fix shortbread boundary processing in regards to disputed boundaries
The way disputed boundaries are implemented was not correct. Generally boundaries should be processed as if disputed boundaries do not exists. But then all boundary lines created from ways that have the disputed flag set or that are in a relation tagged boundary=disputed will be marked as disputed. Note that the relation that marks a way as disputed is not the same relation that marks a way as part of some specific admin boundary. The first is tagged boundary=disputed, the second is tagged boundary=administrative. This is based on the work in #10 but rewrites the code to be (hopefully) easier to understand. Note that this only fixes the version for shortbread_v1, the version for shortbread_v1_gen also needs updating which will come later.
1 parent b0cd6fb commit 49d3282

File tree

1 file changed

+30
-34
lines changed

1 file changed

+30
-34
lines changed

themes/shortbread_v1/topics/boundaries.lua

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ themepark:add_table{
1212
ids_type = 'way',
1313
geom = 'linestring',
1414
columns = themepark:columns({
15-
{ column = 'admin_level', type = 'int' },
15+
{ column = 'admin_level', type = 'int', not_null = true },
1616
{ column = 'maritime', type = 'bool' },
1717
{ column = 'disputed', type = 'bool' },
1818
}),
@@ -29,27 +29,23 @@ themepark:add_table{
2929
}
3030
}
3131

32-
local rinfos = {}
33-
3432
-- ---------------------------------------------------------------------------
33+
-- Storage of information from boundary relations for use by boundary ways
34+
-- (two-stage processing).
3535

36-
-- Check if this looks like a boundary and return admin_level as number
37-
-- Return nil if this is not a valid boundary.
38-
local function get_admin_level(tags)
39-
local type = tags.type
36+
-- Minimum admin level of all relations that reference a way id
37+
local min_admin_level = {}
4038

41-
if type == 'boundary' or type == 'multipolygon' then
42-
local boundary = tags.boundary
43-
if boundary == 'administrative' or boundary == 'disputed' then
44-
return tonumber(tags.admin_level)
45-
end
46-
end
47-
end
39+
-- For all way ids that are in a relation tagged boundary=disputed
40+
local ways_in_disputed_boundary_relation = {}
41+
42+
-- ---------------------------------------------------------------------------
4843

49-
-- Check the (numeric) admin level. Change this depending on which admin
50-
-- levels you want to process. Shortbread only shows 2 and 4.
51-
local function valid_admin_level(level)
52-
return level == 2 or level == 4
44+
-- Shortbread is only interested in level 2 and level 4 admin boundaries.
45+
local function is_admin_boundary(tags)
46+
return (tags.type == 'boundary' or tags.type == 'multipolygon')
47+
and tags.boundary == 'administrative'
48+
and (tags.admin_level == '2' or tags.admin_level == '4')
5349
end
5450

5551
-- ---------------------------------------------------------------------------
@@ -59,45 +55,45 @@ themepark:add_proc('way', function(object, data)
5955
return
6056
end
6157

62-
local info = rinfos[object.id]
63-
if not info then
58+
local admin_level = min_admin_level[object.id]
59+
if not admin_level then
6460
return
6561
end
6662

6763
local t = object.tags
6864
local a = {
69-
admin_level = info.admin_level,
65+
admin_level = admin_level,
7066
maritime = (t.maritime and (t.maritime == 'yes' or t.natural == 'coastline')),
71-
disputed = info.disputed or (t.disputed and t.disputed == 'yes'),
67+
disputed = (t.disputed and t.disputed == 'yes') or ways_in_disputed_boundary_relation[object.id],
7268
geom = object:as_linestring()
7369
}
7470

7571
themepark:insert('boundaries', a, t)
7672
end)
7773

7874
themepark:add_proc('select_relation_members', function(relation)
79-
if valid_admin_level(get_admin_level(relation.tags)) then
75+
if is_admin_boundary(relation.tags) then
8076
return { ways = osm2pgsql.way_member_ids(relation) }
8177
end
8278
end)
8379

8480
themepark:add_proc('relation', function(object, data)
85-
local t = object.tags
81+
if is_admin_boundary(object.tags) then
82+
local admin_level = tonumber(object.tags.admin_level)
8683

87-
local admin_level = get_admin_level(t)
84+
for _, id in ipairs(osm2pgsql.way_member_ids(object)) do
85+
if not min_admin_level[id] or min_admin_level[id] > admin_level then
86+
min_admin_level[id] = admin_level
87+
end
88+
end
8889

89-
if not valid_admin_level(admin_level) then
9090
return
9191
end
9292

93-
for _, member in ipairs(object.members) do
94-
if member.type == 'w' then
95-
if not rinfos[member.ref] then
96-
rinfos[member.ref] = { admin_level = admin_level }
97-
elseif rinfos[member.ref].admin_level > admin_level then
98-
rinfos[member.ref].admin_level = admin_level
99-
end
100-
rinfos[member.ref].disputed = (t.boundary == 'disputed')
93+
-- All ways in relations tagged boundary=disputed are flagged as disputed
94+
if object.tags.boundary == 'disputed' then
95+
for _, id in ipairs(osm2pgsql.way_member_ids(object)) do
96+
ways_in_disputed_boundary_relation[id] = true
10197
end
10298
end
10399
end)

0 commit comments

Comments
 (0)