X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/32d3eb46d5dfa4fd5486dc8abfb6afc1dcb0a360..2c61fe08a031bd4ccbe47c62c021321e2dff7510:/lib-sql/functions/utils.sql diff --git a/lib-sql/functions/utils.sql b/lib-sql/functions/utils.sql index 6af2afd5..30f94080 100644 --- a/lib-sql/functions/utils.sql +++ b/lib-sql/functions/utils.sql @@ -24,7 +24,7 @@ BEGIN RETURN ST_PointOnSurface(place); END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION geometry_sector(partition INTEGER, place GEOMETRY) @@ -34,7 +34,7 @@ BEGIN RETURN (partition*1000000) + (500-ST_X(place)::INTEGER)*1000 + (500-ST_Y(place)::INTEGER); END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; @@ -60,7 +60,7 @@ BEGIN RETURN r; END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; -- Return the node members with a given label from a relation member list -- as a set. @@ -88,7 +88,7 @@ BEGIN RETURN; END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION get_rel_node_members(members JSONB, memberLabels TEXT[]) @@ -107,7 +107,7 @@ BEGIN RETURN; END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; -- Copy 'name' to or from the default language. @@ -136,7 +136,7 @@ BEGIN END IF; END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; -- Find the nearest artificial postcode for the given geometry. @@ -172,7 +172,7 @@ BEGIN RETURN outcode; END; $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION get_country_code(place geometry) @@ -233,7 +233,7 @@ BEGIN RETURN NULL; END; $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION get_country_language_code(search_country_code VARCHAR(2)) @@ -251,7 +251,7 @@ BEGIN RETURN NULL; END; $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION get_partition(in_country_code VARCHAR(10)) @@ -268,7 +268,7 @@ BEGIN RETURN 0; END; $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; -- Find the parent of an address with addr:street/addr:place tag. @@ -299,7 +299,7 @@ BEGIN RETURN parent_place_id; END; $$ -LANGUAGE plpgsql STABLE; +LANGUAGE plpgsql STABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION delete_location(OLD_place_id BIGINT) @@ -337,7 +337,7 @@ BEGIN ST_Project(geom::geography, radius, 3.9269908)::geometry)); END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION add_location(place_id BIGINT, country_code varchar(2), @@ -393,19 +393,21 @@ DECLARE geo RECORD; area FLOAT; remainingdepth INTEGER; - added INTEGER; BEGIN - -- RAISE WARNING 'quad_split_geometry: maxarea=%, depth=%',maxarea,maxdepth; - IF (ST_GeometryType(geometry) not in ('ST_Polygon','ST_MultiPolygon') OR NOT ST_IsValid(geometry)) THEN + IF not ST_IsValid(geometry) THEN + RETURN; + END IF; + + IF ST_Dimension(geometry) != 2 OR maxdepth <= 1 THEN RETURN NEXT geometry; RETURN; END IF; remainingdepth := maxdepth - 1; area := ST_AREA(geometry); - IF remainingdepth < 1 OR area < maxarea THEN + IF area < maxarea THEN RETURN NEXT geometry; RETURN; END IF; @@ -425,7 +427,6 @@ BEGIN xmid := (xmin+xmax)/2; ymid := (ymin+ymax)/2; - added := 0; FOR seg IN 1..4 LOOP IF seg = 1 THEN @@ -441,23 +442,20 @@ BEGIN secbox := ST_SetSRID(ST_MakeBox2D(ST_Point(xmid,ymid),ST_Point(xmax,ymax)),4326); END IF; - IF st_intersects(geometry, secbox) THEN - secgeo := st_intersection(geometry, secbox); - IF NOT ST_IsEmpty(secgeo) AND ST_GeometryType(secgeo) in ('ST_Polygon','ST_MultiPolygon') THEN - FOR geo IN select quad_split_geometry(secgeo, maxarea, remainingdepth) as geom LOOP - IF NOT ST_IsEmpty(geo.geom) AND ST_GeometryType(geo.geom) in ('ST_Polygon','ST_MultiPolygon') THEN - added := added + 1; - RETURN NEXT geo.geom; - END IF; - END LOOP; - END IF; + secgeo := st_intersection(geometry, secbox); + IF NOT ST_IsEmpty(secgeo) AND ST_Dimension(secgeo) = 2 THEN + FOR geo IN SELECT quad_split_geometry(secgeo, maxarea, remainingdepth) as geom LOOP + IF NOT ST_IsEmpty(geo.geom) AND ST_Dimension(geo.geom) = 2 THEN + RETURN NEXT geo.geom; + END IF; + END LOOP; END IF; END LOOP; RETURN; END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION split_geometry(geometry GEOMETRY) @@ -466,14 +464,26 @@ CREATE OR REPLACE FUNCTION split_geometry(geometry GEOMETRY) DECLARE geo RECORD; BEGIN - -- 10000000000 is ~~ 1x1 degree - FOR geo IN select quad_split_geometry(geometry, 0.25, 20) as geom LOOP - RETURN NEXT geo.geom; - END LOOP; + IF ST_GeometryType(geometry) = 'ST_MultiPolygon' + and ST_Area(geometry) * 10 > ST_Area(Box2D(geometry)) + THEN + FOR geo IN + SELECT quad_split_geometry(g, 0.25, 20) as geom + FROM (SELECT (ST_Dump(geometry)).geom::geometry(Polygon, 4326) AS g) xx + LOOP + RETURN NEXT geo.geom; + END LOOP; + ELSE + FOR geo IN + SELECT quad_split_geometry(geometry, 0.25, 20) as geom + LOOP + RETURN NEXT geo.geom; + END LOOP; + END IF; RETURN; END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION simplify_large_polygons(geometry GEOMETRY) RETURNS GEOMETRY @@ -487,7 +497,7 @@ BEGIN RETURN geometry; END; $$ -LANGUAGE plpgsql IMMUTABLE; +LANGUAGE plpgsql IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION place_force_delete(placeid BIGINT)