X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/d643ca8dee1d1371b3128129f416fc2e99912b7b..b0a350db37d9a3700accaedd12471f853d7e2dc8:/sql/functions/placex_triggers.sql

diff --git a/sql/functions/placex_triggers.sql b/sql/functions/placex_triggers.sql
index fb3f2dc5..d123e362 100644
--- a/sql/functions/placex_triggers.sql
+++ b/sql/functions/placex_triggers.sql
@@ -135,8 +135,7 @@ BEGIN
     IF fallback THEN
       IF ST_Area(bbox) < 0.01 THEN
         -- for smaller features get the nearest road
-        SELECT place_id FROM getNearestRoadFeature(poi_partition, bbox)
-          INTO parent_place_id;
+        SELECT getNearestRoadPlaceId(poi_partition, bbox) INTO parent_place_id;
         --DEBUG: RAISE WARNING 'Checked for nearest way (%)', parent_place_id;
       ELSE
         -- for larger features simply find the area with the largest rank that
@@ -205,9 +204,26 @@ BEGIN
     END IF;
   END IF;
 
+  -- If extratags has a place tag, look for linked nodes by their place type.
+  -- Area and node still have to have the same name.
+  IF bnd.extratags ? 'place' and bnd_name is not null THEN
+    FOR linked_placex IN
+      SELECT * FROM placex
+      WHERE make_standard_name(name->'name') = bnd_name
+        AND placex.class = 'place' AND placex.type = bnd.extratags->'place'
+        AND placex.osm_type = 'N'
+        AND placex.rank_search < 26 -- needed to select the right index
+        AND _st_covers(bnd.geometry, placex.geometry)
+    LOOP
+      --DEBUG: RAISE WARNING 'Found type-matching place node %', linked_placex.osm_id;
+      RETURN linked_placex;
+    END LOOP;
+  END IF;
+
   -- Search for relation members with role admin_center.
   IF bnd.osm_type = 'R' and bnd_name is not null
-     and relation_members is not null THEN
+     and relation_members is not null
+  THEN
     FOR rel_member IN
       SELECT get_rel_node_members(relation_members,
                                 ARRAY['admin_center','admin_centre']) as member
@@ -232,7 +248,7 @@ BEGIN
   END IF;
 
   -- Name searches can be done for ways as well as relations
-  IF bnd.osm_type in ('W','R') and bnd_name is not null THEN
+  IF bnd_name is not null THEN
     --DEBUG: RAISE WARNING 'Looking for nodes with matching names';
     FOR linked_placex IN
       SELECT placex.* from placex
@@ -242,7 +258,7 @@ BEGIN
         AND placex.rank_search < 26 -- needed to select the right index
         AND _st_covers(bnd.geometry, placex.geometry)
     LOOP
-      --DEBUG: RAISE WARNING 'Found matching place node %', linkedPlacex.osm_id;
+      --DEBUG: RAISE WARNING 'Found matching place node %', linked_placex.osm_id;
       RETURN linked_placex;
     END LOOP;
   END IF;
@@ -593,6 +609,8 @@ DECLARE
   location RECORD;
   relation_members TEXT[];
 
+  centroid GEOMETRY;
+
   addr_street TEXT;
   addr_place TEXT;
 
@@ -667,10 +685,10 @@ BEGIN
   -- Speed up searches - just use the centroid of the feature
   -- cheaper but less acurate
   NEW.centroid := ST_PointOnSurface(NEW.geometry);
-  -- For searching near features rather use the centroid
-  NEW.postcode := null;
   --DEBUG: RAISE WARNING 'Computing preliminary centroid at %',ST_AsText(NEW.centroid);
 
+  NEW.postcode := null;
+
   -- recalculate country and partition
   IF NEW.rank_search = 4 AND NEW.address is not NULL AND NEW.address ? 'country' THEN
     -- for countries, believe the mapped country code,
@@ -705,6 +723,7 @@ BEGIN
                   and ( relation_members[i+1] != 'side_stream' or NEW.name->'name' = name->'name')
                 LOOP
                   UPDATE placex SET linked_place_id = NEW.place_id WHERE place_id = linked_node_id;
+                  DELETE FROM search_name WHERE place_id = linked_node_id;
                 END LOOP;
               END IF;
           END LOOP;
@@ -819,11 +838,19 @@ BEGIN
   --DEBUG: RAISE WARNING 'Using full index mode for % %', NEW.osm_type, NEW.osm_id;
   SELECT * INTO location FROM find_linked_place(NEW);
   IF location.place_id is not null THEN
-      --DEBUG: RAISE WARNING 'Linked %', location;
+    --DEBUG: RAISE WARNING 'Linked %', location;
+
+    -- Use the linked point as the centre point of the geometry,
+    -- but only if it is within the area of the boundary.
+    centroid := coalesce(location.centroid, ST_Centroid(location.geometry));
+    IF centroid is not NULL AND ST_Within(centroid, NEW.geometry) THEN
+        NEW.centroid := centroid;
+    END IF;
 
-    -- Use this as the centre point of the geometry
-    NEW.centroid := coalesce(location.centroid,
-                             ST_Centroid(location.geometry));
+    -- Use the address rank of the linked place, if it has one
+    IF location.rank_address between 5 and 25 THEN
+      NEW.rank_address := location.rank_address;
+    END IF;
 
     -- merge in the label name
     IF NOT location.name IS NULL THEN
@@ -831,13 +858,15 @@ BEGIN
     END IF;
 
     -- merge in extra tags
-    NEW.extratags := hstore(location.class, location.type)
+    NEW.extratags := hstore('linked_' || location.class, location.type)
                      || coalesce(location.extratags, ''::hstore)
                      || coalesce(NEW.extratags, ''::hstore);
 
     -- mark the linked place (excludes from search results)
     UPDATE placex set linked_place_id = NEW.place_id
       WHERE place_id = location.place_id;
+    -- ensure that those places are not found anymore
+    DELETE FROM search_name WHERE place_id = location.place_id;
 
     SELECT wikipedia, importance
       FROM compute_importance(location.extratags, NEW.country_code,
