local buildings = osm2pgsql.define_area_table('buildings', { { column = 'osm_id', type = 'bigint', not_null = true }, { column = 'geom', type = 'multipolygon', projection = 4326, not_null = true }, { column = 'height_m', type = 'real', not_null = true }, { column = 'levels', type = 'int' }, { column = 'building_type', type = 'text' }, { column = 'source', type = 'text', not_null = true }, }) local function parse_number(value) if value == nil then return nil end local normalized = tostring(value):gsub(',', '.') local number = normalized:match('[-+]?%d+%.?%d*') if number == nil then return nil end return tonumber(number) end local function default_height(building_type) if building_type == 'garage' or building_type == 'garages' or building_type == 'shed' then return 3.0 end if building_type == 'industrial' or building_type == 'warehouse' then return 8.0 end if building_type == 'church' or building_type == 'cathedral' then return 12.0 end return 9.0 end local function building_height(tags) local height = parse_number(tags.height) if height ~= nil and height > 0 then return height, parse_number(tags['building:levels']), 'measured' end local levels = parse_number(tags['building:levels']) if levels ~= nil and levels > 0 then return levels * 3.0, levels, 'estimated' end return default_height(tags.building), nil, 'estimated' end local function add_building(object, geom) if object.tags.building == nil or object.tags.building == 'no' then return end local height_m, levels, source = building_height(object.tags) buildings:add_row({ osm_id = object.id, geom = geom, height_m = height_m, levels = levels, building_type = object.tags.building, source = source, }) end function osm2pgsql.process_way(object) if object.is_closed then add_building(object, object:as_multipolygon()) end end function osm2pgsql.process_relation(object) if object.tags.type == 'multipolygon' or object.tags.type == 'boundary' then add_building(object, object:as_multipolygon()) end end