diff --git a/layers/building/building.sql b/layers/building/building.sql index bbc5d04..96eea63 100644 --- a/layers/building/building.sql +++ b/layers/building/building.sql @@ -1,6 +1,50 @@ -- etldoc: layer_building[shape=record fillcolor=lightpink, style="rounded,filled", -- etldoc: label="layer_building | z13 | z14+ " ] ; +CREATE OR REPLACE FUNCTION as_numeric(text) RETURNS NUMERIC AS $$ + -- Inspired by http://stackoverflow.com/questions/16195986/isnumeric-with-postgresql/16206123#16206123 +DECLARE test NUMERIC; +BEGIN + test = $1::NUMERIC; + RETURN test; +EXCEPTION WHEN others THEN + RETURN -1; +END; +$$ STRICT +LANGUAGE plpgsql IMMUTABLE; + +CREATE INDEX IF NOT EXISTS osm_building_relation_building_idx ON osm_building_relation(building); + +CREATE OR REPLACE VIEW osm_all_buildings AS ( + -- etldoc: osm_building_relation -> layer_building:z14_ + SELECT member AS osm_id,geometry, + COALESCE(nullif(as_numeric(height),-1),nullif(as_numeric(buildingheight),-1)) as height, + COALESCE(nullif(as_numeric(min_height),-1),nullif(as_numeric(buildingmin_height),-1)) as min_height, + COALESCE(nullif(as_numeric(levels),-1),nullif(as_numeric(buildinglevels),-1)) as levels, + COALESCE(nullif(as_numeric(min_level),-1),nullif(as_numeric(buildingmin_level),-1)) as min_level + FROM + osm_building_relation WHERE building = '' + UNION ALL + -- etldoc: osm_building_polygon -> layer_building:z14_ + SELECT osm_id,geometry, + COALESCE(nullif(as_numeric(height),-1),nullif(as_numeric(buildingheight),-1)) as height, + COALESCE(nullif(as_numeric(min_height),-1),nullif(as_numeric(buildingmin_height),-1)) as min_height, + COALESCE(nullif(as_numeric(levels),-1),nullif(as_numeric(buildinglevels),-1)) as levels, + COALESCE(nullif(as_numeric(min_level),-1),nullif(as_numeric(buildingmin_level),-1)) as min_level + FROM + osm_building_polygon obp WHERE EXISTS (SELECT 1 FROM osm_building_multipolygon obm WHERE obp.osm_id = obm.osm_id) + UNION ALL + -- etldoc: osm_building_polygon -> layer_building:z14_ + SELECT osm_id,geometry, + + COALESCE(nullif(as_numeric(height),-1),nullif(as_numeric(buildingheight),-1)) as height, + COALESCE(nullif(as_numeric(min_height),-1),nullif(as_numeric(buildingmin_height),-1)) as min_height, + COALESCE(nullif(as_numeric(levels),-1),nullif(as_numeric(buildinglevels),-1)) as levels, + COALESCE(nullif(as_numeric(min_level),-1),nullif(as_numeric(buildingmin_level),-1)) as min_level + FROM + osm_building_polygon WHERE osm_id >= 0 +); + CREATE OR REPLACE FUNCTION layer_building(bbox geometry, zoom_level int) RETURNS TABLE(geometry geometry, osm_id bigint, render_height int, render_min_height int) AS $$ SELECT geometry, osm_id, render_height, render_min_height @@ -13,12 +57,15 @@ RETURNS TABLE(geometry geometry, osm_id bigint, render_height int, render_min_he WHERE zoom_level = 13 AND geometry && bbox AND area > 1400 UNION ALL -- etldoc: osm_building_polygon -> layer_building:z14_ - SELECT - osm_id, geometry, - greatest(5, COALESCE(height, levels*3.66,5))::int AS render_height, - greatest(0, COALESCE(min_height, min_level*3.66,0))::int AS render_min_height - FROM osm_building_polygon + SELECT DISTINCT ON (osm_id) + osm_id, geometry, + ceil( COALESCE(height, levels*3.66,5))::int AS render_height, + floor(COALESCE(min_height, min_level*3.66,0))::int AS render_min_height FROM + osm_all_buildings WHERE zoom_level >= 14 AND geometry && bbox ) AS zoom_levels ORDER BY render_height ASC, ST_YMin(geometry) DESC; $$ LANGUAGE SQL IMMUTABLE; + +-- not handled: where a building outline covers building parts + diff --git a/layers/building/mapping.yaml b/layers/building/mapping.yaml index 0f2ef3e..7656364 100644 --- a/layers/building/mapping.yaml +++ b/layers/building/mapping.yaml @@ -1,5 +1,7 @@ -generalized_tables: +tags: + load_all: true +generalized_tables: # etldoc: imposm3 -> osm_building_polygon_gen1 building_polygon_gen1: source: building_polygon @@ -7,7 +9,6 @@ generalized_tables: tolerance: 10.0 tables: - # etldoc: imposm3 -> osm_building_polygon building_polygon: fields: @@ -20,18 +21,33 @@ tables: - name: building key: building type: string + - name: buildingpart + key: building:part + type: string + - name: buildingheight + key: building:height + type: string + - name: buildingmin_height + key: building:min_height + type: string + - name: buildinglevels + key: building:levels + type: string + - name: buildingmin_level + key: building:min_level + type: string - name: height key: height - type: integer + type: string - name: min_height key: min_height - type: integer + type: string - name: levels - key: building:levels - type: integer + key: levels + type: string - name: min_level - key: building:min_level - type: integer + key: min_level + type: string mapping: building:part: - __any__ @@ -43,5 +59,159 @@ tables: - hangar filters: reject: - building: ["no","none","No"] + building: ["no","none","No"] + building:part: ["no","none","No"] type: polygon + + # etldoc: imposm3 -> osm_building_relation + building_relation: + fields: + - name: osm_id + type: id + - name: geometry + type: validated_geometry + - name: area + type: webmerc_area + - name: building + key: building + type: string + from_member: true + - name: buildingpart + key: building:part + type: string + from_member: true + - name: buildingheight + key: building:height + type: string + from_member: true + - name: height + key: height + type: string + from_member: true + - name: buildingmin_height + key: building:min_height + type: string + from_member: true + - name: min_height + key: min_height + type: string + from_member: true + - name: buildinglevels + key: building:levels + type: string + from_member: true + - name: levels + key: levels + type: string + from_member: true + - name: buildingmin_level + key: building:min_level + type: string + from_member: true + - name: min_level + key: min_level + type: string + from_member: true + - name: relbuildingheight + key: building:height + type: string + - name: relheight + key: height + type: string + - name: relbuildingmin_height + key: building:min_height + type: string + - name: relmin_height + key: min_height + type: string + - name: relbuildinglevels + key: building:levels + type: string + - name: rellevels + key: levels + type: string + - name: relbuildingmin_level + key: building:min_level + type: string + - name: relmin_level + key: min_level + type: string + - name: member + type: member_id + - name: index + type: member_index + - name: role + type: member_role + from_member: true + - name: type + type: member_type + mapping: + type: [building] + type: relation_member + + # etldoc: imposm3 -> osm_building_multipolygon + building_multipolygon: + fields: + - name: osm_id + type: id + - name: geometry + type: validated_geometry + - name: area + type: webmerc_area + - name: building + key: building + type: string + from_member: true + - name: buildingpart + key: building:part + type: string + from_member: true + - name: buildingheight + key: building:height + type: string + from_member: true + - name: height + key: height + type: string + from_member: true + - name: buildingmin_height + key: building:min_height + type: string + from_member: true + - name: min_height + key: min_height + type: string + from_member: true + - name: buildinglevels + key: building:levels + type: string + from_member: true + - name: levels + key: levels + type: string + from_member: true + - name: buildingmin_level + key: building:min_level + type: string + from_member: true + - name: min_level + key: min_level + type: string + from_member: true + - name: member + type: member_id + - name: index + type: member_index + - name: role + type: member_role + from_member: true + - name: type + type: member_type + mapping: + type: [multipolygon] + filters: + reject: + building: ["no","none","No"] + building:part: ["no","none","No"] + type: relation_member +