]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge pull request #2074 from lonvia/add-housenumber-to-unknown-places
authorSarah Hoffmann <lonvia@denofr.de>
Wed, 25 Nov 2020 15:57:09 +0000 (16:57 +0100)
committerGitHub <noreply@github.com>
Wed, 25 Nov 2020 15:57:09 +0000 (16:57 +0100)
Improve finding addresses that have their own search_name entry because of unknown addr:* parts

lib/SearchDescription.php
sql/functions/normalization.sql
test/bdd/db/import/search_name.feature
test/bdd/steps/db_ops.py
utils/query.php

index 94ba87ff76480e3e237010e0b7005f5fa835034b..1e1955c249a7e8a498a9c1d92d4bc08991fbf6b1 100644 (file)
@@ -248,6 +248,18 @@ class SearchDescription
                     $oSearch->iSearchRank++;
                 }
                 $aNewSearches[] = $oSearch;
+                // Housenumbers may appear in the name when the place has its own
+                // address terms.
+                if ($oSearchTerm->iId !== null
+                    && ($this->iNamePhrase >= 0 || empty($this->aName))
+                    && empty($this->aAddress)
+                   ) {
+                    $oSearch = clone $this;
+                    $oSearch->iSearchRank++;
+                    $oSearch->aAddress = $this->aName;
+                    $oSearch->aName = array($oSearchTerm->iId => $oSearchTerm->iId);
+                    $aNewSearches[] = $oSearch;
+                }
             }
         } elseif ($sPhraseType == ''
                   && is_a($oSearchTerm, '\Nominatim\Token\SpecialTerm')
index 4aea0e9ba3673854dd4cf8ed7dea492916600b66..8bb4915bbf8612ab858c98345409bbef57ff6eb0 100644 (file)
@@ -490,53 +490,34 @@ BEGIN
     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.
-    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
-      -- make sure addr:place terms are always searchable
-      nameaddress_vector := array_merge(nameaddress_vector,
-                                        addr_ids_from_name(address->'place'));
-    END IF;
-
-    RETURN;
-  END IF;
-
-  ----- unnamed POIS
-
-  IF (array_length(nameaddress_vector, 1) is null
-      and (address ? 'street'or not address ? 'place'))
-     or housenumber is null
-  THEN
-    RETURN;
-  END IF;
+  name_vector := initial_name_vector;
 
   -- 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
   -- is returned when we only search for the street/place.
 
-  IF not nameaddress_vector <@ parent_address_vector THEN
-    name_vector := ARRAY[getorcreate_name_id(housenumber)];
+  IF housenumber is not null and not nameaddress_vector <@ parent_address_vector THEN
+    name_vector := array_merge(name_vector,
+                               ARRAY[getorcreate_housenumber_id(make_standard_name(housenumber))]);
   END IF;
 
   IF not address ? 'street' and address ? 'place' THEN
     addr_place_ids := addr_ids_from_name(address->'place');
     IF not addr_place_ids <@ parent_name_vector THEN
-      -- addr:place tag exists without a corresponding place. Mix in addr:place
-      -- in the address.
-      name_vector := ARRAY[getorcreate_name_id(housenumber)];
+      -- make sure addr:place terms are always searchable
       nameaddress_vector := array_merge(nameaddress_vector, addr_place_ids);
+      -- If there is a housenumber, also add the place name as a name,
+      -- so we can search it by the usual housenumber+place algorithms.
+      IF housenumber is not null THEN
+        name_vector := array_merge(name_vector,
+                                   ARRAY[getorcreate_name_id(make_standard_name(address->'place'))]);
+      END IF;
     END IF;
   END IF;
 
-  -- Merge the parent name and address.
+  -- Cheating here by not recomputing all terms but simply using the ones
+  -- from the parent object.
   nameaddress_vector := array_merge(nameaddress_vector, parent_name_vector);
   nameaddress_vector := array_merge(nameaddress_vector, parent_address_vector);
 
index 30c430a6b4503e33da91aa4d53a04eb8e9db4d25..0e922e1d6b503716f649ff8b13409adf21bd9a1f 100644 (file)
@@ -23,12 +23,20 @@ Feature: Creation of search terms
          | W1  | highway | residential | Rose Street | :w-north |
         When importing
         Then search_name contains
-         | object | name_vector | nameaddress_vector |
-         | N1     | #23         | Rose Street, Walltown |
+         | object | nameaddress_vector |
+         | N1     | Rose, Street, Walltown |
         When searching for "23 Rose Street, Walltown"
         Then results contain
          | osm_type | osm_id | name |
          | N        | 1      | 23, Rose Street |
+        When searching for "Walltown, Rose Street 23"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | 23, Rose Street |
+        When searching for "Rose Street 23, Walltown"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | 23, Rose Street |
 
     Scenario: Searching for unknown addr: tags also works for multiple words
         Given the scene roads-with-pois
@@ -40,12 +48,20 @@ Feature: Creation of search terms
          | W1  | highway | residential | Rose Street | :w-north |
         When importing
         Then search_name contains
-         | object | name_vector | nameaddress_vector |
-         | N1     | #23         | Rose Street, Little, Big, Town |
+         | object | nameaddress_vector |
+         | N1     | Rose Street, Little, Big, Town |
         When searching for "23 Rose Street, Little Big Town"
         Then results contain
          | osm_type | osm_id | name |
          | N        | 1      | 23, Rose Street |
+        When searching for "Rose Street 23, Little Big Town"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | 23, Rose Street |
+        When searching for "Little big Town, Rose Street 23"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | 23, Rose Street |
 
      Scenario: Unnamed POI has no search entry when it has known addr: tags
         Given the scene roads-with-pois
@@ -88,7 +104,7 @@ Feature: Creation of search terms
          | N1     | N2              |
         Then search_name contains
          | object | name_vector | nameaddress_vector |
-         | N1     | #23         | Walltown, Strange, Town |
+         | N1     | #Walltown   | Strange, Town |
         When searching for "23 Rose Street"
         Then exactly 1 results are returned
         And results contain
@@ -98,6 +114,70 @@ Feature: Creation of search terms
         Then results contain
          | osm_type | osm_id | name |
          | N        | 1      | 23, Walltown, Strange Town |
+        When searching for "Walltown 23, Strange Town"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | 23, Walltown, Strange Town |
+        When searching for "Strange Town, Walltown 23"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | 23, Walltown, Strange Town |
+
+    Scenario: Named POIs can be searched by housenumber when unknown addr:place is present
+        Given the scene roads-with-pois
+        And the places
+         | osm | class   | type  | name       | housenr | addr+place | geometry |
+         | N1  | place   | house | Blue house | 23      | Walltown   | :p-N1 |
+        And the places
+         | osm | class   | type        | name+name    | geometry |
+         | W1  | highway | residential | Rose Street  | :w-north |
+         | N2  | place   | city        | Strange Town | :p-N1 |
+        When importing
+        Then search_name contains
+         | object | name_vector      | nameaddress_vector      |
+         | N1     | #Walltown, #Blue house | Walltown, Strange, Town |
+        When searching for "23 Walltown, Strange Town"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Blue house, 23, Walltown, Strange Town |
+        When searching for "Walltown 23, Strange Town"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Blue house, 23, Walltown, Strange Town |
+        When searching for "Strange Town, Walltown 23"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Blue house, 23, Walltown, Strange Town |
+        When searching for "Strange Town, Walltown 23, Blue house"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Blue house, 23, Walltown, Strange Town |
+        When searching for "Strange Town, Walltown, Blue house"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Blue house, 23, Walltown, Strange Town |
+
+    Scenario: Named POIs can be found when unknown multi-word addr:place is present
+        Given the scene roads-with-pois
+        And the places
+         | osm | class   | type  | name       | housenr | addr+place | geometry |
+         | N1  | place   | house | Blue house | 23      | Moon sun   | :p-N1 |
+        And the places
+         | osm | class   | type        | name+name    | geometry |
+         | W1  | highway | residential | Rose Street  | :w-north |
+         | N2  | place   | city        | Strange Town | :p-N1 |
+        When importing
+        Then search_name contains
+         | object | name_vector      | nameaddress_vector      |
+         | N1     | #Moon sun, #Blue house | Moon, Sun, Strange, Town |
+        When searching for "23 Moon Sun, Strange Town"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Blue house, 23, Moon sun, Strange Town |
+        When searching for "Blue house, Moon Sun, Strange Town"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Blue house, 23, Moon sun, Strange Town |
 
     Scenario: Unnamed POIs doesn't inherit parent name when addr:place is present only in parent address
         Given the scene roads-with-pois
@@ -111,7 +191,7 @@ Feature: Creation of search terms
         When importing
         Then search_name contains
          | object | name_vector | nameaddress_vector |
-         | N1     | #23         | Walltown |
+         | N1     | #Walltown   | Strange, Town      |
         When searching for "23 Rose Street, Walltown"
         Then exactly 1 result is returned
         And results contain
@@ -157,22 +237,38 @@ Feature: Creation of search terms
         When searching for "23 Lily Street"
         Then exactly 0 results are returned
 
-    Scenario: Named POIs have unknown address tags added in the search_name table
+    Scenario: Named POIs get unknown address tags added in the search_name table
         Given the scene roads-with-pois
         And the places
-         | osm | class   | type        | name+name  | addr+city | geometry |
-         | N1  | place   | house       | Green Moss | Walltown  | :p-N1 |
+         | osm | class   | type        | name+name  | housenr | addr+city | geometry |
+         | N1  | place   | house       | Green Moss | 26      | Walltown  | :p-N1 |
         And the places
          | osm | class   | type        | name+name   | geometry |
          | W1  | highway | residential | Rose Street | :w-north |
         When importing
         Then search_name contains
          | object | name_vector | nameaddress_vector |
-         | N1     | #Green Moss | Rose Street, Walltown |
+         | N1     | #Green Moss | Rose, Street, Walltown |
         When searching for "Green Moss, Rose Street, Walltown"
         Then results contain
          | osm_type | osm_id | name |
-         | N        | 1      | Green Moss, Rose Street |
+         | N        | 1      | Green Moss, 26, Rose Street |
+        When searching for "Green Moss, 26, Rose Street, Walltown"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Green Moss, 26, Rose Street |
+        When searching for "26, Rose Street, Walltown"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Green Moss, 26, Rose Street |
+        When searching for "Rose Street 26, Walltown"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Green Moss, 26, Rose Street |
+        When searching for "Walltown, Rose Street 26"
+        Then results contain
+         | osm_type | osm_id | name |
+         | N        | 1      | Green Moss, 26, Rose Street |
 
     Scenario: Named POI doesn't inherit parent name when addr:place is present only in parent address
         Given the scene roads-with-pois
index 377c977d412986de192537928117ff39b86188b0..2b012c41d9be286717b385310780083001cc1602 100644 (file)
@@ -487,8 +487,8 @@ def check_search_name_contents(context, exclude):
                                    """,
                                    (terms, words))
                     if not exclude:
-                        ok_(subcur.rowcount >= len(terms),
-                            "No word entry found for " + row[h])
+                        ok_(subcur.rowcount >= len(terms) + len(words),
+                            "No word entry found for " + row[h] + ". Entries found: " + str(subcur.rowcount))
                     for wid in subcur:
                         if exclude:
                             assert_not_in(wid[0], res[h],
index 956bb56634bddd79ad295d1b7cd9d75a4fd552f3..6068c7c00af9efbd18f68db0fd021a17808472b9 100644 (file)
@@ -58,6 +58,7 @@ if (!$oParams->hasSetAny($aSearchParams)) {
 $oGeocode = new Nominatim\Geocode($oDB);
 
 $oGeocode->setLanguagePreference($oParams->getPreferredLanguages(false));
+$oGeocode->setReverseInPlan(true);
 $oGeocode->loadParamArray($oParams);
 
 if ($oParams->getBool('search')) {