@@ -11,8 +11,8 @@ themepark:add_table{
1111 name = ' boundaries' ,
1212 ids_type = ' way' ,
1313 geom = ' linestring' ,
14- columns = themepark :columns (' core/name ' , {
15- { column = ' admin_level' , type = ' int' },
14+ columns = themepark :columns ({
15+ { column = ' admin_level' , type = ' int' , not_null = true },
1616 { column = ' maritime' , type = ' bool' },
1717 { column = ' disputed' , type = ' bool' },
1818 }),
@@ -29,27 +29,33 @@ themepark:add_table{
2929 }
3030}
3131
32- local rinfos = {}
32+ -- ---------------------------------------------------------------------------
33+ -- Storage of information from boundary relations for use by boundary ways
34+ -- (two-stage processing).
35+
36+ -- Minimum admin level of all relations that reference a way id
37+ local min_admin_level = {}
38+
39+ -- Minimum admin level of all relations tagged boundary=disputed that
40+ -- reference a way id
41+ local min_disputed_admin_level = {}
3342
3443-- ---------------------------------------------------------------------------
3544
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
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' )
50+ end
4051
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
52+ -- Get numerical admin level from string, default to 1 if invalid
53+ local function get_admin_level (value )
54+ if not value or not string.match (value , ' ^[1-9][0-9]?$' ) then
55+ return 1
4656 end
47- end
4857
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
58+ return tonumber (value )
5359end
5460
5561-- ---------------------------------------------------------------------------
@@ -59,45 +65,61 @@ themepark:add_proc('way', function(object, data)
5965 return
6066 end
6167
62- local info = rinfos [object .id ]
63- if not info then
68+ local admin_level = min_admin_level [object .id ]
69+ if not admin_level then
6470 return
6571 end
6672
6773 local t = object .tags
74+
75+ -- Set disputed flag either from disputed tag on the way...
76+ local disputed = (t .disputed == ' yes' )
77+
78+ -- .. or from a parent relation with boundary=disputed
79+ if min_disputed_admin_level [object .id ] and min_disputed_admin_level [object .id ] <= admin_level then
80+ disputed = true
81+ end
82+
6883 local a = {
69- admin_level = info . admin_level ,
84+ admin_level = admin_level ,
7085 maritime = (t .maritime and (t .maritime == ' yes' or t .natural == ' coastline' )),
71- disputed = info . disputed or ( t . disputed and t . disputed == ' yes ' ) ,
86+ disputed = disputed ,
7287 geom = object :as_linestring ()
7388 }
74- themepark . themes . core . add_name ( a , object )
89+
7590 themepark :insert (' boundaries' , a , t )
7691end )
7792
7893themepark :add_proc (' select_relation_members' , function (relation )
79- if valid_admin_level ( get_admin_level ( relation .tags ) ) then
94+ if is_admin_boundary ( relation .tags ) then
8095 return { ways = osm2pgsql .way_member_ids (relation ) }
8196 end
8297end )
8398
8499themepark :add_proc (' relation' , function (object , data )
85- local t = object .tags
100+ if is_admin_boundary (object .tags ) then
101+ local admin_level = tonumber (object .tags .admin_level )
86102
87- local admin_level = get_admin_level (t )
103+ for _ , id in ipairs (osm2pgsql .way_member_ids (object )) do
104+ if not min_admin_level [id ] or min_admin_level [id ] > admin_level then
105+ min_admin_level [id ] = admin_level
106+ end
107+ end
88108
89- if not valid_admin_level (admin_level ) then
90109 return
91110 end
92111
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
112+ if object .tags .boundary == ' disputed' then
113+ -- Ways in relations tagged boundary=disputed are flagged as disputed
114+ -- if either the relation doesn't have an admin_level tag or the
115+ -- admin_level tag is <= the admin level the way got from the
116+ -- boundary=administrative relation(s).
117+ local admin_level = get_admin_level (object .tags .admin_level )
118+
119+ for _ , id in ipairs (osm2pgsql .way_member_ids (object )) do
120+ if not min_disputed_admin_level [id ] or min_disputed_admin_level [id ] > admin_level then
121+ min_disputed_admin_level [id ] = admin_level
99122 end
100- rinfos [member .ref ].disputed = (t .boundary == ' disputed' )
101123 end
102124 end
103125end )
0 commit comments