]> git.openstreetmap.org Git - nominatim.git/commitdiff
get address terms from address tags for rank 30
authorSarah Hoffmann <lonvia@denofr.de>
Tue, 10 Nov 2020 18:50:30 +0000 (19:50 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Mon, 16 Nov 2020 14:28:01 +0000 (15:28 +0100)
For rank 30 objects add extra elements into the place_addressline
table.

sql/functions/normalization.sql
sql/functions/placex_triggers.sql
sql/partition-functions.src.sql
test/bdd/db/import/addressing.feature

index 71b14ee5109aa198f510993247073df754cafdc5..c7ead7006c8408a583dd716cd4e5ae51bc33fef8 100644 (file)
@@ -414,10 +414,14 @@ $$
 LANGUAGE plpgsql;
 
 
-CREATE OR REPLACE FUNCTION create_poi_search_terms(parent_place_id BIGINT,
+CREATE OR REPLACE FUNCTION create_poi_search_terms(obj_place_id BIGINT,
+                                                   in_partition SMALLINT,
+                                                   parent_place_id BIGINT,
                                                    address HSTORE,
+                                                   country TEXT,
                                                    housenumber TEXT,
                                                    initial_name_vector INTEGER[],
+                                                   geometry GEOMETRY,
                                                    OUT name_vector INTEGER[],
                                                    OUT nameaddress_vector INTEGER[])
   AS $$
@@ -427,34 +431,52 @@ DECLARE
   addr_place_ids INTEGER[];
 
   addr_item RECORD;
+  parent_address_place_ids BIGINT[];
 BEGIN
-  -- Compute all search terms from the addr: tags.
   nameaddress_vector := '{}'::INTEGER[];
 
+  SELECT s.name_vector, s.nameaddress_vector
+    INTO parent_name_vector, parent_address_vector
+    FROM search_name s
+    WHERE s.place_id = parent_place_id;
+
+  -- Compute all search terms from the addr: tags.
   IF address IS NOT NULL THEN
-    FOR addr_item IN SELECT * FROM each(address)
+    FOR addr_item IN
+      SELECT * FROM
+        get_places_for_addr_tags(in_partition, geometry, address, country)
     LOOP
-      IF addr_item.key IN ('city', 'tiger:county', 'state', 'suburb', 'province',
-                           'district', 'region', 'county', 'municipality',
-                           'hamlet', 'village', 'subdistrict', 'town',
-                           'neighbourhood', 'quarter', 'parish')
-      THEN
-          nameaddress_vector := array_merge(nameaddress_vector,
-                                            addr_ids_from_name(addr_item.value));
-      END IF;
+        IF addr_item.place_id is null THEN
+            nameaddress_vector := array_merge(nameaddress_vector,
+                                              addr_item.keywords);
+            CONTINUE;
+        END IF;
+
+        IF parent_address_place_ids is null THEN
+            SELECT array_agg(parent_place_id) INTO parent_address_place_ids
+              FROM place_addressline
+             WHERE place_id = parent_place_id;
+        END IF;
+
+        IF not parent_address_place_ids @> ARRAY[addr_item.place_id] THEN
+            nameaddress_vector := array_merge(nameaddress_vector,
+                                              addr_item.keywords);
+
+            INSERT INTO place_addressline (place_id, address_place_id, fromarea,
+                                           isaddress, distance, cached_rank_address)
+            VALUES (obj_place_id, addr_item.place_id, not addr_item.isguess,
+                    true, addr_item.distance, addr_item.rank_address);
+        END IF;
     END LOOP;
   END IF;
 
+
   -- If the POI is named, simply mix in all address terms and be done.
   IF array_length(initial_name_vector, 1) is not NULL THEN
     -- Cheating here by not recomputing all terms but simply using the ones
     -- from the parent object.
-    SELECT array_merge(s.name_vector, s.nameaddress_vector)
-      INTO parent_address_vector
-      FROM search_name s
-      WHERE s.place_id = parent_place_id;
-
     name_vector := initial_name_vector;
+    nameaddress_vector := array_merge(nameaddress_vector, parent_name_vector);
     nameaddress_vector := array_merge(nameaddress_vector, parent_address_vector);
 
     IF not address ? 'street' and address ? 'place' THEN
@@ -475,11 +497,6 @@ BEGIN
     RETURN;
   END IF;
 
-  SELECT s.name_vector, s.nameaddress_vector
-    INTO parent_name_vector, parent_address_vector
-    FROM search_name s
-    WHERE s.place_id = parent_place_id;
-
   -- Check if the parent covers all address terms.
   -- If not, create a search name entry with the house number as the name.
   -- This is unusual for the search_name table but prevents that the place
index 5e43b27afdb3999c3e7cb9e82c2886f5c63d6e91..c9095fbea94c3157932ff589642cdac7e0ecc2dc 100644 (file)
@@ -813,13 +813,17 @@ BEGIN
 
       END IF;
 
-      IF NOT %REVERSE-ONLY% THEN
+      IF array_length(name_vector, 1) is not NULL
+         OR inherited_address is not NULL OR NEW.address is not NULL
+      THEN
         SELECT * INTO name_vector, nameaddress_vector
-          FROM create_poi_search_terms(NEW.parent_place_id,
+          FROM create_poi_search_terms(NEW.place_id,
+                                       NEW.partition, NEW.parent_place_id,
                                        inherited_address || NEW.address,
-                                       NEW.housenumber, name_vector);
+                                       NEW.country_code, NEW.housenumber,
+                                       name_vector, NEW.centroid);
 
-        IF array_length(name_vector, 1) is not NULL THEN
+        IF not %REVERSE-ONLY% AND array_length(name_vector, 1) is not NULL THEN
           INSERT INTO search_name (place_id, search_rank, address_rank,
                                    importance, country_code, name_vector,
                                    nameaddress_vector, centroid)
index 8e54868b664bbbd108d2e371001a3b55ce1c4ca5..63548ab20ec6a1531f0bce77ef8e32c9338a9840 100644 (file)
@@ -72,8 +72,6 @@ BEGIN
   FOR item IN
     SELECT (get_addr_tag_rank(key, country)).*, key, name FROM
       (SELECT skeys(address) as key, svals(address) as name) x
-        WHERE key not in ('country', 'postcode', 'housenumber',
-                          'conscriptionnumber', 'streetnumber')
   LOOP
    IF item.from_rank is null THEN
      CONTINUE;
index e7d60c30d93cd67369818ab54b85228d2d80ecda..0421352139bd8c85adc86dc674a0e5382ecfcae5 100644 (file)
@@ -298,7 +298,7 @@ Feature: Address computation
             | object | address |
             | W1     | W2      |
 
-    Scenario: addr:* tags are honored even when the place is outside
+    Scenario: addr:* tags are honored even when a street is far away from the place
         Given the grid
             | 1 |   | 2 |   |   | 5 |
             |   |   |   | 8 | 9 |   |
@@ -321,3 +321,26 @@ Feature: Address computation
            | object | address |
            | W2     | R1      |
 
+
+    Scenario: addr:* tags are honored even when a POI is far away from the place
+        Given the grid
+            | 1 |   | 2 |   |   | 5 |
+            |   |   |   | 8 | 9 |   |
+            | 4 |   | 3 |   |   | 6 |
+        And the places
+            | osm | class    | type           | admin | name  | geometry    |
+            | R1  | boundary | administrative | 8     | Left  | (1,2,3,4,1) |
+            | R2  | boundary | administrative | 8     | Right | (2,3,6,5,2) |
+        And the named places
+            | osm | class   | type    | addr+city | geometry |
+            | W1  | highway | primary | Right     | 8,9      |
+            | N1  | amenity | cafe    | Left      | 9        |
+        When importing
+        Then place_addressline contains
+           | object | address | isaddress |
+           | W1     | R2      | True      |
+           | N1     | R1      | True      |
+        And place_addressline doesn't contain
+           | object | address |
+           | W1     | R1      |
+