]> git.openstreetmap.org Git - nominatim.git/blob - sql/functions/ranking.sql
move ranks-related functions in separate sql file
[nominatim.git] / sql / functions / ranking.sql
1 -- Functions related to search and address ranks
2
3 -- Return an approximate search radius according to the search rank.
4 CREATE OR REPLACE FUNCTION reverse_place_diameter(rank_search SMALLINT)
5   RETURNS FLOAT
6   AS $$
7 BEGIN
8   IF rank_search <= 4 THEN
9     RETURN 5.0;
10   ELSIF rank_search <= 8 THEN
11     RETURN 1.8;
12   ELSIF rank_search <= 12 THEN
13     RETURN 0.6;
14   ELSIF rank_search <= 17 THEN
15     RETURN 0.16;
16   ELSIF rank_search <= 18 THEN
17     RETURN 0.08;
18   ELSIF rank_search <= 19 THEN
19     RETURN 0.04;
20   END IF;
21
22   RETURN 0.02;
23 END;
24 $$
25 LANGUAGE plpgsql IMMUTABLE;
26
27
28 -- Return an approximate update radius according to the search rank.
29 CREATE OR REPLACE FUNCTION update_place_diameter(rank_search SMALLINT)
30   RETURNS FLOAT
31   AS $$
32 BEGIN
33   -- postcodes
34   IF rank_search = 11 or rank_search = 5 THEN
35     RETURN 0.05;
36   -- anything higher than city is effectively ignored (polygon required)
37   ELSIF rank_search < 16 THEN
38     RETURN 0;
39   ELSIF rank_search < 18 THEN
40     RETURN 0.1;
41   ELSIF rank_search < 20 THEN
42     RETURN 0.05;
43   ELSIF rank_search = 21 THEN
44     RETURN 0.001;
45   ELSIF rank_search < 24 THEN
46     RETURN 0.02;
47   ELSIF rank_search < 26 THEN
48     RETURN 0.002;
49   ELSIF rank_search < 28 THEN
50     RETURN 0.001;
51   END IF;
52
53   RETURN 0;
54 END;
55 $$
56 LANGUAGE plpgsql IMMUTABLE;
57
58
59 -- Guess a ranking for postcodes from country and postcode format.
60 CREATE OR REPLACE FUNCTION get_postcode_rank(country_code VARCHAR(2), postcode TEXT,
61                                              OUT rank_search SMALLINT,
62                                              OUT rank_address SMALLINT)
63 AS $$
64 DECLARE
65   part TEXT;
66 BEGIN
67     rank_search := 30;
68     rank_address := 30;
69     postcode := upper(postcode);
70
71     IF country_code = 'gb' THEN
72         IF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9][A-Z][A-Z])$' THEN
73             rank_search := 25;
74             rank_address := 5;
75         ELSEIF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z]? [0-9])$' THEN
76             rank_search := 23;
77             rank_address := 5;
78         ELSEIF postcode ~ '^([A-Z][A-Z]?[0-9][0-9A-Z])$' THEN
79             rank_search := 21;
80             rank_address := 5;
81         END IF;
82
83     ELSEIF country_code = 'sg' THEN
84         IF postcode ~ '^([0-9]{6})$' THEN
85             rank_search := 25;
86             rank_address := 11;
87         END IF;
88
89     ELSEIF country_code = 'de' THEN
90         IF postcode ~ '^([0-9]{5})$' THEN
91             rank_search := 21;
92             rank_address := 11;
93         END IF;
94
95     ELSE
96         -- Guess at the postcode format and coverage (!)
97         IF postcode ~ '^[A-Z0-9]{1,5}$' THEN -- Probably too short to be very local
98             rank_search := 21;
99             rank_address := 11;
100         ELSE
101             -- Does it look splitable into and area and local code?
102             part := substring(postcode from '^([- :A-Z0-9]+)([- :][A-Z0-9]+)$');
103
104             IF part IS NOT NULL THEN
105                 rank_search := 25;
106                 rank_address := 11;
107             ELSEIF postcode ~ '^[- :A-Z0-9]{6,}$' THEN
108                 rank_search := 21;
109                 rank_address := 11;
110             END IF;
111         END IF;
112     END IF;
113
114 END;
115 $$
116 LANGUAGE plpgsql IMMUTABLE;