ST_DWithin — Testar om två geometrier ligger inom ett givet avstånd
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);
Returnerar true om geometrierna ligger inom ett givet avstånd
För geometri: Avståndet anges i enheter som definieras av geometriernas spatiala referenssystem. För att denna funktion ska vara meningsfull måste källgeometrierna vara i samma koordinatsystem (ha samma SRID).
För geografi: enheterna är i meter och avståndsmätning sker som standard med use_spheroid = true. För snabbare utvärdering, använd use_spheroid = false för att mäta på sfären.
|
|
|
Använd ST_3DDWithin för 3D-geometrier. |
|
|
|
Detta funktionsanrop innehåller en jämförelse av begränsningsrutor som använder alla index som finns tillgängliga för geometrierna. |
Denna metod implementerar OGC:s implementeringsspecifikation för enkla funktioner för SQL 1.1.
Tillgänglighet: 1.5.0 stöd för geografi infördes
Förbättrad: 2.1.0 förbättrad hastighet för geografi. Se Göra geografi snabbare för mer information.
Förbättrad i 2.1.0: stöd för krökta geometrier infördes.
Före 1.3 användes ST_Expand ofta i kombination med && och ST_Distance för att testa avstånd och före 1.3.4 använde den här funktionen den logiken. Från och med 1.3.4 använder ST_DWithin en snabbare funktion för kortslutningsavstånd.
Det här fristående geometriexemplet håller de jämförda formerna synliga samtidigt som de booleska resultaten returneras.
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)
Hitta närmaste sjukhus till varje skola som ligger inom 3 000 enheter från skolan. Vi gör en sökning med ST_DWithin för att utnyttja index och begränsa söklistan som den icke-indexerbara ST_Distance måste bearbeta. Om enheterna i den rumsliga referensen är meter blir enheterna meter.
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);
Skolorna utan närliggande sjukhus. Hitta alla skolor som saknar ett sjukhus inom 3 000 enheter från skolan. Enheterna är den rumsliga referensens enheter (till exempel meter, fot eller grader).
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;
Hitta platser som ligger mer än 3 000 enheter från sitt närmaste sjukhus. Använd NOT EXISTS så att en plats returneras endast när inget närliggande sjukhus finns.
SELECT l.location_name
FROM locations l
WHERE NOT EXISTS (
SELECT 1
FROM hospitals h
WHERE ST_DWithin(l.geom, h.geom, 3000)
);
Hitta sändartorn som en mottagare med begränsad räckvidd kan ta emot. Data består av geometri i Spherical Mercator (SRID=3857) och räckvidderna är ungefärliga.
CREATE INDEX ON broadcasting_towers USING gist (geom); CREATE INDEX ON broadcasting_towers USING gist (ST_Expand(geom, sending_range));
Fråga efter torn som en mottagare med räckvidden 4 kilometer i Minsk Hackerspace kan ta emot. Observera att två villkor krävs eftersom den kortare LEAST(b.sending_range, 4000) inte använder ett index.
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);