Files
RadioPropagationApi/db/sql/normalize_buildings.sql
T
2026-06-23 11:33:40 +03:00

60 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_SetSRID(
ST_Multi(ST_CollectionExtract(ST_MakeValid(way), 3)),
4326
) 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;