mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-02-26 11:08:13 +00:00
Merge pull request #1745 from lonvia/shuffle-sql-functions
Some more SQL function reorganisation
This commit is contained in:
@@ -695,6 +695,7 @@ class SetupFunctions
|
|||||||
$sBasePath = CONST_BasePath.'/sql/functions/';
|
$sBasePath = CONST_BasePath.'/sql/functions/';
|
||||||
$sTemplate = file_get_contents($sBasePath.'utils.sql');
|
$sTemplate = file_get_contents($sBasePath.'utils.sql');
|
||||||
$sTemplate .= file_get_contents($sBasePath.'normalization.sql');
|
$sTemplate .= file_get_contents($sBasePath.'normalization.sql');
|
||||||
|
$sTemplate .= file_get_contents($sBasePath.'ranking.sql');
|
||||||
$sTemplate .= file_get_contents($sBasePath.'importance.sql');
|
$sTemplate .= file_get_contents($sBasePath.'importance.sql');
|
||||||
$sTemplate .= file_get_contents($sBasePath.'address_lookup.sql');
|
$sTemplate .= file_get_contents($sBasePath.'address_lookup.sql');
|
||||||
$sTemplate .= file_get_contents($sBasePath.'interpolation.sql');
|
$sTemplate .= file_get_contents($sBasePath.'interpolation.sql');
|
||||||
|
|||||||
@@ -1,45 +1,5 @@
|
|||||||
-- Trigger functions for the placex table.
|
-- Trigger functions for the placex table.
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION get_rel_node_members(members TEXT[], memberLabels TEXT[])
|
|
||||||
RETURNS SETOF BIGINT
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
i INTEGER;
|
|
||||||
BEGIN
|
|
||||||
FOR i IN 1..ARRAY_UPPER(members,1) BY 2 LOOP
|
|
||||||
IF members[i+1] = ANY(memberLabels)
|
|
||||||
AND upper(substring(members[i], 1, 1))::char(1) = 'N'
|
|
||||||
THEN
|
|
||||||
RETURN NEXT substring(members[i], 2)::bigint;
|
|
||||||
END IF;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
RETURN;
|
|
||||||
END;
|
|
||||||
$$
|
|
||||||
LANGUAGE plpgsql IMMUTABLE;
|
|
||||||
|
|
||||||
-- copy 'name' to or from the default language (if there is a default language)
|
|
||||||
CREATE OR REPLACE FUNCTION add_default_place_name(country_code VARCHAR(2),
|
|
||||||
INOUT name HSTORE)
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
default_language VARCHAR(10);
|
|
||||||
BEGIN
|
|
||||||
IF name is not null AND array_upper(akeys(name),1) > 1 THEN
|
|
||||||
default_language := get_country_language_code(country_code);
|
|
||||||
IF default_language IS NOT NULL THEN
|
|
||||||
IF name ? 'name' AND NOT name ? ('name:'||default_language) THEN
|
|
||||||
name := name || hstore(('name:'||default_language), (name -> 'name'));
|
|
||||||
ELSEIF name ? ('name:'||default_language) AND NOT name ? 'name' THEN
|
|
||||||
name := name || hstore('name', (name -> ('name:'||default_language)));
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
$$
|
|
||||||
LANGUAGE plpgsql IMMUTABLE;
|
|
||||||
|
|
||||||
-- Find the parent road of a POI.
|
-- Find the parent road of a POI.
|
||||||
--
|
--
|
||||||
-- \returns Place ID of parent object or NULL if none
|
-- \returns Place ID of parent object or NULL if none
|
||||||
@@ -538,25 +498,7 @@ BEGIN
|
|||||||
END IF;
|
END IF;
|
||||||
ELSE
|
ELSE
|
||||||
-- mark nearby items for re-indexing, where 'nearby' depends on the features rank_search and is a complete guess :(
|
-- mark nearby items for re-indexing, where 'nearby' depends on the features rank_search and is a complete guess :(
|
||||||
diameter := 0;
|
diameter := update_place_diameter(NEW.rank_search);
|
||||||
-- 16 = city, anything higher than city is effectively ignored (polygon required!)
|
|
||||||
IF NEW.type='postcode' THEN
|
|
||||||
diameter := 0.05;
|
|
||||||
ELSEIF NEW.rank_search < 16 THEN
|
|
||||||
diameter := 0;
|
|
||||||
ELSEIF NEW.rank_search < 18 THEN
|
|
||||||
diameter := 0.1;
|
|
||||||
ELSEIF NEW.rank_search < 20 THEN
|
|
||||||
diameter := 0.05;
|
|
||||||
ELSEIF NEW.rank_search = 21 THEN
|
|
||||||
diameter := 0.001;
|
|
||||||
ELSEIF NEW.rank_search < 24 THEN
|
|
||||||
diameter := 0.02;
|
|
||||||
ELSEIF NEW.rank_search < 26 THEN
|
|
||||||
diameter := 0.002; -- 100 to 200 meters
|
|
||||||
ELSEIF NEW.rank_search < 28 THEN
|
|
||||||
diameter := 0.001; -- 50 to 100 meters
|
|
||||||
END IF;
|
|
||||||
IF diameter > 0 THEN
|
IF diameter > 0 THEN
|
||||||
-- RAISE WARNING 'placex point insert: % % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type,diameter;
|
-- RAISE WARNING 'placex point insert: % % % % %',NEW.osm_type,NEW.osm_id,NEW.class,NEW.type,diameter;
|
||||||
IF NEW.rank_search >= 26 THEN
|
IF NEW.rank_search >= 26 THEN
|
||||||
|
|||||||
116
sql/functions/ranking.sql
Normal file
116
sql/functions/ranking.sql
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
-- Functions related to search and address ranks
|
||||||
|
|
||||||
|
-- Return an approximate search radius according to the search rank.
|
||||||
|
CREATE OR REPLACE FUNCTION reverse_place_diameter(rank_search SMALLINT)
|
||||||
|
RETURNS FLOAT
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
IF rank_search <= 4 THEN
|
||||||
|
RETURN 5.0;
|
||||||
|
ELSIF rank_search <= 8 THEN
|
||||||
|
RETURN 1.8;
|
||||||
|
ELSIF rank_search <= 12 THEN
|
||||||
|
RETURN 0.6;
|
||||||
|
ELSIF rank_search <= 17 THEN
|
||||||
|
RETURN 0.16;
|
||||||
|
ELSIF rank_search <= 18 THEN
|
||||||
|
RETURN 0.08;
|
||||||
|
ELSIF rank_search <= 19 THEN
|
||||||
|
RETURN 0.04;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN 0.02;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
|
||||||
|
-- Return an approximate update radius according to the search rank.
|
||||||
|
CREATE OR REPLACE FUNCTION update_place_diameter(rank_search SMALLINT)
|
||||||
|
RETURNS FLOAT
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
-- postcodes
|
||||||
|
IF rank_search = 11 or rank_search = 5 THEN
|
||||||
|
RETURN 0.05;
|
||||||
|
-- anything higher than city is effectively ignored (polygon required)
|
||||||
|
ELSIF rank_search < 16 THEN
|
||||||
|
RETURN 0;
|
||||||
|
ELSIF rank_search < 18 THEN
|
||||||
|
RETURN 0.1;
|
||||||
|
ELSIF rank_search < 20 THEN
|
||||||
|
RETURN 0.05;
|
||||||
|
ELSIF rank_search = 21 THEN
|
||||||
|
RETURN 0.001;
|
||||||
|
ELSIF rank_search < 24 THEN
|
||||||
|
RETURN 0.02;
|
||||||
|
ELSIF rank_search < 26 THEN
|
||||||
|
RETURN 0.002;
|
||||||
|
ELSIF rank_search < 28 THEN
|
||||||
|
RETURN 0.001;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
|
||||||
|
-- Guess a ranking for postcodes from country and postcode format.
|
||||||
|
CREATE OR REPLACE FUNCTION get_postcode_rank(country_code VARCHAR(2), postcode TEXT,
|
||||||
|
OUT rank_search SMALLINT,
|
||||||
|
OUT rank_address SMALLINT)
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
part TEXT;
|
||||||
|
BEGIN
|
||||||
|
rank_search := 30;
|
||||||
|
rank_address := 30;
|
||||||
|
postcode := upper(postcode);
|
||||||
|
|
||||||
|
IF country_code = 'gb' THEN
|
||||||
|
IF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9][A-Z][A-Z])$' THEN
|
||||||
|
rank_search := 25;
|
||||||
|
rank_address := 5;
|
||||||
|
ELSEIF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9])$' THEN
|
||||||
|
rank_search := 23;
|
||||||
|
rank_address := 5;
|
||||||
|
ELSEIF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z])$' THEN
|
||||||
|
rank_search := 21;
|
||||||
|
rank_address := 5;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
ELSEIF country_code = 'sg' THEN
|
||||||
|
IF postcode ~ '^([0-9]{6})$' THEN
|
||||||
|
rank_search := 25;
|
||||||
|
rank_address := 11;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
ELSEIF country_code = 'de' THEN
|
||||||
|
IF postcode ~ '^([0-9]{5})$' THEN
|
||||||
|
rank_search := 21;
|
||||||
|
rank_address := 11;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
ELSE
|
||||||
|
-- Guess at the postcode format and coverage (!)
|
||||||
|
IF postcode ~ '^[A-Z0-9]{1,5}$' THEN -- Probably too short to be very local
|
||||||
|
rank_search := 21;
|
||||||
|
rank_address := 11;
|
||||||
|
ELSE
|
||||||
|
-- Does it look splitable into and area and local code?
|
||||||
|
part := substring(postcode from '^([- :A-Z0-9]+)([- :][A-Z0-9]+)$');
|
||||||
|
|
||||||
|
IF part IS NOT NULL THEN
|
||||||
|
rank_search := 25;
|
||||||
|
rank_address := 11;
|
||||||
|
ELSEIF postcode ~ '^[- :A-Z0-9]{6,}$' THEN
|
||||||
|
rank_search := 21;
|
||||||
|
rank_address := 11;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
@@ -38,85 +38,58 @@ END;
|
|||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql IMMUTABLE;
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
-- Return the node members with a given label from a relation member list
|
||||||
CREATE OR REPLACE FUNCTION reverse_place_diameter(rank_search SMALLINT)
|
-- as a set.
|
||||||
RETURNS FLOAT
|
--
|
||||||
|
-- \param members Member list in osm2pgsql middle format.
|
||||||
|
-- \param memberLabels Array of labels to accept.
|
||||||
|
--
|
||||||
|
-- \returns Set of OSM ids of nodes that are found.
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION get_rel_node_members(members TEXT[],
|
||||||
|
memberLabels TEXT[])
|
||||||
|
RETURNS SETOF BIGINT
|
||||||
AS $$
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
i INTEGER;
|
||||||
BEGIN
|
BEGIN
|
||||||
IF rank_search <= 4 THEN
|
FOR i IN 1..ARRAY_UPPER(members,1) BY 2 LOOP
|
||||||
RETURN 5.0;
|
IF members[i+1] = ANY(memberLabels)
|
||||||
ELSIF rank_search <= 8 THEN
|
AND upper(substring(members[i], 1, 1))::char(1) = 'N'
|
||||||
RETURN 1.8;
|
THEN
|
||||||
ELSIF rank_search <= 12 THEN
|
RETURN NEXT substring(members[i], 2)::bigint;
|
||||||
RETURN 0.6;
|
END IF;
|
||||||
ELSIF rank_search <= 17 THEN
|
END LOOP;
|
||||||
RETURN 0.16;
|
|
||||||
ELSIF rank_search <= 18 THEN
|
|
||||||
RETURN 0.08;
|
|
||||||
ELSIF rank_search <= 19 THEN
|
|
||||||
RETURN 0.04;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
RETURN 0.02;
|
RETURN;
|
||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql IMMUTABLE;
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
|
|
||||||
|
-- Copy 'name' to or from the default language.
|
||||||
CREATE OR REPLACE FUNCTION get_postcode_rank(country_code VARCHAR(2), postcode TEXT,
|
--
|
||||||
OUT rank_search SMALLINT,
|
-- \param country_code Country code of the object being named.
|
||||||
OUT rank_address SMALLINT)
|
-- \param[inout] name List of names of the object.
|
||||||
AS $$
|
--
|
||||||
|
-- If the country named by country_code has a single default language,
|
||||||
|
-- then a `name` tag is copied to `name:<country_code>` if this tag does
|
||||||
|
-- not yet exist and vice versa.
|
||||||
|
CREATE OR REPLACE FUNCTION add_default_place_name(country_code VARCHAR(2),
|
||||||
|
INOUT name HSTORE)
|
||||||
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
part TEXT;
|
default_language VARCHAR(10);
|
||||||
BEGIN
|
BEGIN
|
||||||
rank_search := 30;
|
IF name is not null AND array_upper(akeys(name),1) > 1 THEN
|
||||||
rank_address := 30;
|
default_language := get_country_language_code(country_code);
|
||||||
postcode := upper(postcode);
|
IF default_language IS NOT NULL THEN
|
||||||
|
IF name ? 'name' AND NOT name ? ('name:'||default_language) THEN
|
||||||
IF country_code = 'gb' THEN
|
name := name || hstore(('name:'||default_language), (name -> 'name'));
|
||||||
IF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9][A-Z][A-Z])$' THEN
|
ELSEIF name ? ('name:'||default_language) AND NOT name ? 'name' THEN
|
||||||
rank_search := 25;
|
name := name || hstore('name', (name -> ('name:'||default_language)));
|
||||||
rank_address := 5;
|
END IF;
|
||||||
ELSEIF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9])$' THEN
|
|
||||||
rank_search := 23;
|
|
||||||
rank_address := 5;
|
|
||||||
ELSEIF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z])$' THEN
|
|
||||||
rank_search := 21;
|
|
||||||
rank_address := 5;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
ELSEIF country_code = 'sg' THEN
|
|
||||||
IF postcode ~ '^([0-9]{6})$' THEN
|
|
||||||
rank_search := 25;
|
|
||||||
rank_address := 11;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
ELSEIF country_code = 'de' THEN
|
|
||||||
IF postcode ~ '^([0-9]{5})$' THEN
|
|
||||||
rank_search := 21;
|
|
||||||
rank_address := 11;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
ELSE
|
|
||||||
-- Guess at the postcode format and coverage (!)
|
|
||||||
IF postcode ~ '^[A-Z0-9]{1,5}$' THEN -- Probably too short to be very local
|
|
||||||
rank_search := 21;
|
|
||||||
rank_address := 11;
|
|
||||||
ELSE
|
|
||||||
-- Does it look splitable into and area and local code?
|
|
||||||
part := substring(postcode from '^([- :A-Z0-9]+)([- :][A-Z0-9]+)$');
|
|
||||||
|
|
||||||
IF part IS NOT NULL THEN
|
|
||||||
rank_search := 25;
|
|
||||||
rank_address := 11;
|
|
||||||
ELSEIF postcode ~ '^[- :A-Z0-9]{6,}$' THEN
|
|
||||||
rank_search := 21;
|
|
||||||
rank_address := 11;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
|
||||||
END IF;
|
END IF;
|
||||||
|
END IF;
|
||||||
END;
|
END;
|
||||||
$$
|
$$
|
||||||
LANGUAGE plpgsql IMMUTABLE;
|
LANGUAGE plpgsql IMMUTABLE;
|
||||||
@@ -509,22 +482,7 @@ BEGIN
|
|||||||
AND rank_search > rank and indexed_status = 0 and ST_geometrytype(placex.geometry) != 'ST_Point' and (rank_search < 28 or name is not null or (rank >= 16 and address ? 'place'));
|
AND rank_search > rank and indexed_status = 0 and ST_geometrytype(placex.geometry) != 'ST_Point' and (rank_search < 28 or name is not null or (rank >= 16 and address ? 'place'));
|
||||||
END LOOP;
|
END LOOP;
|
||||||
ELSE
|
ELSE
|
||||||
diameter := 0;
|
diameter := update_place_diameter(rank);
|
||||||
IF rank = 11 THEN
|
|
||||||
diameter := 0.05;
|
|
||||||
ELSEIF rank < 18 THEN
|
|
||||||
diameter := 0.1;
|
|
||||||
ELSEIF rank < 20 THEN
|
|
||||||
diameter := 0.05;
|
|
||||||
ELSEIF rank = 21 THEN
|
|
||||||
diameter := 0.001;
|
|
||||||
ELSEIF rank < 24 THEN
|
|
||||||
diameter := 0.02;
|
|
||||||
ELSEIF rank < 26 THEN
|
|
||||||
diameter := 0.002; -- 100 to 200 meters
|
|
||||||
ELSEIF rank < 28 THEN
|
|
||||||
diameter := 0.001; -- 50 to 100 meters
|
|
||||||
END IF;
|
|
||||||
IF diameter > 0 THEN
|
IF diameter > 0 THEN
|
||||||
IF rank >= 26 THEN
|
IF rank >= 26 THEN
|
||||||
-- roads may cause reparenting for >27 rank places
|
-- roads may cause reparenting for >27 rank places
|
||||||
|
|||||||
Reference in New Issue
Block a user