diff --git a/lua/themepark.lua b/lua/themepark.lua index d1205d7..7651623 100644 --- a/lua/themepark.lua +++ b/lua/themepark.lua @@ -398,18 +398,116 @@ end -- --------------------------------------------------------------------------- +-- Objects with any of the following keys will be treated as polygon +local polygon_keys = { + 'abandoned:aeroway', + 'abandoned:amenity', + 'abandoned:building', + 'abandoned:landuse', + 'abandoned:power', + 'aeroway', + 'allotments', + 'amenity', + 'area:highway', + 'craft', + 'building', + 'building:part', + 'club', + 'golf', + 'emergency', + 'harbour', + 'healthcare', + 'historic', + 'landuse', + 'leisure', + 'man_made', + 'military', + 'natural', + 'office', + 'place', + 'power', + 'public_transport', + 'shop', + 'tourism', + 'water', + 'wetland' +} + +-- Objects with any of the following key/value combinations will be treated as linestring +local linestring_values = { + aeroway = {taxiway = true, runway = true}, + golf = {cartpath = true, hole = true, path = true}, + emergency = {designated = true, destination = true, no = true, official = true, yes = true}, + historic = {citywalls = true}, + leisure = {track = true, slipway = true}, + man_made = {breakwater = true, cutline = true, embankment = true, groyne = true, pipeline = true}, + natural = {cliff = true, earth_bank = true, tree_row = true, ridge = true, arete = true}, + power = {cable = true, line = true, minor_line = true}, + tourism = {yes = true} +} + +-- Objects with any of the following key/value combinations will be treated as polygon +local polygon_values = { + aerialway = {station = true}, + boundary = {aboriginal_lands = true, national_park = true, protected_area= true}, + highway = {services = true, rest_area = true}, + junction = {yes = true}, + railway = {station = true}, + waterway = {dock = true, boatyard = true, fuel = true, riverbank = true} +} + -- This function should return `true` when it is called with a way object -- that can be understood as an area (polygon). You can override this in your -- setup code. function themepark:way_is_area(object) - return object.is_closed + if not object.is_closed then + return false + end + local tags = object.tags + -- Treat objects tagged as area=yes polygon, other area as no + if tags.area then + return tags.area == "yes" and true or false + end + + -- Search through object's tags + for k, v in pairs(tags) do + -- Check if it has a polygon key and not a linestring override, or a polygon k=v + for _, ptag in ipairs(polygon_keys) do + if k == ptag and v ~= "no" and not (linestring_values[k] and linestring_values[k][v]) then + return true + end + end + + if (polygon_values[k] and polygon_values[k][v]) then + return true + end + end + return false end -- This function should return `true` when it is called with a relation object -- that can be understood as an area (multipolygon). You can override this in -- your setup code. function themepark:relation_is_area(object) - return object.tags.type == 'multipolygon' or object.tags.type == 'boundary' + local tags = object.tags + if tags.type ~= 'multipolygon' and tags.type ~= 'boundary' then + return false + end + + -- Search through object's tags + for k, v in pairs(tags) do + -- Check if it has a polygon key and not a linestring override, or a polygon k=v + for _, ptag in ipairs(polygon_keys) do + if k == ptag and v ~= "no" and not (linestring_values[k] and linestring_values[k][v]) then + return true + end + end + + if (polygon_values[k] and polygon_values[k][v]) then + return true + end + end + return false end -- --------------------------------------------------------------------------- @@ -430,28 +528,37 @@ local process_area = function(object, data) end end -function osm2pgsql.process_node(object) - local data = {} - - for _, func in ipairs(themepark.process.node) do +local process_line = function(object, data) + for _, func in ipairs(themepark.process.way) do if func(object, data) == 'stop' then return end end end -function osm2pgsql.process_way(object) +function osm2pgsql.process_node(object) local data = {} - for _, func in ipairs(themepark.process.way) do + for _, func in ipairs(themepark.process.node) do if func(object, data) == 'stop' then return end end +end +function osm2pgsql.process_way(object) + local data = {} + + -- Check if the tags indicate an area if themepark:way_is_area(object) then - object.as_area = object.as_polygon - process_area(object, data) + -- Only closed ways are valid areas + if object.is_closed then + object.as_area = object.as_polygon + process_area(object, data) + end + else + -- By only processing where tags don't indicate an area, this avoids linestrings disappearing when a way is closed + process_line(object, data) end end