@@ -11,8 +11,8 @@ themepark:add_table{
11
11
name = ' boundaries' ,
12
12
ids_type = ' way' ,
13
13
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 },
16
16
{ column = ' maritime' , type = ' bool' },
17
17
{ column = ' disputed' , type = ' bool' },
18
18
}),
@@ -29,27 +29,33 @@ themepark:add_table{
29
29
}
30
30
}
31
31
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 = {}
33
42
34
43
-- ---------------------------------------------------------------------------
35
44
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
40
51
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
46
56
end
47
- end
48
57
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 )
53
59
end
54
60
55
61
-- ---------------------------------------------------------------------------
@@ -59,45 +65,61 @@ themepark:add_proc('way', function(object, data)
59
65
return
60
66
end
61
67
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
64
70
return
65
71
end
66
72
67
73
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
+
68
83
local a = {
69
- admin_level = info . admin_level ,
84
+ admin_level = admin_level ,
70
85
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 ,
72
87
geom = object :as_linestring ()
73
88
}
74
- themepark . themes . core . add_name ( a , object )
89
+
75
90
themepark :insert (' boundaries' , a , t )
76
91
end )
77
92
78
93
themepark :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
80
95
return { ways = osm2pgsql .way_member_ids (relation ) }
81
96
end
82
97
end )
83
98
84
99
themepark :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 )
86
102
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
88
108
89
- if not valid_admin_level (admin_level ) then
90
109
return
91
110
end
92
111
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
99
122
end
100
- rinfos [member .ref ].disputed = (t .boundary == ' disputed' )
101
123
end
102
124
end
103
125
end )
0 commit comments