Guest User

Untitled

a guest
May 21st, 2018
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.67 KB | None | 0 0
  1. CREATE OR REPLACE FUNCTION RandomPointsInPolygon(geom geometry, num_points integer)
  2. RETURNS SETOF geometry AS
  3. $BODY$DECLARE
  4. target_proportion numeric;
  5. n_ret integer := 0;
  6. loops integer := 0;
  7. x_min float8;
  8. y_min float8;
  9. x_max float8;
  10. y_max float8;
  11. srid integer;
  12. rpoint geometry;
  13. BEGIN
  14. -- Get envelope and SRID of source polygon
  15. SELECT ST_XMin(geom), ST_YMin(geom), ST_XMax(geom), ST_YMax(geom), ST_SRID(geom)
  16. INTO x_min, y_min, x_max, y_max, srid;
  17. -- Get the area proportion of envelope size to determine if a
  18. -- result can be returned in a reasonable amount of time
  19. SELECT ST_Area(geom)/ST_Area(ST_Envelope(geom)) INTO target_proportion;
  20. RAISE DEBUG 'geom: SRID %, NumGeometries %, NPoints %, area proportion within envelope %',
  21. srid, ST_NumGeometries(geom), ST_NPoints(geom),
  22. round(100.0*target_proportion, 2) || '%';
  23. IF target_proportion < 0.0001 THEN
  24. RAISE EXCEPTION 'Target area proportion of geometry is too low (%)',
  25. 100.0*target_proportion || '%';
  26. END IF;
  27. RAISE DEBUG 'bounds: % % % %', x_min, y_min, x_max, y_max;
  28.  
  29. WHILE n_ret < num_points LOOP
  30. loops := loops + 1;
  31. SELECT ST_SetSRID(ST_MakePoint(random()*(x_max - x_min) + x_min,
  32. random()*(y_max - y_min) + y_min),
  33. srid) INTO rpoint;
  34. IF ST_Contains(geom, rpoint) THEN
  35. n_ret := n_ret + 1;
  36. RETURN NEXT rpoint;
  37. END IF;
  38. END LOOP;
  39. RAISE DEBUG 'determined in % loops (% efficiency)', loops, round(100.0*num_points/loops, 2) || '%';
  40. END$BODY$
  41. LANGUAGE plpgsql VOLATILE
  42. COST 100
  43. ROWS 1000;
  44. ALTER FUNCTION RandomPointsInPolygon(geometry, integer) OWNER TO postgres;
Add Comment
Please, Sign In to add comment