[postgis-users] Placing a random point within a range of distances from existing point, ST_DWithin and ST_Intersects

Stephen V. Mather svm at clevelandmetroparks.com
Wed Oct 26 07:27:54 PDT 2011


Hi All,

                I'm trying to find the problem with my logic in the
following query.  I want to randomize a point, and neither place it too
close or too far from the initial point.  I'd like to further constrain the
placement of that point so that it stays within certain bounds.  Imagine, if
you will sensitive point data that might need a little fuzzing-1) I don't
want to fuzz it too much (outer circle), 2) I don't want it too close to the
original point (inner circle) 3) but I want it to also stay within certain
boundaries in order to retain some verisimilitude, e.g. must stay within
forest boundaries.

I've tested this in PostGIS 1.3.5 on a Windows Server 2003 machine (postgres
8.3), and in PostGIS 2.0 on Debian (with postgres 8.4).

In general, it works really well.  Occasionally, I get a point that seems to
meet my first to criteria but not my third

 

Here's a few hundred of the same point fuzzed:



Function:

 

CREATE OR REPLACE FUNCTION ST_Donut

                ( geom GEOMETRY,
-- GEOMETRY point to be processed

                dough DOUBLE PRECISION,
-- Outside ring

                nut DOUBLE PRECISION,
-- Inside ring

                itermax INTEGER,
-- Maximum number of iterations

                bite GEOMETRY)
--POLYGON that randomized point must intersect

 

                RETURNS GEOMETRY
-- Returns the randomized point

                AS $$

 

                DECLARE

                                xmin DOUBLE PRECISION;
-- xmin for envelope of donut

                                ymin DOUBLE PRECISION;
-- ymin for envelope of donut

                                delta DOUBLE PRECISION;
-- difference between xmax and xmin

                                pointx DOUBLE PRECISION;
-- output point x

                                pointy DOUBLE PRECISION;
-- output point y

                                returnpoint GEOMETRY;

                                i INTEGER := 0;
-- index integer for while loop

                                

                BEGIN

                                xmin = ST_X( geom ) - dough;    -- find min
x, min y for resulting envelope

                                ymin = ST_Y( geom ) - dough;     -- in which
to place initial points

                                delta = dough*2;
-- for calculating max extent for envelope

                WHILE i < itermax LOOP

                                i = i + 1;

                                pointx = xmin + delta * random();
-- generate random point value

                                pointy = ymin + delta * random();

                                returnpoint = ST_SetSRID( ST_MakePoint(
pointx, pointy ), ST_SRID( geom ) );

                EXIT WHEN

                                ST_DWithin( returnpoint, geom, dough )
-- test to see if inside outer ring

                                                AND NOT

                                ST_DWithin( returnpoint, geom, nut )
-- test to see if outside inner ring

                                                AND

                                ST_Intersects( returnpoint, bite )
--test to see if inside inclusion polygon

                                ;

                END LOOP;

 

                IF i > itermax THEN

                                RAISE NOTICE 'Reached maximum iterations
without placing point inside donut.';

                END IF;

 

                RETURN returnpoint;     -- return the GEOMETRY

                END;

 

$$ LANGUAGE plpgsql;

 

 

To run:

 

CREATE TABLE donut_bite_test1 AS

SELECT ST_Donut(ST_MakePoint(0, 0), 40, 60, 1000,
ST_Buffer(ST_MakePoint(-60, -60), 60))

UNION ALL

SELECT ST_Donut(ST_MakePoint(0, 0), 60, 40, 1000,
ST_Buffer(ST_MakePoint(-60, -60), 60))

UNION ALL

Etc. etc.

SELECT ST_Donut(ST_MakePoint(0, 0), 60, 40, 1000,
ST_Buffer(ST_MakePoint(-60, -60), 60))

;

 

Best,

Steve

 

http://www.clemetparks.com/images/esig/cmp-ms-90x122.pngStephen Mather
Geographic Information Systems (GIS) Manager
(216) 635-3243

svm at clevelandmetroparks.com
 <http://www.clemetparks.com/> clevelandmetroparks.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20111026/dcaacaaa/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 22376 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20111026/dcaacaaa/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 3772 bytes
Desc: not available
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20111026/dcaacaaa/attachment-0001.png>


More information about the postgis-users mailing list