Merge pull request #1749 from lonvia/ranking-during-updates

Reset search and address ranks on update
This commit is contained in:
Sarah Hoffmann 2020-04-11 20:52:05 +02:00 committed by GitHub
commit b443c92a7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 52 deletions

View File

@ -392,7 +392,6 @@ DECLARE
country_code VARCHAR(2);
diameter FLOAT;
classtable TEXT;
classtype TEXT;
BEGIN
--DEBUG: RAISE WARNING '% % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type;
@ -410,8 +409,8 @@ BEGIN
is_area := ST_GeometryType(NEW.geometry) IN ('ST_Polygon','ST_MultiPolygon');
IF NEW.class in ('place','boundary')
AND NEW.type in ('postcode','postal_code') THEN
AND NEW.type in ('postcode','postal_code')
THEN
IF NEW.address IS NULL OR NOT NEW.address ? 'postcode' THEN
-- most likely just a part of a multipolygon postcode boundary, throw it away
RETURN NULL;
@ -419,61 +418,26 @@ BEGIN
NEW.name := hstore('ref', NEW.address->'postcode');
SELECT * FROM get_postcode_rank(NEW.country_code, NEW.address->'postcode')
INTO NEW.rank_search, NEW.rank_address;
IF NOT is_area THEN
NEW.rank_address := 0;
END IF;
ELSEIF NEW.class = 'boundary' AND NOT is_area THEN
return NULL;
RETURN NULL;
ELSEIF NEW.class = 'boundary' AND NEW.type = 'administrative'
AND NEW.admin_level <= 4 AND NEW.osm_type = 'W' THEN
return NULL;
ELSEIF NEW.osm_type = 'N' AND NEW.class = 'highway' THEN
NEW.rank_search = 30;
NEW.rank_address = 0;
ELSEIF NEW.class = 'landuse' AND NOT is_area THEN
NEW.rank_search = 30;
NEW.rank_address = 0;
ELSE
-- do table lookup stuff
IF NEW.class = 'boundary' and NEW.type = 'administrative' THEN
classtype = NEW.type || NEW.admin_level::TEXT;
ELSE
classtype = NEW.type;
END IF;
SELECT l.rank_search, l.rank_address FROM address_levels l
WHERE (l.country_code = NEW.country_code or l.country_code is NULL)
AND l.class = NEW.class AND (l.type = classtype or l.type is NULL)
ORDER BY l.country_code, l.class, l.type LIMIT 1
INTO NEW.rank_search, NEW.rank_address;
IF NEW.rank_search is NULL THEN
NEW.rank_search := 30;
END IF;
IF NEW.rank_address is NULL THEN
NEW.rank_address := 30;
END IF;
AND NEW.admin_level <= 4 AND NEW.osm_type = 'W'
THEN
RETURN NULL;
END IF;
-- some postcorrections
IF NEW.class = 'waterway' AND NEW.osm_type = 'R' THEN
-- Slightly promote waterway relations so that they are processed
-- before their members.
NEW.rank_search := NEW.rank_search - 1;
SELECT * INTO NEW.rank_search, NEW.rank_address
FROM compute_place_rank(NEW.country_code,
CASE WHEN is_area THEN 'A' ELSE NEW.osm_type END,
NEW.class, NEW.type, NEW.admin_level,
(NEW.extratags->'capital') = 'yes',
NEW.address->'postcode');
-- a country code make no sense below rank 4 (country)
IF NEW.rank_search < 4 THEN
NEW.country_code := NULL;
END IF;
IF (NEW.extratags -> 'capital') = 'yes' THEN
NEW.rank_search := NEW.rank_search - 1;
END IF;
END IF;
-- a country code make no sense below rank 4 (country)
IF NEW.rank_search < 4 THEN
NEW.country_code := NULL;
END IF;
--DEBUG: RAISE WARNING 'placex_insert:END: % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type;
@ -588,6 +552,17 @@ BEGIN
RETURN NEW;
END IF;
-- recompute the ranks, they might change when linking changes
SELECT * INTO NEW.rank_search, NEW.rank_address
FROM compute_place_rank(NEW.country_code,
CASE WHEN ST_GeometryType(NEW.geometry)
IN ('ST_Polygon','ST_MultiPolygon')
THEN 'A' ELSE NEW.osm_type END,
NEW.class, NEW.type, NEW.admin_level,
(NEW.extratags->'capital') = 'yes',
NEW.address->'postcode');
--DEBUG: RAISE WARNING 'Copy over address tags';
-- housenumber is a computed field, so start with an empty value
NEW.housenumber := NULL;

View File

@ -114,3 +114,79 @@ BEGIN
END;
$$
LANGUAGE plpgsql IMMUTABLE;
-- Get standard search and address rank for an object.
--
-- \param country Two-letter country code where the object is in.
-- \param extended_type OSM type (N, W, R) or area type (A).
-- \param place_class Class (or tag key) of object.
-- \param place_type Type (or tag value) of object.
-- \param admin_level Value of admin_level tag.
-- \param is_major If true, boost search rank by one.
-- \param postcode Value of addr:postcode tag.
-- \param[out] search_rank Computed search rank.
-- \param[out] address_rank Computed address rank.
--
CREATE OR REPLACE FUNCTION compute_place_rank(country VARCHAR(2),
extended_type VARCHAR(1),
place_class TEXT, place_type TEXT,
admin_level SMALLINT,
is_major BOOLEAN,
postcode TEXT,
OUT search_rank SMALLINT,
OUT address_rank SMALLINT)
AS $$
DECLARE
classtype TEXT;
BEGIN
IF place_class in ('place','boundary')
and place_type in ('postcode','postal_code')
THEN
SELECT * INTO search_rank, address_rank
FROM get_postcode_rank(country, postcode);
IF NOT extended_type = 'A' THEN
address_rank := 0;
END IF;
ELSEIF extended_type = 'N' AND place_class = 'highway' THEN
search_rank = 30;
address_rank = 0;
ELSEIF place_class = 'landuse' AND extended_type != 'A' THEN
search_rank = 30;
address_rank = 0;
ELSE
IF place_class = 'boundary' and place_type = 'administrative' THEN
classtype = place_type || admin_level::TEXT;
ELSE
classtype = place_type;
END IF;
SELECT l.rank_search, l.rank_address INTO search_rank, address_rank
FROM address_levels l
WHERE (l.country_code = country or l.country_code is NULL)
AND l.class = place_class AND (l.type = classtype or l.type is NULL)
ORDER BY l.country_code, l.class, l.type LIMIT 1;
IF search_rank is NULL THEN
search_rank := 30;
END IF;
IF address_rank is NULL THEN
address_rank := 30;
END IF;
-- some postcorrections
IF place_class = 'waterway' AND extended_type = 'R' THEN
-- Slightly promote waterway relations so that they are processed
-- before their members.
search_rank := search_rank - 1;
END IF;
IF is_major THEN
search_rank := search_rank - 1;
END IF;
END IF;
END;
$$
LANGUAGE plpgsql IMMUTABLE;