57 lines
1.7 KiB
SQL
57 lines
1.7 KiB
SQL
DROP TABLE IF EXISTS buildings CASCADE;
|
|
|
|
CREATE TABLE buildings AS
|
|
WITH raw AS (
|
|
SELECT
|
|
osm_id,
|
|
way,
|
|
NULLIF(building, '') AS building_type,
|
|
substring(replace(COALESCE(tags -> 'height', ''), ',', '.') FROM '[-+]?[0-9]+(\.[0-9]+)?')::real
|
|
AS height_value,
|
|
substring(replace(COALESCE(tags -> 'building:levels', ''), ',', '.') FROM '[-+]?[0-9]+(\.[0-9]+)?')::real
|
|
AS levels_value
|
|
FROM planet_osm_polygon
|
|
WHERE building IS NOT NULL
|
|
AND building <> ''
|
|
AND building <> 'no'
|
|
),
|
|
normalized AS (
|
|
SELECT
|
|
osm_id,
|
|
ST_Multi(ST_CollectionExtract(ST_MakeValid(way), 3)) AS geom,
|
|
building_type,
|
|
height_value,
|
|
levels_value
|
|
FROM raw
|
|
)
|
|
SELECT
|
|
osm_id,
|
|
geom,
|
|
CASE
|
|
WHEN height_value IS NOT NULL AND height_value > 0 THEN height_value
|
|
WHEN levels_value IS NOT NULL AND levels_value > 0 THEN levels_value * 3.0
|
|
WHEN building_type IN ('garage', 'garages', 'shed') THEN 3.0
|
|
WHEN building_type IN ('industrial', 'warehouse') THEN 8.0
|
|
WHEN building_type IN ('church', 'cathedral') THEN 12.0
|
|
ELSE 9.0
|
|
END::real AS height_m,
|
|
CASE
|
|
WHEN levels_value IS NOT NULL AND levels_value > 0 THEN levels_value::integer
|
|
ELSE NULL
|
|
END AS levels,
|
|
building_type,
|
|
CASE
|
|
WHEN height_value IS NOT NULL AND height_value > 0 THEN 'measured'
|
|
ELSE 'estimated'
|
|
END AS source
|
|
FROM normalized
|
|
WHERE NOT ST_IsEmpty(geom);
|
|
|
|
ALTER TABLE buildings ALTER COLUMN geom TYPE geometry(MultiPolygon, 4326)
|
|
USING ST_SetSRID(geom, 4326);
|
|
|
|
CREATE INDEX IF NOT EXISTS buildings_geom_gix ON buildings USING GIST (geom);
|
|
CREATE INDEX IF NOT EXISTS buildings_height_idx ON buildings (height_m);
|
|
CREATE INDEX IF NOT EXISTS buildings_type_idx ON buildings (building_type);
|
|
ANALYZE buildings;
|