Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
create or replace function generate_polygon_rad(
p_min_radius in number,
p_variance_pct in number,
p_lon in number default 0,
p_lat in number default 0)
return sdo_geometry
is
c_upper_limit constant number := p_min_radius + p_min_radius*(p_variance_pct/100);
v_cur_radian number := 0;
v_x number;
v_y number;
/* array of point used to construct the polygon */
v_ordinate_array_points sdo_ordinate_array := sdo_ordinate_array();
begin
/*
Each itteration will add a point at a random distance from the center point
on the current radian.
asin(1)*4 = 2pi
*/
while v_cur_radian < asin(1)*4 loop
select t.x, t.y
into v_x, v_y
from table(sdo_util.getvertices(
sdo_util.point_at_bearing(
sdo_geometry(2001,
4326,
sdo_point_type(p_lon, p_lat, null), null, null),
/*
Since sdo_util.getvertices increments radian in a clockwise direction
and a valid polygon must be defined in a counter-clockwise direction
we'll change our v_cur_radian to a negative value.
*/
v_cur_radian * -1,
round(dbms_random.value(p_min_radius,c_upper_limit))
)
)
) t;
/* add x and y value of new point */
v_ordinate_array_points.extend(2);
v_ordinate_array_points(v_ordinate_array_points.count-1) := v_x;
v_ordinate_array_points(v_ordinate_array_points.count) := v_y;
/* increment the current radian by .1 to .5 radians */
v_cur_radian := v_cur_radian + round(dbms_random.value(.1,.5),2);
end loop;
/* add x and y value of first point as the last point of the polygon to close it */
v_ordinate_array_points.extend(2);
v_ordinate_array_points(v_ordinate_array_points.count-1) := v_ordinate_array_points(1);
v_ordinate_array_points(v_ordinate_array_points.count) := v_ordinate_array_points(2);
return sdo_geometry(2003, -- two-dimensional polygon
4326,
null,
sdo_elem_info_array(1,1003,1), -- simple polygon
v_ordinate_array_points
);
end;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.