PostGIS에서 지오메트리를 청소 하시겠습니까?


12

매우 큰 다각형 레이어에서 처리하려고합니다. 그러나 다음과 같은 다양한 기하학 오류가 발생합니다.

NOTICE:  Ring Self-intersection at or near point 470396.52017068537 141300.52235257279
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 504154.61769969884 140782.04115761846
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 505255.50242871145 140803.34860398644
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 510312.46970004693 141215.29256710084
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 510312.46970004693 141215.29256710084
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 511839.50335641927 141115.85781738357
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 515064.03024010791 140895.68087158105
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 519233.18724611058 140881.47590733573
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 521072.73011588014 141044.83299615697
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 523331.31943088671 141144.26774587421
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 523331.31943088671 141144.26774587424
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 523395.24176999065 140725.22130063715
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1
NOTICE:  Ring Self-intersection at or near point 524531.63890961662 140810.45108610913
CONTEXT:  PL/pgSQL function st_intersection(geometry,raster,integer) line 10 at RETURN QUERY
SQL function "st_intersection" statement 1

나는 여기에 제안 된 기능을 시도했다 : https://trac.osgeo.org/postgis/wiki/UsersWikiCleanPolygons

지오메트리를 청소하기 위해 내가 사용한 코드는 다음과 같습니다.

UPDATE public.mytable
SET geom=cleangeometry(geom);

결과 :

ERROR:  GEOSisSimple: IllegalArgumentException: This method does not support GeometryCollection arguments

그리고 또한

UPDATE public.valid_mytable
SET geom=ST_MakeValid(geom);

이것은 작동하지만 형상 열을 형상으로 처음 변경하는 경우에만 작동합니다

ALTER TABLE public.mytable  ALTER COLUMN geom SET DATA TYPE geometry;

그러면 다른 기능과 더 이상 작동하지 않는 테이블이 생깁니다!

ERROR:  Relate Operation called with a LWGEOMCOLLECTION type.  This is unsupported.

열을 기하학으로 다시 변경하려고했습니다 (MultiPolygon)

ALTER TABLE public.my_table ALTER COLUMN geom SET DATA TYPE geometry (멀티 폴리곤);

그러나 이것은 실패

ERROR:  Geometry type (GeometryCollection) does not match column type (MultiPolygon)

PostGIS in Action (Second Ed) http://www.manning.com/obe/를 통해 시도했지만 유효하지 않은 형상을 찾는 기능 만 찾을 수 있지만 데이터 세트가 너무 커서 수동으로 해결할 수는 없습니다. 자동으로 고칠 무언가가 필요합니다.


ST_MakeValid ()를 시도하고 실행할 때 문제가있는 다각형을 격리 할 수있었습니다. 결과가 나타납니다.

ERROR:  Geometry type (GeometryCollection) does not match column type      (MultiPolygon)
 ********** Error **********

 ERROR: Geometry type (GeometryCollection) does not match column type      (MultiPolygon)
SQL state: 22023

형상 열에서 유형 검사를 수행 한 결과 유형이 "MULTIPOLYGON"


ST_MakeValid는 최대한 수정합니다.
user30184

고마워, 나는 실제로 내 질문에 ST_Make_Valid라는 말을 잊어 버린 내 질문에 실수를했다. 나는 ST_MakeValid 사용했지만 나는 일에 얻을 수있는 형상 데이터 형식으로 내 기하 구조 열을 변경해야하고, 나는 기하학 (다중)로 다시 그것을 얻을 어차피 그렇게되면
마트

2
해킹 ST_Buffer (geom, 0)을 사용하면 많은 유효하지 않은 형상을 처리 할 수 ​​있습니다. ST_MakeValid를 사용할 수도 있습니다. 마지막으로 새 테이블을 선택하고 where 절에 ST_IsValid (geom)을 넣을 수 있습니다.
John Powell

고마워, 나는 이미 버퍼 해킹을 시도했지만 작동하지 않아 기하학 (MultiPolygon) 대신 기하학 입력을 원했다. 유효한 다각형 만 선택하고 필터링 된 수를 확인합니다.
Mart

1
확인. 이것은 st_makevalid 생성 점과 LineStrings와 GeometryCollection을 생성하는 다각형과 함께 제공됩니다. 몇 시간 안에 쓸 수있는 수정 사항이 있습니다. 나는 서핑하러 가려고한다 :-)
John Powell

답변:


15

ST_MakeValid 에서 다각형 또는 다중 다각형 만 원하는 경우 ST_Dump 를 사용하여 구성 도형을 추출한 다음 도형 유형을 테스트 할 수 있습니다 . ST_MakeValid는 때때로 GeometryCollection이 시작되는 Points 또는 LineString을 생성합니다. 다음과 같은 것을 시도하십시오 :

SELECT 
  g.geom, 
  row_number() over() AS gid,
FROM 
  (SELECT 
     (ST_DUMP(ST_MakeValid (geom))).geom FROM your_table
  ) AS g
WHERE ST_GeometryType(g.geom) = 'ST_MultiPolygon' 
   OR ST_GeometryType(g.geom) = 'ST_Polygon';

결과와 쿼리 계획은 동일하지만 OR 조건 대신 IN 절을 사용할 수 있습니다. Multipolygons 만 원하는 경우 ST_Multi 함수 에서 ST_Dump 를 랩핑 할 수 있습니다 .

row_number () over ()는 ST_Dump에서 반환 된 각 지오메트리에 대해 하나에서 시작하여 고유 한 ID를 반환합니다. ST_Dump가 리턴 한 경로 요소를 동일한 결과로 사용할 수도 있습니다.

ST_MakeValid가 일반적으로 (또는 항상) 일대일 매핑을 생성하여 출력 할 때와 같이 직접 업데이트가 작동하지 않을 수 있으므로 이것을 CREATE TABLE clean_geoms AS SELECT .... type 문과 결합하는 것이 좋습니다.

이것은 현재 수단이 없기 때문에 테스트되지 않았으므로 괄호가 잘못 배치되었을 수 있지만 일반적인 원칙은 건전합니다. 도움이 되었기를 바랍니다.


19

ST_CollectionExtract 를 사용하여 GeometryCollection에서 [Multi] Polygons를 추출 할 수 있습니다 . ST_Multi를 사용하여 MuliPolygons로 설정하십시오.

UPDATE public.valid_lcmsouthshapefile
  SET geom=ST_Multi(ST_CollectionExtract(ST_MakeValid(geom), 3))
  WHERE NOT ST_IsValid(geom);

완료 후 CHECK 제약 조건을 사용하여 유효하게 유지하십시오. 자세한 내용은 여기를 참조 하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.