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は、より速いショートサーキットを使った距離関数を使います。
このジオメトリーの自己完結型の例では、真偽値を返すと同時に比較対象の形状を表示できるようにしています。
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)
学校ごとに最も近い病院を探索します。学校から3000単位以内とします。ST_DWithinでインデックスを効かせた探索対象制限を行います。インデックスを使えないST_Distanceではこのような処理が必要です。空間参照系の単位がメートルの場合には、この例での距離の単位はメートルになります。
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);
近くに病院が無い学校。病院が 3000単位以内に無い学校を全て見つけます。単位は空間参照系の単位に従います (メートル、フィート、度など)。
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;
最も近い病院との距離が 3000単位を超える位置を見つける。NOT EXISTS を使って、病院が近くにない位置を返しています。
SELECT l.location_name
FROM locations l
WHERE NOT EXISTS (
SELECT 1
FROM hospitals h
WHERE ST_DWithin(l.geom, h.geom, 3000)
);
範囲が制限されている受信機で受信可能な放送塔の探索。データは球面メルカトル (SRID=3857) のジオメトリーで、指定範囲は近似的なものです。
CREATE INDEX ON broadcasting_towers USING gist (geom); CREATE INDEX ON broadcasting_towers USING gist (ST_Expand(geom, sending_range));
ミンスクのハケルスペイスで距離制限 4kmの受信機が受信できる放送塔のクエリー。ご注意: 短い方の LEAST(b.sending_range, 4000) ではインデックスを使わないので二つの条件が必要です。
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);