Advanced: 01 Build sector coverage.sql

File 01 Build sector coverage.sql, 1.7 KB (added by 231139, 10 days ago)
Line 
1CREATE OR REPLACE FUNCTION public.build_sector_coverage(
2 p_center geometry(Point, 4326),
3 p_azimuth double precision,
4 p_beamwidth double precision,
5 p_radius_m double precision,
6 p_arc_segments integer DEFAULT 16
7)
8RETURNS geometry(Polygon, 4326)
9LANGUAGE plpgsql
10IMMUTABLE
11STRICT
12AS $$
13DECLARE
14 ring_points geometry[] := ARRAY[p_center];
15 angle_degrees double precision;
16 i integer;
17BEGIN
18 IF p_azimuth < 0 OR p_azimuth >= 360 THEN
19 RAISE EXCEPTION 'Azimuth must be between 0 and 359 degrees';
20 END IF;
21
22 IF p_beamwidth <= 0 OR p_beamwidth > 360 THEN
23 RAISE EXCEPTION 'Beamwidth must be between 1 and 360 degrees';
24 END IF;
25
26 IF p_radius_m <= 0 THEN
27 RAISE EXCEPTION 'Coverage radius must be positive';
28 END IF;
29
30 IF p_arc_segments < 4 OR p_arc_segments > 72 THEN
31 RAISE EXCEPTION 'Arc segments must be between 4 and 72';
32 END IF;
33
34 IF p_beamwidth = 360 THEN
35 RETURN ST_Buffer(p_center::geography, p_radius_m)::geometry;
36 END IF;
37
38 FOR i IN 0..p_arc_segments LOOP
39 angle_degrees := p_azimuth - (p_beamwidth / 2.0)
40 + (p_beamwidth * i / p_arc_segments);
41 ring_points := array_append(
42 ring_points,
43 ST_Project(
44 p_center::geography,
45 p_radius_m,
46 radians(angle_degrees)
47 )::geometry
48 );
49 END LOOP;
50
51 ring_points := array_append(ring_points, p_center);
52 RETURN ST_ForcePolygonCCW(ST_MakePolygon(ST_MakeLine(ring_points)));
53END;
54$$;
55
56COMMENT ON FUNCTION public.build_sector_coverage IS
57 'Builds a directional coverage wedge from a site point and sector settings.';