reorganise layout of location_postcode table

Also renames the table as this will make it easier to migrate.
This commit is contained in:
Sarah Hoffmann
2025-12-23 12:13:19 +01:00
parent 7ef3f99fa4
commit 89821d01e0
14 changed files with 69 additions and 53 deletions

View File

@@ -139,37 +139,46 @@ $$
LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE;
-- Find the nearest artificial postcode for the given geometry.
-- TODO For areas there should not be more than two inside the geometry.
-- Find the best-matching postcode for the given geometry
CREATE OR REPLACE FUNCTION get_nearest_postcode(country VARCHAR(2), geom GEOMETRY)
RETURNS TEXT
AS $$
DECLARE
outcode TEXT;
cnt INTEGER;
location RECORD;
BEGIN
-- If the geometry is an area then only one postcode must be within
-- that area, otherwise consider the area as not having a postcode.
IF ST_GeometryType(geom) in ('ST_Polygon','ST_MultiPolygon') THEN
SELECT min(postcode), count(*) FROM
(SELECT postcode FROM location_postcode
WHERE ST_Contains(geom, location_postcode.geometry) LIMIT 2) sub
INTO outcode, cnt;
SELECT min(postcode), count(*) FROM
(SELECT postcode FROM location_postcodes
WHERE geom && location_postcodes.geometry -- want to use the index
AND ST_Contains(geom, location_postcodes.centroid)
AND country_code = country
LIMIT 2) sub
INTO outcode, cnt;
IF cnt = 1 THEN
RETURN outcode;
ELSE
RETURN null;
END IF;
RETURN null;
END IF;
SELECT postcode FROM location_postcode
WHERE ST_DWithin(geom, location_postcode.geometry, 0.05)
AND location_postcode.country_code = country
ORDER BY ST_Distance(geom, location_postcode.geometry) LIMIT 1
INTO outcode;
-- Otherwise: be fully within the coverage area of a postcode
FOR location IN
SELECT postcode
FROM location_postcodes p
WHERE ST_Covers(p.geometry, geom)
AND p.country_code = country
ORDER BY osm_id is null, ST_Distance(p.centroid, geom)
LIMIT 1
LOOP
RETURN location.postcode;
END LOOP;
RETURN outcode;
RETURN NULL;
END;
$$
LANGUAGE plpgsql STABLE PARALLEL SAFE;