X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/efafa5271957fb54b356ec1c90e8613f14de40d4..2c61fe08a031bd4ccbe47c62c021321e2dff7510:/lib-sql/functions/partition-functions.sql diff --git a/lib-sql/functions/partition-functions.sql b/lib-sql/functions/partition-functions.sql index cf83f840..d3c83615 100644 --- a/lib-sql/functions/partition-functions.sql +++ b/lib-sql/functions/partition-functions.sql @@ -17,29 +17,10 @@ CREATE TYPE nearfeaturecentr AS ( centroid GEOMETRY ); --- feature intersects geoemtry --- for areas and linestrings they must touch at least along a line -CREATE OR REPLACE FUNCTION is_relevant_geometry(de9im TEXT, geom_type TEXT) -RETURNS BOOLEAN -AS $$ -BEGIN - IF substring(de9im from 1 for 2) != 'FF' THEN - RETURN TRUE; - END IF; - - IF geom_type = 'ST_Point' THEN - RETURN substring(de9im from 4 for 1) = '0'; - END IF; - - IF geom_type in ('ST_LineString', 'ST_MultiLineString') THEN - RETURN substring(de9im from 4 for 1) = '1'; - END IF; - - RETURN substring(de9im from 4 for 1) = '2'; -END -$$ LANGUAGE plpgsql IMMUTABLE; - -create or replace function getNearFeatures(in_partition INTEGER, feature GEOMETRY, maxrank INTEGER) RETURNS setof nearfeaturecentr AS $$ +CREATE OR REPLACE function getNearFeatures(in_partition INTEGER, feature GEOMETRY, + feature_centroid GEOMETRY, + maxrank INTEGER) +RETURNS setof nearfeaturecentr AS $$ DECLARE r nearfeaturecentr%rowtype; BEGIN @@ -48,11 +29,20 @@ BEGIN IF in_partition = {{ partition }} THEN FOR r IN SELECT place_id, keywords, rank_address, rank_search, - min(ST_Distance(feature, centroid)) as distance, + CASE WHEN isguess THEN ST_Distance(feature, centroid) + ELSE min(ST_Distance(feature_centroid, geometry)) + -- tie breaker when distance is the same (i.e. way is on boundary) + + 0.00001 * ST_Distance(feature, centroid) + END as distance, isguess, postcode, centroid FROM location_area_large_{{ partition }} WHERE geometry && feature - AND is_relevant_geometry(ST_Relate(geometry, feature), ST_GeometryType(feature)) + AND CASE WHEN ST_Dimension(feature) = 0 + THEN _ST_Covers(geometry, feature) + WHEN ST_Dimension(feature) = 2 + THEN ST_Relate(geometry, feature, 'T********') + ELSE ST_NPoints(ST_Intersection(geometry, feature)) > 1 + END AND rank_address < maxrank -- Postcodes currently still use rank_search to define for which -- features they are relevant. @@ -68,7 +58,7 @@ BEGIN RAISE EXCEPTION 'Unknown partition %', in_partition; END $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION get_address_place(in_partition SMALLINT, feature GEOMETRY, @@ -89,7 +79,7 @@ BEGIN AND rank_address between from_rank and to_rank AND token_matches_address(token_info, key, keywords) GROUP BY place_id, keywords, rank_address, rank_search, isguess, postcode, centroid - ORDER BY bool_or(ST_Intersects(geometry, feature)), distance LIMIT 1; + ORDER BY bool_or(ST_Intersects(geometry, feature)) DESC, distance LIMIT 1; RETURN r; END IF; {% endfor %} @@ -97,7 +87,7 @@ BEGIN RAISE EXCEPTION 'Unknown partition %', in_partition; END; $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; create or replace function deleteLocationArea(in_partition INTEGER, in_place_id BIGINT, in_rank_search INTEGER) RETURNS BOOLEAN AS $$ @@ -135,14 +125,16 @@ BEGIN IF in_rank_search <= 4 and not in_estimate THEN INSERT INTO location_area_country (place_id, country_code, geometry) - values (in_place_id, in_country_code, in_geometry); + (SELECT in_place_id, in_country_code, geom + FROM split_geometry(in_geometry) as geom); RETURN TRUE; END IF; {% for partition in db.partitions %} IF in_partition = {{ partition }} THEN INSERT INTO location_area_large_{{ partition }} (partition, place_id, country_code, keywords, rank_search, rank_address, isguess, postcode, centroid, geometry) - values (in_partition, in_place_id, in_country_code, in_keywords, in_rank_search, in_rank_address, in_estimate, postcode, in_centroid, in_geometry); + (SELECT in_partition, in_place_id, in_country_code, in_keywords, in_rank_search, in_rank_address, in_estimate, postcode, in_centroid, geom + FROM split_geometry(in_geometry) as geom); RETURN TRUE; END IF; {% endfor %} @@ -180,7 +172,7 @@ BEGIN RAISE EXCEPTION 'Unknown partition %', in_partition; END $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION getNearestNamedPlacePlaceId(in_partition INTEGER, point GEOMETRY, @@ -210,7 +202,7 @@ BEGIN RAISE EXCEPTION 'Unknown partition %', in_partition; END $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; create or replace function insertSearchName( in_partition INTEGER, in_place_id BIGINT, in_name_vector INTEGER[], @@ -318,7 +310,7 @@ BEGIN RAISE EXCEPTION 'Unknown partition %', in_partition; END $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION getNearestParallelRoadFeature(in_partition INTEGER, line GEOMETRY) @@ -362,4 +354,4 @@ BEGIN RAISE EXCEPTION 'Unknown partition %', in_partition; END $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE;