名前

ST_DWithin — 二つのジオメトリが与えらえれた距離内にあるかどうかをテストします。

概要

boolean ST_DWithin(geometry g1, geometry g2, double precision distance_of_srid);

boolean ST_DWithin(geography gg1, geography gg2, double precision distance_meters, boolean use_spheroid = true);

説明

ジオメトリが与えられた距離内にある場合にはTRUEを返します。

geometry: 距離の単位は空間参照系で定義される単位です。この関数が意味のあるものにするためには、与えられるジオメトリは両方とも同じ座標系である (同じSRIDを持つ)必要があります。

geography: 単位はメートルで、距離の測定の既定値はuse_spheroid = trueです。より高速な評価のために、use_spheroid = falseとして球面で測定します。

[注記]

3次元ジオメトリではST_3DDWithinを使います。

[注記]

この関数の呼び出しによって、ジオメトリで使用可能なインデックスを使用したバウンディングボックスの比較が自動的に行われます。

このメソッドはOGC Simple Features Implementation Specification for SQL 1.1の実装です。

Availability: 1.5.0 ジオグラフィが導入されました。

Enhanced: 2.1.0 ジオグラフィ版の速度が改善しました。詳細についてはMaking Geography fasterをご覧下さい。

Enhanced: 2.1.0 曲線ジオメトリ対応が導入されました。

1.3以前のST_Expandは、 距離をテストするために、&&と、ST_Distanceとを一般的に併用していました。1.3.4より前では、この関数はそのロジックを使っていました。1.3.4からST_DWithinは、より速いショートサーキットを使った距離関数を使います。

This self-contained geometry example keeps the compared shapes visible while also returning the boolean results.

Code
WITH sample AS (
  SELECT ST_Buffer('POINT(100 90)'::geometry, 50, 'quad_segs=2') AS coverage,
         ST_Point(120, 120) AS inside_pt,
         ST_Point(170, 90) AS outside_pt
)
SELECT ST_DWithin(coverage, inside_pt, 0) AS inside_now,
       ST_DWithin(coverage, outside_pt, 10) AS outside_within_10,
       coverage AS coverage_geom,
       inside_pt AS inside_geom,
       outside_pt AS outside_geom
FROM sample;
出力:
-[ RECORD 1 ]-----
inside_now        | t
outside_within_10 | f
coverage_geom     | POLYGON((150 90,135 55,100 40,65 55,50 90,65 125,100 140,135 125,150 90))
inside_geom       | POINT(120 120)
outside_geom      | POINT(170 90)
Figure
Geometry figure for visual-st-dwithin-01

学校ごとに最も近い病院を探索します。学校から3000単位以内とします。ST_DWithinでインデックスを効かせた探索対象制限を行います。インデックスを使えないST_Distanceではこのような処理が必要です。空間参照系の単位がメートルの場合には、この例での距離の単位はメートルになります。

Code
SELECT DISTINCT ON (s.gid) s.gid, s.school_name, s.geom, h.hospital_name
  FROM schools s
    LEFT JOIN hospitals h ON ST_DWithin(s.geom, h.geom, 3000)
  ORDER BY s.gid, ST_Distance(s.geom, h.geom);

The schools with no close hospitals. Find all schools with no hospital within 3000 units away from the school. Units are in units of spatial reference (for example meters, feet, or degrees).

Code
SELECT s.gid, s.school_name
  FROM schools s
    LEFT JOIN hospitals h ON ST_DWithin(s.geom, h.geom, 3000)
  WHERE h.gid IS NULL;

Find locations more than 3000 units away from their nearest hospital. Use NOT EXISTS so that a location is returned only when no nearby hospital exists.

Code
SELECT l.location_name
  FROM locations l
  WHERE NOT EXISTS (
    SELECT 1
    FROM hospitals h
    WHERE ST_DWithin(l.geom, h.geom, 3000)
  );

Find broadcasting towers that a receiver with limited range can receive. Data is geometry in Spherical Mercator (SRID=3857), ranges are approximate.

Code
CREATE INDEX ON broadcasting_towers USING gist (geom);
CREATE INDEX ON broadcasting_towers USING gist (ST_Expand(geom, sending_range));

Query towers that a 4-kilometer receiver in Minsk Hackerspace can get. Note: two conditions are required because the shorter LEAST(b.sending_range, 4000) will not use an index.

Code
SELECT b.tower_id, b.geom
  FROM broadcasting_towers b
  WHERE ST_DWithin(b.geom, 'SRID=3857;POINT(3072163.4 7159374.1)', 4000)
    AND ST_DWithin(b.geom, 'SRID=3857;POINT(3072163.4 7159374.1)', b.sending_range);

関連情報

ST_Distance, ST_3DDWithin