X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/2c05fc858a53bc84cdcfa84d898ae39bc2b2d8ac..3c188164ab73fc3442db1e8979b86ef5503f6b32:/lib-sql/functions/placex_triggers.sql?ds=sidebyside diff --git a/lib-sql/functions/placex_triggers.sql b/lib-sql/functions/placex_triggers.sql index 37b57b64..70071b2f 100644 --- a/lib-sql/functions/placex_triggers.sql +++ b/lib-sql/functions/placex_triggers.sql @@ -16,7 +16,9 @@ CREATE TYPE prepare_update_info AS ( country_code TEXT, class TEXT, type TEXT, - linked_place_id BIGINT + linked_place_id BIGINT, + centroid_x float, + centroid_y float ); -- Retrieve the data needed by the indexer for updating the place. @@ -47,7 +49,7 @@ BEGIN and rank_search = 30 AND ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') LIMIT 1; ELSE - -- See if we can inherit addtional address tags from an interpolation. + -- See if we can inherit additional address tags from an interpolation. -- These will become permanent. FOR location IN SELECT (address - 'interpolation'::text - 'housenumber'::text) as address @@ -71,6 +73,8 @@ BEGIN result.type := p.type; result.country_code := p.country_code; result.rank_address := p.rank_address; + result.centroid_x := ST_X(p.centroid); + result.centroid_y := ST_Y(p.centroid); -- Names of linked places need to be merged in, so search for a linkable -- place already here. @@ -864,29 +868,55 @@ BEGIN IF NEW.rank_address > 9 THEN -- Second check that the boundary is not completely contained in a - -- place area with a higher address rank + -- place area with a equal or higher address rank. FOR location IN - SELECT rank_address FROM placex + SELECT rank_address + FROM placex, + LATERAL compute_place_rank(country_code, 'A', class, type, + admin_level, False, null) prank WHERE class = 'place' and rank_address < 24 - and rank_address > NEW.rank_address + and prank.address_rank >= NEW.rank_address and geometry && NEW.geometry and geometry ~ NEW.geometry -- needed because ST_Relate does not do bbox cover test and ST_Relate(geometry, NEW.geometry, 'T*T***FF*') -- contains but not equal - ORDER BY rank_address desc LIMIT 1 + ORDER BY prank.address_rank desc LIMIT 1 LOOP NEW.rank_address := location.rank_address + 2; END LOOP; END IF; + ELSEIF NEW.class = 'place' + and ST_GeometryType(NEW.geometry) in ('ST_Polygon', 'ST_MultiPolygon') + and NEW.rank_address between 16 and 23 + THEN + -- For place areas make sure they are not completely contained in an area + -- with a equal or higher address rank. + FOR location IN + SELECT rank_address + FROM placex, + LATERAL compute_place_rank(country_code, 'A', class, type, + admin_level, False, null) prank + WHERE prank.address_rank < 24 + and prank.address_rank >= NEW.rank_address + and geometry && NEW.geometry + and geometry ~ NEW.geometry -- needed because ST_Relate does not do bbox cover test + and ST_Relate(geometry, NEW.geometry, 'T*T***FF*') -- contains but not equal + ORDER BY prank.address_rank desc LIMIT 1 + LOOP + NEW.rank_address := location.rank_address + 2; + END LOOP; ELSEIF NEW.class = 'place' and NEW.osm_type = 'N' - and NEW.rank_address between 16 and 23 + and NEW.rank_address between 16 and 23 THEN - -- If a place node is contained in a admin boundary with the same address level - -- and has not been linked, then make the node a subpart by increasing the - -- address rank (city level and above). + -- If a place node is contained in an admin or place boundary with the same + -- address level and has not been linked, then make the node a subpart + -- by increasing the address rank (city level and above). FOR location IN - SELECT rank_address FROM placex - WHERE osm_type = 'R' and class = 'boundary' and type = 'administrative' - and rank_address = NEW.rank_address + SELECT rank_address + FROM placex, + LATERAL compute_place_rank(country_code, 'A', class, type, + admin_level, False, null) prank + WHERE osm_type = 'R' + and prank.address_rank = NEW.rank_address and geometry && NEW.centroid and _ST_Covers(geometry, NEW.centroid) LIMIT 1 LOOP @@ -966,7 +996,7 @@ BEGIN {% if debug %}RAISE WARNING 'Got parent details from search name';{% endif %} -- determine postcode - NEW.postcode := coalesce(token_normalized_postcode(NEW.address->'postcode'), + NEW.postcode := coalesce(token_get_postcode(NEW.token_info), location.postcode, get_nearest_postcode(NEW.country_code, NEW.centroid)); @@ -1006,7 +1036,7 @@ BEGIN {% if debug %}RAISE WARNING 'Using full index mode for % %', NEW.osm_type, NEW.osm_id;{% endif %} IF linked_place is not null THEN -- Recompute the ranks here as the ones from the linked place might - -- have been shifted to accomodate surrounding boundaries. + -- have been shifted to accommodate surrounding boundaries. SELECT place_id, osm_id, class, type, extratags, centroid, geometry, (compute_place_rank(country_code, osm_type, class, type, admin_level, @@ -1036,7 +1066,9 @@ BEGIN || coalesce(NEW.extratags, ''::hstore); -- mark the linked place (excludes from search results) - UPDATE placex set linked_place_id = NEW.place_id + -- Force reindexing to remove any traces from the search indexes and + -- reset the address rank if necessary. + UPDATE placex set linked_place_id = NEW.place_id, indexed_status = 2 WHERE place_id = location.place_id; -- ensure that those places are not found anymore {% if 'search_name' in db.tables %} @@ -1075,7 +1107,7 @@ BEGIN THEN -- Update the list of country names. -- Only take the name from the largest area for the given country code - -- in the hope that this is the authoritive one. + -- in the hope that this is the authoritative one. -- Also replace any old names so that all mapping mistakes can -- be fixed through regular OSM updates. FOR location IN @@ -1122,8 +1154,7 @@ BEGIN {% if debug %}RAISE WARNING 'RETURN insert_addresslines: %, %, %', NEW.parent_place_id, NEW.postcode, nameaddress_vector;{% endif %} - NEW.postcode := coalesce(token_normalized_postcode(NEW.address->'postcode'), - NEW.postcode); + NEW.postcode := coalesce(token_get_postcode(NEW.token_info), NEW.postcode); -- if we have a name add this to the name search table IF NEW.name IS NOT NULL THEN @@ -1164,7 +1195,7 @@ BEGIN NEW.postcode := get_nearest_postcode(NEW.country_code, NEW.geometry); END IF; - {% if debug %}RAISE WARNING 'place update % % finsihed.', NEW.osm_type, NEW.osm_id;{% endif %} + {% if debug %}RAISE WARNING 'place update % % finished.', NEW.osm_type, NEW.osm_id;{% endif %} NEW.token_info := token_strip_info(NEW.token_info); RETURN NEW;