Last active
January 7, 2022 20:08
-
-
Save geozelot/33b3f92f45039db8dea6bb2c9e2d8b46 to your computer and use it in GitHub Desktop.
PostgreSQL/PostGIS - Create a wedge of a buffer around a point, with optional inner radius
This file contains 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
/* | |
* @params | |
* pnt - center POINT geometry | |
* sdeg - wedge sector start value; in degrees | |
* edeg - wedge sector end value; in degrees | |
* irad - radius around @pnt for the inner extend of the wedge; in meter | |
* orad - radius around @pnt for the outer extend of the wedge; in meter | |
* qsegs - vertices per full quarter circle; at least two vertices will be created | |
* | |
* The function will calculate the angular difference in clockwise direction, from @sdeg to @edeg. | |
* @irad defaults to 0 to get a wedge including the center POINT geometry (full wedge) | |
*/ | |
CREATE OR REPLACE FUNCTION ST_PointBufferWedge( | |
pnt GEOMETRY(POINT), | |
sdeg FLOAT, | |
edeg FLOAT, | |
orad FLOAT, | |
irad FLOAT DEFAULT 0, | |
qsegs INT DEFAULT 8 | |
) RETURNS GEOMETRY(POLYGON) AS | |
$$ | |
DECLARE | |
srid INT; | |
tdelta FLOAT; | |
otvert INT; | |
otstep FLOAT; | |
itvert INT; | |
itstep FLOAT; | |
wedge GEOMETRY(POINT)[]; | |
BEGIN | |
srid := ST_SRID($1); | |
tdelta := CASE ($2 <= $3) WHEN TRUE THEN $3-$2 ELSE 360.0-$2+$3 END; | |
otvert := GREATEST($6 * (FLOOR(tdelta)/90), 2); | |
otstep := tdelta/otvert; | |
itvert := CASE irad > 0 WHEN TRUE THEN GREATEST((otvert * ($5/$4))::INT, $6/2) ELSE 1 END; | |
itstep := COALESCE(NULLIF(tdelta/itvert, tdelta), 0); | |
FOR n IN 0..itvert | |
LOOP | |
wedge := wedge || ST_Project($1::GEOGRAPHY, $5, RADIANS(MOD($3::NUMERIC-(n*itstep)::NUMERIC, 360.0::NUMERIC)))::GEOMETRY; | |
END LOOP | |
; | |
FOR n IN 0..otvert | |
LOOP | |
wedge := wedge || ST_Project($1::GEOGRAPHY, $4, RADIANS(MOD($2::NUMERIC+(n*otstep)::NUMERIC, 360.0::NUMERIC)))::GEOMETRY; | |
END LOOP | |
; | |
wedge := wedge || wedge[1]; | |
RETURN ST_MakePolygon(ST_SetSRID(ST_MakeLine(wedge), srid)); | |
END; | |
$$ | |
LANGUAGE 'plpgsql'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment