Namn

ST_DWithin — Testar om två geometrier ligger inom ett givet avstånd

Synopsis

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);

Beskrivning

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.

[Notera]

Använd ST_3DDWithin för 3D-geometrier.

[Notera]

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.

Exempel

Det här fristående geometriexemplet håller de jämförda formerna synliga samtidigt som de booleska resultaten returneras.

Kod
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;
Utdata
-[ 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)
Figur
Geometry figure for visual-st-dwithin-01

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.

Kod
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).

Kod
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.

Kod
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.

Kod
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.

Kod
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);