Building on the answer from @user3307073 and extending it to handle angles greater or equal to 180 degrees.
First some helper functions:
normalizes angle in radians to (-pi,pi)
create or replace function misc_normalizeRadians(rad double precision)
returns double precision
as $$
SELECT r-floor(r/pi())*(2*pi()) FROM (SELECT (floor($1/(2*pi()))*-(2*pi())+$1) as r) as t;
$$ LANGUAGE sql immutable;
Rotates a 2D heading with an angle in radians
create or replace function misc_rotateHeadingByAngle(heading double precision,angle double precision)
returns double precision
as $$
select misc_normalizeRadians($1-$2);
$$ LANGUAGE sql immutable;
Builds a triangle specifying origin,heading, inner angle and length of sides
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;
Builds a circle sector given origin, heading, iner angle and radius
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;
Then creating the view:
create view sectors as
select s1.*, buildSector(p1.geom,s1.azimuth,s1.beam,s1.range) as geom
from sector s1 left join points p1 on p1.id=s1.centerid