2014-01-15 5 views
1

PostGIS의 GEOMETRYCOLLECTION을 처리하는 동안 GEOMETRYCOLLECTION을 단순 GEOMETRY로 변환하는 것을 처리하는 것으로 보이는 here이 있지만 ST_Intersect 내부 함수에서만 작동합니다.함수 이름을 인수로 전달합니다.

게으르다. 나는 게으르다. 나는 함수가 인자로 실행되도록함으로써 더 강력하게 만드는 것이 좋을 것이라고 생각했지만, 그렇게하지 않는다.

CREATE OR REPLACE FUNCTION ST_GeoCollConv_(geofunction, geometry, geometry) RETURNS boolean AS $$ 
     DECLARE 
       is1collection boolean; 
       is2collection boolean; 
     BEGIN 

       is1collection := GeometryType($1) = 'GEOMETRYCOLLECTION'; 
       is2collection := GeometryType($2) = 'GEOMETRYCOLLECTION'; 

       IF NOT is1collection AND NOT is2collection THEN 
         return PERFORM geofunction($1, $2); 
       END IF; 


       IF NOT is1collection THEN 
         FOR i IN 1..ST_NumGeometries($2) LOOP 
           IF PERFORM geofunction($1, ST_GeometryN($2, i)) THEN 
             RETURN true; 
           END IF; 
         END LOOP; 
       ELSIF NOT is2collection THEN 
         FOR i IN 1..ST_NumGeometries($1) LOOP 
           IF PERFORM geofunction(ST_GeometryN($1, i), $2) THEN 
             RETURN true; 
           END IF; 
         END LOOP; 
       ELSE 
         FOR i IN 1..ST_NumGeometries($1) LOOP 
           IF ST_GeoCollConv_(geofunction, $1, $2) THEN 
             RETURN true; 
           END IF; 
         END LOOP; 
       END IF; 

       RETURN false; 

     END; 
$$ LANGUAGE 'plpgsql'; 

어떻게하면됩니까?

답변

1

함수는 포스트그레스에서 제일 시민이 아니며 (나는 RDBMS를 생각할 수 없다.) 인수로 전달할 수 없다. 그 다음으로 가장 가까운 것은 가능한 모든 함수 (st_overlaps, st_intersects, st_within 등)를 열거하고, 말하는 함수를 나타내는 플래그를 전달하고, if 문에이를 통합하는 것입니다 (예 : "if func = 'overlaps'이고 st_overlaps (geom1, geom2) else if func = 'within'및 st_within (geom1, geom2) ...".

지오메트리 컬렉션은 처리하기가 다소 어려울 수 있습니다. 당신은 그들을 사용하도록 강요 받았습니까? 대신 다각형을 사용할 수 있습니까?

또한 함수 자체가 약간 과한 것에 유의하십시오. st_dump를 사용하여 모든 지오메트리를 열거 할 수 있습니다 (단순한 지오메트리가 있더라도 작동 함). 그런 다음 결과를 조인하십시오. 예를 들면 :

create or replace function st_intersects_gc(geometry, geometry) 
returns boolean 
as 
$$ 
    select exists (
      select 1 
      from st_dump($1) a 
        join st_dump($2) b 
         on st_intersects(a.geom, b.geom) 
      limit 1 
      ) 
    ; 
$$ 
language sql 
immutable 
; 

샘플 사용 (이이뿐만 아니라 컬렉션 제대로 작동하는지 설명하는 예를해야하지만 손에 일이없는) : 신발에

-- returns false 
select st_intersects_gc('POINT(0 0)'::geometry, 'LINESTRING (2 0, 0 2)'::geometry) 

-- returns true 
select st_intersects_gc('POINT(0 0)'::geometry, 'LINESTRING (0 0, 0 2)'::geometry) 

, 나는 당신이 사용하려고 계획하고있는 각각의 기능에 대해 그것들 중 하나를 쓸 것이다.

+0

감사합니다 yieldsfalsehood, 특히 내가 ST_Overlaps 함수를 사용하는 경우, 지금까지 작성한 모든 실험보다 솔루션으로 더 많은 성공을 거두었습니다. 나는 다중 다각형을 사용하는 방법을 아직 모르고이 방향으로 조사 할 것이다. (+1에 대한 명성이 충분하지 않다.) – annoyed

+0

다행스럽게도 나는 도울 수 있었고, 행운을 빈다. – yieldsfalsehood

관련 문제