]> git.openstreetmap.org Git - nominatim.git/blobdiff - sql/functions.sql
adapt status page to new word table layout
[nominatim.git] / sql / functions.sql
index fc48512859ea8b086ac8242a7b970fe630a582dd..e0d0897f97f4dd19bad10fbd76ed8f01162f7a12 100644 (file)
@@ -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
@@ -1852,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
@@ -2305,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,