Skip to content

Instantly share code, notes, and snippets.

@nim4n136
Created February 2, 2021 06:05
Show Gist options
  • Save nim4n136/17964f2ff5dbee03f94acc1e7df59ab0 to your computer and use it in GitHub Desktop.
Save nim4n136/17964f2ff5dbee03f94acc1e7df59ab0 to your computer and use it in GitHub Desktop.
Build sector function postgis
-- 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