[postgis-users] certain distance to polygon's exterior ring

Kevin Neufeld kneufeld at refractions.net
Wed Oct 3 10:18:08 PDT 2007


temiz wrote:
> hello
>
> how can I find the some points that are in a polygon and they have 
> certain distance ( say 10 m) to polygon's exterior ring ?
>
>
> regards
>
Finding close interior rings is relatively easy.  To find all points on 
an interior ring (that may or may not be a vertex on the ring) that is 
within a certain distance to the exterior ring requires a couple 
additional steps.

http://postgis.refractions.net/support/wiki/index.php?ExamplesInsidePolygon2

My approach to identify the "close" interior rings would be:
1. Extract the exterior ring of your token polygon
2. Extract all the interior rings of your polygon
3. Find all interior rings that are within a certain distance from the 
exterior ring

SELECT int_rings.geom
FROM
   (SELECT ST_ExteriorRing(the_geom) AS geom
    FROM my_poly_table
    WHERE id = <your_token_poly_id>
    ) AS ex_ring,

   (SELECT ST_InteriorRingN(
        the_geom,
        generate_series(1, ST_NumInteriorRings(the_geom))) AS geom
    FROM my_poly_table
    WHERE id = <your_token_poly_id>
    ) AS int_rings
WHERE ST_DWithin(ex_ring.geom, int_rings.geom, 10);

Obviously replace "<your_token_poly_id>" with the id of your token polygon.
Note: If you have many polygons you need to query, then alternatively, 
you will want to put the two sub queries into separate temporary tables 
(with gist indexes).

To further find all the points on an interior ring that are within a 
certain distance of the exterior ring.
4. Add a buffered geometry of the exterior ring subquery (so that you 
only compute the buffer ONCE ... this is expensive to compute)
5. Replace the outer select query with the intersection of the buffered 
exterior ring and the interior ring that is "close"

SELECT ST_Intersection(ex_ring.buff_geom, int_rings.geom)
FROM
   (SELECT ST_ExteriorRing(the_geom) AS geom,
           ST_Buffer(ST_ExteriorRing(the_geom), 10) AS buff_geom
    FROM my_poly_table
    WHERE id = <your_token_poly_id>
    ) AS ex_ring,

   (SELECT ST_InteriorRingN(
        the_geom,
        generate_series(1, ST_NumInteriorRings(the_geom))) AS geom
    FROM my_poly_table
    WHERE id = <your_token_poly_id>
    ) AS int_rings
WHERE ST_DWithin(ex_ring.geom, int_rings.geom, 10);

This will return all the points on a line (your interior rings) that are 
within 10m of the exterior ring. 
Depending on your geometry, this will result in a (multi)point, a 
(multi)linestring, or a geometry collection of points and lines.

Hope this helps,
Kevin

-------------
Kevin Neufeld
Software Developer
Refractions Research Inc.
300-1207 Douglas St.
Victoria, B.C., V8W 2E7

Phone: (250) 383-3022
Email: kneufeld at refractions.net




More information about the postgis-users mailing list