]> git.openstreetmap.org Git - nominatim.git/commitdiff
get additional addresses for rank 30 objects
authorSarah Hoffmann <lonvia@denofr.de>
Wed, 11 Nov 2020 10:52:14 +0000 (11:52 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Mon, 16 Nov 2020 14:28:01 +0000 (15:28 +0100)
get_addressdata() now also checks if the place itself has entries
in the place_addressline table and merges them into the results.

Also restrict checking for address tag places to cases where the
name cannot be found in the parent's address search terms. Looking
up all address tags is just too slow.

sql/functions/address_lookup.sql
sql/functions/normalization.sql
test/bdd/db/import/addressing.feature

index 1a5ed391d42ae9c049cabcb21b801106b5d6ddc6..266e8686d5fde5845dfa05e78776a23df4580fb1 100644 (file)
@@ -90,7 +90,7 @@ DECLARE
   for_place_id BIGINT;
   result TEXT[];
   search TEXT[];
-  found INTEGER;
+  current_rank_address INTEGER;
   location RECORD;
   countrylocation RECORD;
   searchcountrycode varchar(2);
@@ -103,7 +103,7 @@ DECLARE
   search_unlisted_place TEXT;
   countryname HSTORE;
 BEGIN
-  -- The place ein question might not have a direct entry in place_addressline.
+  -- The place in question might not have a direct entry in place_addressline.
   -- Look for the parent of such places then and save if in for_place_id.
 
   postcode_isexact := false;
@@ -177,9 +177,8 @@ BEGIN
 
 --RAISE WARNING '% % % %',searchcountrycode, searchhousenumber, searchpostcode;
 
-  found := 1000; -- the lowest rank_address included
+  -- --- Return the record for the base entry.
 
-  -- Return the record for the base entry.
   FOR location IN
     SELECT placex.place_id, osm_type, osm_id, name,
            coalesce(extratags->'linked_place', extratags->'place') as place_type,
@@ -206,9 +205,12 @@ BEGIN
                            location.admin_level, true, location.isaddress,
                            location.rank_address, location.distance)::addressline;
     RETURN NEXT countrylocation;
-    found := location.rank_address;
+
+    current_rank_address := location.rank_address;
   END LOOP;
 
+  -- --- Return records for address parts.
+
   FOR location IN
     SELECT placex.place_id, osm_type, osm_id, name, class, type,
            coalesce(extratags->'linked_place', extratags->'place') as place_type,
@@ -216,14 +218,15 @@ BEGIN
            CASE WHEN rank_address = 11 THEN 5 ELSE rank_address END as rank_address,
            distance, country_code, postcode
       FROM place_addressline join placex on (address_place_id = placex.place_id)
-      WHERE place_addressline.place_id = for_place_id
+      WHERE place_addressline.place_id IN (for_place_id, in_place_id)
             AND linked_place_id is null
             AND (placex.country_code IS NULL OR searchcountrycode IS NULL
                  OR placex.country_code = searchcountrycode)
-      ORDER BY rank_address desc, isaddress desc, fromarea desc,
+      ORDER BY rank_address desc, (place_addressline.place_id = in_place_id) desc,
+               isaddress desc, fromarea desc,
                distance asc, rank_search desc
   LOOP
---RAISE WARNING '%',location;
+    -- RAISE WARNING '%',location;
     IF searchcountrycode IS NULL AND location.country_code IS NOT NULL THEN
       searchcountrycode := location.country_code;
     END IF;
@@ -243,17 +246,21 @@ BEGIN
                            location.name, location.class, location.type,
                            location.place_type,
                            location.admin_level, location.fromarea,
-                           location.isaddress, location.rank_address,
+                           location.isaddress and location.rank_address != current_rank_address,
+                           location.rank_address,
                            location.distance)::addressline;
     RETURN NEXT countrylocation;
-    found := location.rank_address;
+
+    IF location.isaddress THEN
+      current_rank_address := location.rank_address;
+    END IF;
   END LOOP;
 
   -- If no country was included yet, add the name information from country_name.
-  IF found > 4 THEN
+  IF current_rank_address > 4 THEN
     SELECT name FROM country_name
       WHERE country_code = searchcountrycode LIMIT 1 INTO countryname;
---RAISE WARNING '% % %',found,searchcountrycode,countryname;
+--RAISE WARNING '% % %',current_rank_address,searchcountrycode,countryname;
     IF countryname IS NOT NULL THEN
       location := ROW(null, null, null, countryname, 'place', 'country', NULL,
                       null, true, true, 4, 0)::addressline;
index c7ead7006c8408a583dd716cd4e5ae51bc33fef8..fc13aa9096694548cc34a4100b35d459e3068321 100644 (file)
@@ -432,6 +432,7 @@ DECLARE
 
   addr_item RECORD;
   parent_address_place_ids BIGINT[];
+  filtered_address HSTORE;
 BEGIN
   nameaddress_vector := '{}'::INTEGER[];
 
@@ -440,11 +441,18 @@ BEGIN
     FROM search_name s
     WHERE s.place_id = parent_place_id;
 
+  -- Find all address tags that don't appear in the parent search names.
+  SELECT hstore(array_agg(ARRAY[k, v])) INTO filtered_address
+    FROM (SELECT skeys(address) as k, svals(address) as v) a
+   WHERE not addr_ids_from_name(v) && parent_address_vector
+         AND k not in ('country', 'street', 'place', 'postcode',
+                       'housenumber', 'streetnumber', 'consriptionnumber');
+
   -- Compute all search terms from the addr: tags.
-  IF address IS NOT NULL THEN
+  IF filtered_address IS NOT NULL THEN
     FOR addr_item IN
       SELECT * FROM
-        get_places_for_addr_tags(in_partition, geometry, address, country)
+        get_places_for_addr_tags(in_partition, geometry, filtered_address, country)
     LOOP
         IF addr_item.place_id is null THEN
             nameaddress_vector := array_merge(nameaddress_vector,
index 0421352139bd8c85adc86dc674a0e5382ecfcae5..6547545a063ae92e1b11c7537c414fbe51234b47 100644 (file)
@@ -331,10 +331,10 @@ Feature: Address computation
             | 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        |
+        And the places
+            | osm | class   | type    | name      | addr+city | geometry |
+            | W1  | highway | primary | Wonderway | Right     | 8,9      |
+            | N1  | amenity | cafe    | Bolder    | Left      | 9        |
         When importing
         Then place_addressline contains
            | object | address | isaddress |
@@ -343,4 +343,8 @@ Feature: Address computation
         And place_addressline doesn't contain
            | object | address |
            | W1     | R1      |
+        When searching for "Bolder"
+        Then results contain
+           | osm_type | osm_id | name                    |
+           | N        | 1      | Bolder, Wonderway, Left |