X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/dd44ee625b5bca5cde918f4661db5f31ae656e79..b4c87a09a194a7d966724ce48ba2d8ef0d044ca0:/sql/functions.sql diff --git a/sql/functions.sql b/sql/functions.sql index 5b17f6d0..e0d0897f 100644 --- a/sql/functions.sql +++ b/sql/functions.sql @@ -95,7 +95,7 @@ BEGIN SELECT min(word_id), max(search_name_count) FROM word WHERE word_token = lookup_token and class is null and type is null into return_word_id, count; IF return_word_id IS NULL THEN return_word_id := nextval('seq_word'); - INSERT INTO word VALUES (return_word_id, lookup_token, regexp_replace(lookup_token,E'([^0-9])\\1+',E'\\1','g'), null, null, null, null, 0, null); + INSERT INTO word VALUES (return_word_id, lookup_token, null, null, null, null, 0); ELSE IF count > get_maxwordfreq() THEN return_word_id := NULL; @@ -117,7 +117,7 @@ BEGIN SELECT min(word_id) FROM word WHERE word_token = lookup_token and class='place' and type='house' into return_word_id; IF return_word_id IS NULL THEN return_word_id := nextval('seq_word'); - INSERT INTO word VALUES (return_word_id, lookup_token, null, null, 'place', 'house', null, 0, null); + INSERT INTO word VALUES (return_word_id, lookup_token, null, 'place', 'house', null, 0); END IF; RETURN return_word_id; END; @@ -135,7 +135,7 @@ BEGIN SELECT min(word_id) FROM word WHERE word_token = lookup_token and country_code=lookup_country_code into return_word_id; IF return_word_id IS NULL THEN return_word_id := nextval('seq_word'); - INSERT INTO word VALUES (return_word_id, lookup_token, null, null, null, null, lookup_country_code, 0, null); + INSERT INTO word VALUES (return_word_id, lookup_token, null, null, null, lookup_country_code, 0); END IF; RETURN return_word_id; END; @@ -153,7 +153,7 @@ BEGIN SELECT min(word_id) FROM word WHERE word_token = lookup_token and class=lookup_class and type = lookup_type into return_word_id; IF return_word_id IS NULL THEN return_word_id := nextval('seq_word'); - INSERT INTO word VALUES (return_word_id, lookup_token, null, null, lookup_class, lookup_type, null, 0, null); + INSERT INTO word VALUES (return_word_id, lookup_token, null, lookup_class, lookup_type, null, 0); END IF; RETURN return_word_id; END; @@ -171,7 +171,7 @@ BEGIN SELECT min(word_id) FROM word WHERE word_token = lookup_token into return_word_id; IF return_word_id IS NULL THEN return_word_id := nextval('seq_word'); - INSERT INTO word VALUES (return_word_id, lookup_token, null, null, null, null, null, 0, null); + INSERT INTO word VALUES (return_word_id, lookup_token, null, null, null, null, 0); END IF; RETURN return_word_id; END; @@ -203,7 +203,7 @@ BEGIN SELECT min(word_id) FROM word WHERE word_token = lookup_token and class=lookup_class and type = lookup_type and operator = op into return_word_id; IF return_word_id IS NULL THEN return_word_id := nextval('seq_word'); - INSERT INTO word VALUES (return_word_id, lookup_token, null, null, lookup_class, lookup_type, null, 0, op, null); + INSERT INTO word VALUES (return_word_id, lookup_token, null, lookup_class, lookup_type, null, 0, op); END IF; RETURN return_word_id; END; @@ -222,7 +222,7 @@ BEGIN SELECT min(word_id) FROM word WHERE word_token = lookup_token and class is null and type is null into return_word_id; IF return_word_id IS NULL THEN return_word_id := nextval('seq_word'); - INSERT INTO word VALUES (return_word_id, lookup_token, regexp_replace(lookup_token,E'([^0-9])\\1+',E'\\1','g'), src_word, null, null, null, 0, null); + INSERT INTO word VALUES (return_word_id, lookup_token, src_word, null, null, null, 0); -- nospace_lookup_token := replace(replace(lookup_token, '-',''), ' ',''); -- IF ' '||nospace_lookup_token != lookup_token THEN -- INSERT INTO word VALUES (return_word_id, '-'||nospace_lookup_token, null, src_word, null, null, null, 0, null); @@ -345,6 +345,12 @@ BEGIN result := result || w; END IF; + w := getorcreate_word_id(s); + + IF NOT (ARRAY[w] <@ result) THEN + result := result || w; + END IF; + words := string_to_array(s, ' '); IF array_upper(words, 1) IS NOT NULL THEN FOR j IN 1..array_upper(words, 1) LOOP @@ -407,6 +413,12 @@ BEGIN result := result || w; END IF; + w := getorcreate_word_id(s); + + IF NOT (ARRAY[w] <@ result) THEN + result := result || w; + END IF; + words := string_to_array(s, ' '); IF array_upper(words, 1) IS NOT NULL THEN FOR j IN 1..array_upper(words, 1) LOOP @@ -782,8 +794,8 @@ CREATE OR REPLACE FUNCTION create_interpolation(wayid BIGINT, interpolationtype DECLARE newpoints INTEGER; - waynodes integer[]; - nodeid INTEGER; + waynodes BIGINT[]; + nodeid BIGINT; prevnode RECORD; nextnode RECORD; startnumber INTEGER; @@ -811,10 +823,10 @@ BEGIN FOR nodeidpos in 1..array_upper(waynodes, 1) LOOP - select min(place_id) from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::INTEGER and type = 'house' INTO search_place_id; + select min(place_id) from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT and type = 'house' INTO search_place_id; IF search_place_id IS NULL THEN -- null record of right type - select * from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::INTEGER and type = 'house' limit 1 INTO nextnode; + select * from placex where osm_type = 'N' and osm_id = waynodes[nodeidpos]::BIGINT and type = 'house' limit 1 INTO nextnode; select ST_SetSRID(ST_Point(lon::float/10000000,lat::float/10000000),4326) from planet_osm_nodes where id = waynodes[nodeidpos] INTO nextnode.geometry; IF nextnode.geometry IS NULL THEN -- we don't have any information about this point, most likely @@ -1143,6 +1155,9 @@ BEGIN NEW.rank_address := NEW.rank_search; ELSEIF NEW.class = 'natural' and NEW.type in ('coastline') THEN RETURN NULL; + ELSEIF NEW.class = 'mountain_pass' THEN + NEW.rank_search := 20; + NEW.rank_address := 0; END IF; END IF; @@ -1408,7 +1423,7 @@ BEGIN FOR i IN 1..array_upper(relation.members, 1) BY 2 LOOP IF NEW.parent_place_id IS NULL AND relation.members[i+1] = 'street' THEN --RAISE WARNING 'node in relation %',relation; - SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::integer + SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::bigint and rank_search = 26 INTO NEW.parent_place_id; END IF; END LOOP; @@ -1437,7 +1452,7 @@ BEGIN FOR i IN 1..array_upper(relation.members, 1) BY 2 LOOP IF NEW.parent_place_id IS NULL AND relation.members[i+1] = 'street' THEN --RAISE WARNING 'node in way that is in a relation %',relation; - SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::integer + SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::bigint and rank_search = 26 INTO NEW.parent_place_id; END IF; END LOOP; @@ -1482,7 +1497,7 @@ BEGIN FOR i IN 1..array_upper(relation.members, 1) BY 2 LOOP IF NEW.parent_place_id IS NULL AND relation.members[i+1] = 'street' THEN --RAISE WARNING 'way that is in a relation %',relation; - SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::integer + SELECT place_id from placex where osm_type='W' and osm_id = substring(relation.members[i],2,200)::bigint and rank_search = 26 INTO NEW.parent_place_id; END IF; END LOOP; @@ -1545,7 +1560,7 @@ BEGIN result := add_location(NEW.place_id, NEW.calculated_country_code, NEW.partition, name_vector, NEW.rank_search, NEW.rank_address, NEW.geometry); END IF; - result := insertSearchName(NEW.partition, NEW.place_id, NEW.calculated_country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid); + result := insertSearchName(NEW.partition, NEW.place_id, NEW.calculated_country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid, NEW.geometry); return NEW; END IF; @@ -1575,7 +1590,7 @@ BEGIN -- merge in the label name, re-init word vector IF NOT linkedPlacex.name IS NULL THEN NEW.name := linkedPlacex.name || NEW.name; - name_vector := make_keywords(NEW.name); + name_vector := array_merge(name_vector, make_keywords(linkedPlacex.name)); END IF; -- merge in extra tags @@ -1583,6 +1598,10 @@ BEGIN NEW.extratags := linkedPlacex.extratags || NEW.extratags; END IF; + IF NOT NEW.extratags ? linkedPlacex.class THEN + NEW.extratags := NEW.extratags || hstore(linkedPlacex.class, linkedPlacex.type); + END IF; + -- mark the linked place (excludes from search results) UPDATE placex set linked_place_id = NEW.place_id where place_id = linkedPlacex.place_id; @@ -1602,7 +1621,6 @@ BEGIN IF make_standard_name(NEW.name->'name') = make_standard_name(linkedPlacex.name->'name') AND NEW.rank_address = linkedPlacex.rank_address THEN - -- If we don't already have one use this as the centre point of the geometry IF NEW.centroid IS NULL THEN NEW.centroid := coalesce(linkedPlacex.centroid,st_centroid(linkedPlacex.geometry)); @@ -1619,6 +1637,10 @@ BEGIN NEW.extratags := linkedPlacex.extratags || NEW.extratags; END IF; + IF NOT NEW.extratags ? linkedPlacex.class THEN + NEW.extratags := NEW.extratags || hstore(linkedPlacex.class, linkedPlacex.type); + END IF; + -- mark the linked place (excludes from search results) UPDATE placex set linked_place_id = NEW.place_id where place_id = linkedPlacex.place_id; @@ -1656,6 +1678,10 @@ BEGIN -- merge in extra tags NEW.extratags := linkedPlacex.extratags || NEW.extratags; + IF NOT NEW.extratags ? linkedPlacex.class THEN + NEW.extratags := NEW.extratags || hstore(linkedPlacex.class, linkedPlacex.type); + END IF; + -- mark the linked place (excludes from search results) UPDATE placex set linked_place_id = NEW.place_id where place_id = linkedPlacex.place_id; @@ -1666,6 +1692,19 @@ BEGIN IF NEW.centroid IS NOT NULL THEN place_centroid := NEW.centroid; + -- Place might have had only a name tag before but has now received translations + -- from the linked place. Make sure a name tag for the default language exists in + -- this case. + IF NEW.name is not null AND array_upper(akeys(NEW.name),1) > 1 THEN + default_language := get_country_language_code(NEW.calculated_country_code); + IF default_language IS NOT NULL THEN + IF NEW.name ? 'name' AND NOT NEW.name ? ('name:'||default_language) THEN + NEW.name := NEW.name || hstore(('name:'||default_language), (NEW.name -> 'name')); + ELSEIF NEW.name ? ('name:'||default_language) AND NOT NEW.name ? 'name' THEN + NEW.name := NEW.name || hstore('name', (NEW.name -> ('name:'||default_language))); + END IF; + END IF; + END IF; END IF; -- Did we gain a wikipedia tag in the process? then we need to recalculate our importance @@ -1695,8 +1734,15 @@ BEGIN FOR i IN 1..array_upper(isin, 1) LOOP address_street_word_id := get_name_id(make_standard_name(isin[i])); IF address_street_word_id IS NOT NULL AND NOT(ARRAY[address_street_word_id] <@ isin_tokens) THEN + nameaddress_vector := array_merge(nameaddress_vector, ARRAY[address_street_word_id]); isin_tokens := isin_tokens || address_street_word_id; END IF; + + -- merge word into address vector + address_street_word_id := get_word_id(make_standard_name(isin[i])); + IF address_street_word_id IS NOT NULL THEN + nameaddress_vector := array_merge(nameaddress_vector, ARRAY[address_street_word_id]); + END IF; END LOOP; END IF; END IF; @@ -1706,8 +1752,15 @@ BEGIN FOR i IN 1..array_upper(isin, 1) LOOP address_street_word_id := get_name_id(make_standard_name(isin[i])); IF address_street_word_id IS NOT NULL AND NOT(ARRAY[address_street_word_id] <@ isin_tokens) THEN + nameaddress_vector := array_merge(nameaddress_vector, ARRAY[address_street_word_id]); isin_tokens := isin_tokens || address_street_word_id; END IF; + + -- merge into address vector + address_street_word_id := get_word_id(make_standard_name(isin[i])); + IF address_street_word_id IS NOT NULL THEN + nameaddress_vector := array_merge(nameaddress_vector, ARRAY[address_street_word_id]); + END IF; END LOOP; END IF; END IF; @@ -1718,6 +1771,10 @@ BEGIN address_street_word_id := get_name_id(make_standard_name(location.postcode)); nameaddress_vector := array_merge(nameaddress_vector, ARRAY[address_street_word_id]); isin_tokens := isin_tokens || address_street_word_id; + + -- also merge in the single word version + address_street_word_id := get_word_id(make_standard_name(location.postcode)); + nameaddress_vector := array_merge(nameaddress_vector, ARRAY[address_street_word_id]); END LOOP; END IF; @@ -1834,9 +1891,8 @@ BEGIN result := insertLocationRoad(NEW.partition, NEW.place_id, NEW.calculated_country_code, NEW.geometry); END IF; - result := insertSearchName(NEW.partition, NEW.place_id, NEW.calculated_country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid); + result := insertSearchName(NEW.partition, NEW.place_id, NEW.calculated_country_code, name_vector, nameaddress_vector, NEW.rank_search, NEW.rank_address, NEW.importance, place_centroid, NEW.geometry); --- INSERT INTO search_name values (NEW.place_id, NEW.rank_search, NEW.rank_search, 0, NEW.calculated_country_code, name_vector, nameaddress_vector, place_centroid); END IF; -- If we've not managed to pick up a better one - default centroid @@ -2287,11 +2343,11 @@ END; $$ LANGUAGE plpgsql; -DROP TYPE addressline CASCADE; +DROP TYPE IF EXISTS addressline CASCADE; create type addressline as ( place_id BIGINT, osm_type CHAR(1), - osm_id INTEGER, + osm_id BIGINT, name HSTORE, class TEXT, type TEXT,