Created
February 2, 2021 06:05
-
-
Save nim4n136/17964f2ff5dbee03f94acc1e7df59ab0 to your computer and use it in GitHub Desktop.
Build sector function postgis
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Radian | |
create or replace function misc_normalizeRadians(rad double precision) | |
returns double precision | |
as $$ | |
SELECT r-floor(r/pi())*(2*pi()) FROM (SELECT (floor(rad/(2*pi()))*-(2*pi())+rad) as r) as t; | |
$$ LANGUAGE sql immutable; | |
-- Heading by angle | |
create or replace function misc_rotateHeadingByAngle(heading double precision,angle double precision) | |
returns double precision | |
as $$ | |
select misc_normalizeRadians($1-$2); | |
$$ LANGUAGE sql immutable; | |
-- build clone | |
create or replace function util_buildCone(origin geometry,bearing double precision,angle double precision,sides double precision) | |
returns geometry | |
as $$ | |
BEGIN | |
IF ST_GeometryType($1)!='ST_Point' THEN | |
RAISE EXCEPTION 'Function only well defined for points, got: %',ST_GeometryType($1); | |
END IF; | |
IF abs($3)>=pi() THEN | |
RAISE EXCEPTION 'Cones can''t have interior angle greater or equal to half a rotation, got: %',$3; | |
END IF; | |
RETURN (select ST_MakePolygon(ST_MakeLine(ARRAY[$1,a,b,$1])) | |
from | |
util_translateTowardsBearing($1,misc_rotateHeadingByAngle($2,$3/2),$4) as a, | |
util_translateTowardsBearing($1,misc_rotateHeadingByAngle($2,-$3/2),$4) as b); | |
END | |
$$ language plpgsql immutable; | |
-- Build sector | |
create or replace function buildSector(origin geometry,bearing double precision,angle double precision,sides double precision) | |
returns geometry | |
as $$ | |
BEGIN | |
IF ST_GeometryType($1)!='ST_Point' THEN | |
RAISE EXCEPTION 'Function only well defined for points, got: %',ST_GeometryType($1); | |
END IF; | |
IF abs($3)>(2*pi()) THEN | |
RAISE EXCEPTION 'Cones can''t have a sector greater than the whole circle, got : %',$3; | |
END IF; | |
IF abs($3)=(2*pi()) THEN | |
RETURN (select ST_Buffer($1,$4,50)); | |
END IF; | |
IF abs($3)>(pi()/2) THEN | |
RETURN (select ST_Union(a,ST_Snap(b,a,$4/10000)) | |
from buildSector($1,misc_rotateHeadingByAngle($2,$3/4),$3/2,$4) as a, | |
buildSector($1,misc_rotateHeadingByAngle($2,-$3/4),$3/2,$4) as b); | |
END IF; | |
RETURN (select ST_Intersection(ST_Buffer($1,$4,50),util_buildCone($1,$2,$3,$4*2))); | |
END | |
$$ language plpgsql immutable; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment