Skip to content

Commit 47da67c

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 boundary lines are flagged as disputed if they are created from ways * that have the tag disputed=yes, or * that are in a relation tagged boundary=disputed with no admin_level set or an admin_level smaller or equal to the admin_level that the boundary line has (which is the smallest of any boundary relation the way is a member of) 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 47da67c

File tree

1 file changed

+46
-33
lines changed

1 file changed

+46
-33
lines changed

themes/shortbread_v1/topics/boundaries.lua

Lines changed: 46 additions & 33 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,24 @@ 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+
-- Minimum admin level of all relations tagged boundary=disputed that
40+
-- reference a way id
41+
local min_disputed_admin_level = {}
4842

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
43+
-- ---------------------------------------------------------------------------
44+
45+
-- Shortbread is only interested in level 2 and level 4 admin boundaries.
46+
local function is_admin_boundary(tags)
47+
return (tags.type == 'boundary' or tags.type == 'multipolygon')
48+
and tags.boundary == 'administrative'
49+
and (tags.admin_level == '2' or tags.admin_level == '4')
5350
end
5451

5552
-- ---------------------------------------------------------------------------
@@ -59,45 +56,61 @@ themepark:add_proc('way', function(object, data)
5956
return
6057
end
6158

62-
local info = rinfos[object.id]
63-
if not info then
59+
local admin_level = min_admin_level[object.id]
60+
if not admin_level then
6461
return
6562
end
6663

6764
local t = object.tags
65+
66+
-- Set disputed flag either from disputed tag on the way...
67+
local disputed = (t.disputed == 'yes')
68+
69+
-- .. or from a parent relation with boundary=disputed
70+
if min_disputed_admin_level[object.id] and min_disputed_admin_level[object.id] <= admin_level then
71+
disputed = true
72+
end
73+
6874
local a = {
69-
admin_level = info.admin_level,
75+
admin_level = admin_level,
7076
maritime = (t.maritime and (t.maritime == 'yes' or t.natural == 'coastline')),
71-
disputed = info.disputed or (t.disputed and t.disputed == 'yes'),
77+
disputed = disputed,
7278
geom = object:as_linestring()
7379
}
7480

7581
themepark:insert('boundaries', a, t)
7682
end)
7783

7884
themepark:add_proc('select_relation_members', function(relation)
79-
if valid_admin_level(get_admin_level(relation.tags)) then
85+
if is_admin_boundary(relation.tags) then
8086
return { ways = osm2pgsql.way_member_ids(relation) }
8187
end
8288
end)
8389

8490
themepark:add_proc('relation', function(object, data)
85-
local t = object.tags
91+
if is_admin_boundary(object.tags) then
92+
local admin_level = tonumber(object.tags.admin_level)
8693

87-
local admin_level = get_admin_level(t)
94+
for _, id in ipairs(osm2pgsql.way_member_ids(object)) do
95+
if not min_admin_level[id] or min_admin_level[id] > admin_level then
96+
min_admin_level[id] = admin_level
97+
end
98+
end
8899

89-
if not valid_admin_level(admin_level) then
90100
return
91101
end
92102

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
103+
if object.tags.boundary == 'disputed' then
104+
-- Ways in relations tagged boundary=disputed are flagged as disputed
105+
-- if either the relation doesn't have an admin_level tag or the
106+
-- admin_level tag is <= the admin level the way got from the
107+
-- boundary=administrative relation(s).
108+
local admin_level = tonumber(object.tags.admin_level or 1)
109+
110+
for _, id in ipairs(osm2pgsql.way_member_ids(object)) do
111+
if not min_disputed_admin_level[id] or min_disputed_admin_level[id] > admin_level then
112+
min_disputed_admin_level[id] = admin_level
99113
end
100-
rinfos[member.ref].disputed = (t.boundary == 'disputed')
101114
end
102115
end
103116
end)

0 commit comments

Comments
 (0)