From: Sarah Hoffmann Date: Thu, 26 Nov 2020 10:53:58 +0000 (+0100) Subject: restrict size of features that get a full address search X-Git-Tag: v3.6.0~18^2 X-Git-Url: https://git.openstreetmap.org./nominatim.git/commitdiff_plain/2db751700e6b1872fd9f65fa725b59d00ee993c2?ds=sidebyside;hp=1f07d63dc5a043c44faa478f418c38455cc6dd75 restrict size of features that get a full address search It would be nice to always compute addresses for rank 0 objects over the complete geometry, so that they can be found via all the admin boundaries that they intersect. However, there are a couple of extramely large boundaries in OSM (like timezones) where this results in thousands of possible address candidates that need to be checked. Fall back to getting the address of the centroid for them. --- diff --git a/sql/functions/placex_triggers.sql b/sql/functions/placex_triggers.sql index 6fd9e225..e80f14cb 100644 --- a/sql/functions/placex_triggers.sql +++ b/sql/functions/placex_triggers.sql @@ -508,7 +508,7 @@ DECLARE location RECORD; relation_members TEXT[]; - centroid GEOMETRY; + geom GEOMETRY; parent_address_level SMALLINT; place_address_level SMALLINT; @@ -849,9 +849,9 @@ BEGIN -- 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; + geom := coalesce(location.centroid, ST_Centroid(location.geometry)); + IF geom is not NULL AND ST_Within(geom, NEW.geometry) THEN + NEW.centroid := geom; END IF; --DEBUG: RAISE WARNING 'parent address: % rank address: %', parent_address_level, location.rank_address; @@ -918,8 +918,23 @@ BEGIN --DEBUG: RAISE WARNING 'Country names updated'; END IF; + -- For linear features we need the full geometry for determining the address + -- because they may go through several administrative entities. Otherwise use + -- the centroid for performance reasons. + IF ST_GeometryType(NEW.geometry) in ('ST_LineString', 'ST_MultiLineString') THEN + geom := NEW.geometry; + ELSE + geom := NEW.centroid; + END IF; + IF NEW.rank_address = 0 THEN max_rank := geometry_to_rank(NEW.rank_search, NEW.geometry, NEW.country_code); + -- Rank 0 features may also span multiple administrative areas (e.g. lakes) + -- so use the geometry here too. Just make sure the areas don't become too + -- large. + IF NEW.class = 'natural' or max_rank > 10 THEN + geom := NEW.geometry; + END IF; ELSEIF NEW.rank_address > 25 THEN max_rank := 25; ELSE @@ -927,11 +942,7 @@ BEGIN END IF; SELECT * FROM insert_addresslines(NEW.place_id, NEW.partition, max_rank, - NEW.address, - CASE WHEN (NEW.rank_address = 0 or - NEW.rank_search between 26 and 29) - THEN NEW.geometry ELSE NEW.centroid END, - NEW.country_code) + NEW.address, geom, NEW.country_code) INTO NEW.parent_place_id, NEW.postcode, nameaddress_vector; --DEBUG: RAISE WARNING 'RETURN insert_addresslines: %, %, %', NEW.parent_place_id, NEW.postcode, nameaddress_vector;