PostGIS와 교차하지 않는 기능 선택


41

이것은 나에게 간단한 질문처럼 보입니다 (아마도 가능합니다).하지만 나는 대답을주는 예를 찾을 수없는 것 같습니다. PostGIS를 사용하여 다각형 외부 에있는 점을 선택하려고 합니다. 궁극적으로 이것은 내가 볼 수있는 한 ST_Intersects의 반대입니다.

예 : Taxlot 레이어와 주소 포인트 레이어가 있습니다. ST_Intersects를 사용해야한다고 가정하지만 역방향 선택을 수행하려면 어떻게해야합니까? 아래 코드 앞에 NOT 문을 추가한다고 생각 했지만 작동하지 않습니다.

CREATE table t_intersect AS
SELECT 
  hp.gid, 
  hp.st_address, 
  hp.city, 
  hp.st_num,
  hp.the_geom
FROM 
  public.parcel as par,
  public.housepoints as hp
WHERE 
  ST_Intersects(hp.the_geom,par.the_geom);

나는 같은 사고 과정을 가졌다. NOT은 다른 곳과 마찬가지로 트릭을 수행 할 것이라고 생각했다.
Luffydude

답변:


41

"교차하지 않음"으로 작동하지 않는 이유는 형상을 쌍으로 만 비교하기 때문입니다. 분리와 같은 문제가있을 것입니다. 모든 하우스 포인트는 하나의 소포와 교차하더라도 일부 소포를 분리합니다.

underdark의 제안에는 그 문제가 없습니다. 인덱스를보다 효과적으로 사용하는 또 다른 방법이 있습니다.

CREATE TABLE t_intersect AS
SELECT 
  hp.gid, 
  hp.st_address, 
  hp.city, 
  hp.st_num,
  hp.the_geom
FROM 
  public.housepoints AS hp LEFT JOIN
  public.parcel AS par ON
  ST_Intersects(hp.the_geom,par.the_geom)
WHERE par.gid IS NULL;

아이디어는 그것들을 st_intersects와 결합하고 소포 ID가 존재하지 않는 행을 얻는 것입니다.

여기에 필요한 인덱스는 공간 인덱스 및 소포의 gid 인덱스입니다 (소포 테이블의 id가 gid라고 가정).


2
대단히 감사합니다! ST_Disjoint가 올바른 결과를 생성하지 않는 것이 Nicklas의 정확성입니다. ST_Disjoint는 모든 기능을 반환합니다. 지적한대로 각 포인트가 테이블의 일부 소포 다각형 과 분리되어 있지만이 코드 스 니펫은 원하는 결과를 얻었 기 때문입니다.
RyanDalton

이 쿼리는이 gis.stackexchange.com/a/136177/6052 와 동일하게 계획 되므로 순전히 선호하는 스타일의 문제입니다. =) 쇼핑에 대한 답변.
Evan Carroll

14

ST_Disjoint를 찾고있을 수 있습니다.

ST_Disjoint — 도형이 공간적으로 교차하지 않는 경우-공간이 교차하지 않는 경우 TRUE를 반환합니다.


2
ST_Disjoint는이를 수행하지만 공간 인덱스는 사용하지 않습니다. 당신은 loooooong 시간을 기다릴거야
nickves

9

특수 기능이없는 경우 :

CREATE table t_intersect AS
SELECT 
  hp.gid, 
  hp.st_address, 
  hp.city, 
  hp.st_num,
  hp.the_geom
FROM
  public.housepoints as hp
WHERE
  hp.gid NOT IN 
  (
    SELECT 
      h.gid
    FROM 
      public.parcel as p,
      public.housepoints as h
    WHERE 
      ST_Intersects(h.the_geom,p.the_geom)
  ) AS foo

5

여기에 우리가 사용 NOT EXISTS하고 CREATE TABLE AS SELECT(CTAS)

CREATE table t_intersect
AS
  SELECT 
    hp.gid,
    hp.st_address,
    hp.city, hp.st_num,
    hp.the_geom
  FROM public.housepoints AS hp
  WHERE NOT EXISTS (
    SELECT 1
    FROM public.parcel AS par 
    WHERE ST_Intersects(hp.the_geom,par.the_geom)
  );

3

ST_Disjoint는 어떻습니까? — 도형이 공간적으로 교차하지 않는 경우-공간을 공유하지 않으면 TRUE를 반환합니다.



1

어떤 경우에는 LATERAL JOIN을 사용하는 것이 매우 유용합니다. 매우 빠를 수 있습니다.

SELECT * FROM houses h
LEFT JOIN LATERAL (
   SELECT True t FROM parcels p
   WHERE ST_Intersects(p.geom, h.geom)
   LIMIT 1
) p ON True
WHERE p.t IS NULL;

1

ST_Intersects 전에 NOT을 사용하여 트릭을 수행하십시오.

이것은 이웃 # 62에없는 모든 주소를 가져옵니다.

select 
a.*
from denver.neighborhoods as n
join denver.addresses as a on not ST_Intersects(n.geom, a.geom)
where n.nbhd_id = '62'

기하 열의 순서-다각형을 먼저, 점을 두 번째로-일반적인 ST_Intersect 사용과 반대입니다.

빠르고 간단합니다! 이 작업을 잠시 동안 올바르게 수행하는 방법에 대해 궁금했습니다!


"NOT ST_Within"에서도 일했습니다. NOT ST_Within과 외부 조인을 사용하여 오른쪽에서 Null을 확인하는 경우 쿼리가 ~ 30.0 초 안에 완료되었으므로 성능에 영향을 미치지 않는 것 같습니다. 감사!
Nate Wanner

@NateWanner 님이 좋아합니다! 나는 그것이 얼마나 쉽고 빠르다는 것을 믿을 수 없다! !!
DPSSpatial

데카르트 제품을 얻을 수 있기 때문에 이것은 실제로 아주 나쁜 생각입니다
Evan Carroll

@EvanCarroll 그게 무슨 뜻입니까?
DPSSpatial

그것은 단지 1 denver.address를 얻는 것이 아니라면, 일치하지 않는 모든 denver.neighborhood에 대해 하나를 얻는다는 것을 의미합니다.
Evan Carroll

-1

이것은 가장 빠른 해결책이 아닐 수도 있습니다 ... 그러나 일반적으로 다른 테이블의 모든 기능을 결합하여 속임수를 사용합니다.

Create table blah as
select
  d.*
from
  data_i_want d,
  (select st_union(geom) geom from not_in_here) n
where
  st_disjoint(d.geom,n.geom);

경우 생성 니스와는 이따위 not_in_here의 표가 복잡하지 않습니다.


결코 빠르지 않습니다. not_in_here 가 복잡한 경우처럼 간단하지 않습니다 . ;)
Evan Carroll
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.