support multi

This commit is contained in:
abelvm 2017-01-18 17:28:06 +01:00
parent 2b75da1db2
commit 9ab51027fc

View File

@ -96,27 +96,43 @@ $$ language plpgsql IMMUTABLE;
-- signed distance point to polygon with holes -- signed distance point to polygon with holes
-- negative is the point is out the polygon -- negative is the point is out the polygon
-- rev 1. adding MULTIPOLYGON and GEOMETRYCOLLECTION support by @abelvm
CREATE OR REPLACE FUNCTION _Signed_Dist( CREATE OR REPLACE FUNCTION _Signed_Dist(
IN polygon geometry, IN polygon geometry,
IN point geometry IN point geometry
) )
RETURNS numeric AS $$ RETURNS numeric AS $$
DECLARE DECLARE
pols geometry[];
pol geometry;
i integer; i integer;
j integer;
within integer; within integer;
w integer;
holes integer; holes integer;
dist numeric; dist numeric;
d numeric;
BEGIN BEGIN
dist := 1e999; dist := 1e999;
SELECT LEAST(dist, ST_distance(point, ST_ExteriorRing(polygon))::numeric) INTO dist; pols := array_agg((ST_dump(polygon)).geom);
SELECT CASE WHEN ST_Within(point,polygon) THEN 1 ELSE -1 END INTO within; FOR j in 1..array_length(pols, 1);
SELECT ST_NumInteriorRings(polygon) INTO holes; LOOP
IF holes > 0 THEN pol := pols[j];
FOR i IN 1..holes d := dist;
LOOP SELECT LEAST(dist, ST_distance(point, ST_ExteriorRing(pol))::numeric) INTO d;
SELECT LEAST(dist, ST_distance(point, ST_InteriorRingN(polygon, i))::numeric) INTO dist; SELECT CASE WHEN ST_Within(point,pol) THEN 1 ELSE -1 END INTO w;
END LOOP; SELECT ST_NumInteriorRings(pol) INTO holes;
END IF; IF holes > 0 THEN
FOR i IN 1..holes
LOOP
SELECT LEAST(d, ST_distance(point, ST_InteriorRingN(pol, i))::numeric) INTO d;
END LOOP;
END IF;
IF d < dist THEN
dist:= d;
within := w;
END IF;
END LOOP;
dist := dist * within::numeric; dist := dist * within::numeric;
RETURN dist; RETURN dist;
END; END;