6

I have a polygon layer, and would like to generate random points in each polygon. An initial searching in Google resulted this website which presents a function for this purpose:

http://trac.osgeo.org/postgis/wiki/UserWikiRandomPoint

The function I'm interested to use is called RandomPointsInPolygon()

When I use this function and execute my query, it doesn't give an error but also never finishes the process. I tried giving a WHERE clause and limiting my query, this time process executed without any error but no points were stored in the relevant field in my table.

Does anybody know what the problem is? and/or what could be an easy way to solve my problem? using this function or any other options that you may have know?

The code for function:

CREATE OR REPLACE FUNCTION RandomPointsInPolygon(geom geometry, num_points integer)
 RETURNS SETOF geometry AS
$BODY$DECLARE
 target_proportion numeric;
 n_ret integer := 0;
 loops integer := 0;
 x_min float8;
 y_min float8;
 x_max float8;
 y_max float8;
 srid integer;
 rpoint geometry;
BEGIN
 -- Get envelope and SRID of source polygon
 SELECT ST_XMin(geom), ST_YMin(geom), ST_XMax(geom), ST_YMax(geom), ST_SRID(geom)
 INTO x_min, y_min, x_max, y_max, srid;
 -- Get the area proportion of envelope size to determine if a
 -- result can be returned in a reasonable amount of time
 SELECT ST_Area(geom)/ST_Area(ST_Envelope(geom)) INTO target_proportion;
 RAISE DEBUG 'geom: SRID %, NumGeometries %, NPoints %, area proportion within envelope %',
 srid, ST_NumGeometries(geom), ST_NPoints(geom),
 round(100.0*target_proportion, 2) || '%';
 IF target_proportion < 0.0001 THEN
 RAISE EXCEPTION 'Target area proportion of geometry is too low (%)', 
 100.0*target_proportion || '%';
 END IF;
 RAISE DEBUG 'bounds: % % % %', x_min, y_min, x_max, y_max;
 WHILE n_ret < num_points LOOP
 loops := loops + 1;
 SELECT ST_SetSRID(ST_MakePoint(random()*(x_max - x_min) + x_min,
 random()*(y_max - y_min) + y_min),
 srid) INTO rpoint;
 IF ST_Contains(geom, rpoint) THEN
 n_ret := n_ret + 1;
 RETURN NEXT rpoint;
 END IF;
 END LOOP;
 RAISE DEBUG 'determined in % loops (% efficiency)', loops, round(100.0*num_points/loops, 2) || '%';
END$BODY$
 LANGUAGE plpgsql VOLATILE
 COST 100
 ROWS 1000;
ALTER FUNCTION RandomPointsInPolygon(geometry, integer) OWNER TO postgres;

My query:

INSERT INTO grid(point_geom) SELECT RandomPointsInPolygon(h.geom, 1) FROM grid AS h;

Here I have a point geometry column column named point_geom to store the result of query, and in the same table I have polygons stored in the geom field. I would like to generate points inside each polygon of this grid table. In the query above I tried to create 1 random point for each polgyon and store it in the relevant field.

asked Mar 17, 2014 at 16:19

3 Answers 3

9

To create 1 random point for each polgyon in a table I have used this table and code:

enter image description here

DO $$
DECLARE
 r RECORD;
BEGIN
 FOR r IN SELECT id_0 FROM "Grid" LOOP
-- RAISE NOTICE 'affected row id: %', r.id_0;
 UPDATE "Grid" SET "point_geom" = (SELECT RandomPointsInPolygon(geom, 1) FROM "Grid" WHERE "id_0" = r.id_0) WHERE "id_0" = r.id_0;
 END LOOP;
END$$;

Running all the code at once, I've obtained the following:

enter image description here

enter image description here

enter image description here

answered Mar 17, 2014 at 19:25
0
1

It's probably because you have MultiPolygons in your geometry, which are collections of polygons. The author followed up with a function RandomPointMulti that handled the known issue with MultiPolygons.

If you're not sure what geometry type you're working with (Points, Linestring, Polygon, MultiPoints, MultiLinestring, or MultiPolygon), I highly recommend you become familiar with the great Boundless Geo documentation on them.

answered Mar 17, 2014 at 20:52
1
  • No, I have simple polygons. Any other suggestion? Commented Mar 17, 2014 at 22:52
0

Have you set the SRID on the geometries? This code works for me (I have multipolygons, hence the use of ST_Dump):

SELECT RandomPointsInPolygon((ST_Dump(ST_SetSRID(geom, 4283))).geom, 50)

On my home PC it can do ~20 million points in under an hour based on ~350,000 not too complex polygons.

answered Mar 18, 2014 at 1:40

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.