]> git.openstreetmap.org Git - nominatim.git/blobdiff - sql/functions/placex_triggers.sql
linked centroids must always be within geometry
[nominatim.git] / sql / functions / placex_triggers.sql
index ffc83fa3aa03197e9a3ca22ac32cfbcbf219a12d..779301c56cc87f2fafe762d5dd3a281385745f68 100644 (file)
@@ -204,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
@@ -231,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
@@ -241,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;
@@ -592,6 +609,8 @@ DECLARE
   location RECORD;
   relation_members TEXT[];
 
+  centroid GEOMETRY;
+
   addr_street TEXT;
   addr_place TEXT;
 
@@ -666,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,
@@ -818,11 +837,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
@@ -830,7 +857,7 @@ 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);