Hi All,

                Running 1.3.5 still :).  Found some unexpected (to me), but
pleasant behavior with ST_DWithin.  What we're doing is creating a function
that we can use to randomize a point within a minimum and maximum bounds.
Our original approach was to generate the geometry of the difference of two
buffers (a donut, if you will) and then place a random point within that.
Better to test with ST_DWithin directly then buffer, so we rewrote:

 

BEGIN

 

                xmin = ST_XMin(geom) - dough;

                deltax = ST_XMax(geom) - xmin + dough;

                ymin = ST_YMin(geom) - dough;

                deltay = ST_YMax(geom) - ymin + dough;

 

                WHILE i < itermax LOOP

                                i = i + 1;

                                pointx = xmin + deltax * random();

                                pointy = ymin + deltay * random();

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

                EXIT WHEN

                                                ST_DWithin( returnpoint,
geom, dough )

                                                                AND NOT

                                                ST_DWithin( returnpoint,
geom, nut );

                END LOOP;

 

                IF i > itermax THEN

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

                END IF;

 

                RETURN returnpoint;

END;

 

The puzzling part is that even if the parameters are passed out of order,
i.e. the inner ring is passed for the outer ring and vice versa, we get a
fine result.  It's a nice unexpected behavior, but unexpected none-the-less.
Anyone have any thoughts on why this works?  Full function below:

 

 

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

s...@clevelandmetroparks.com
 <http://www.clemetparks.com/> clevelandmetroparks.com

 

 

 

CREATE OR REPLACE FUNCTION ST_Donut

                ( geom Geometry,

                dough DOUBLE PRECISION,

                nut DOUBLE PRECISION,

                itermax INTEGER)

                RETURNS Geometry

                AS $$

                

DECLARE

                xmin DOUBLE PRECISION;

                ymin DOUBLE PRECISION;

 

                deltax DOUBLE PRECISION;

                deltay DOUBLE PRECISION;

 

                pointx DOUBLE PRECISION;

                pointy DOUBLE PRECISION;

 

                returnpoint Geometry;

 

                i INTEGER := 0;

 

                nut1 DOUBLE PRECISION;

                dough1 DOUBLE PRECISION;

 

BEGIN

 

                xmin = ST_XMin(geom) - dough;

                deltax = ST_XMax(geom) - xmin + dough;

                ymin = ST_YMin(geom) - dough;

                deltay = ST_YMax(geom) - ymin + dough;

 

                WHILE i < itermax LOOP

                                i = i + 1;

                                pointx = xmin + deltax * random();

                                pointy = ymin + deltay * random();

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

                EXIT WHEN

                                                ST_DWithin( returnpoint,
geom, dough )

                                                                AND NOT

                                                ST_DWithin( returnpoint,
geom, nut );

                END LOOP;

 

                IF i > itermax THEN

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

                END IF;

 

                RETURN returnpoint;

END;

 

$$ LANGUAGE plpgsql;

<<image001.png>>

_______________________________________________
postgis-users mailing list
postgis-users@postgis.refractions.net
http://postgis.refractions.net/mailman/listinfo/postgis-users

Reply via email to