Làm sạch hình học trong PostGIS?


12

Tôi đang cố gắng thực hiện một số xử lý trên một số lớp đa giác rất lớn. Tuy nhiên, tôi đang gặp phải các lỗi hình học khác nhau như:

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

Tôi đã thử chức năng được đề xuất ở đây: https://trac.osgeo.org/postgis/wiki/UsersWikiCleanPolygons

để làm sạch hình học, mã tôi đã sử dụng là:

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

Với kết quả:

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

và cũng

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

Cái này hoạt động, nhưng chỉ khi lần đầu tiên tôi thay đổi cột hình học của mình thành hình học

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

Sau đó để lại cho tôi một bảng không còn hoạt động với các chức năng khác của tôi!

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

Tôi đã thử thay đổi các cột trở lại hình học (MultiPolygon)

ALTER TABLE public.my_table ALTER COLUMN geom SET DATA TYPE hình học (MultiPolygon);

Nhưng điều này thất bại

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

Tôi đã thử trải qua PostGIS in Action (Ed lần thứ hai) http://www.manning.com/obe/ nhưng tôi chỉ có thể tìm thấy các chức năng tìm hình học không hợp lệ, nhưng tập dữ liệu của tôi quá lớn để sửa lỗi này, tôi thực sự cần một cái gì đó sẽ sửa chúng tự động.


Tôi đã có thể cô lập các đa giác vấn đề, khi tôi thử và chạy ST_MakeValid () tôi nhận được kết quả:

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

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

Tôi đã thực hiện kiểm tra loại trên cột hình học của mình và thông báo loại đó là "MULTIPOLYGON"


ST_MakeValid sửa càng nhiều càng tốt.
dùng49584

Tôi thấy, cảm ơn, tôi thực sự đã mắc một lỗi trong câu hỏi của mình khi tôi quên đề cập rằng đó là ST_Make_Valid gây ra sự cố với các cột của tôi. Tôi đã sử dụng ST_MakeValid nhưng tôi phải thay đổi cột geom của mình thành kiểu dữ liệu hình học để làm cho nó hoạt động và một khi tôi làm điều đó, tôi không thể đưa nó trở lại hình học (MultiPolygon)
Mart

2
Bạn có thể sử dụng hack ST_Buffer (geom, 0) sẽ xử lý nhiều hình học không hợp lệ. Bạn cũng có thể sử dụng ST_MakeValid. Cuối cùng, bạn có thể thử chọn vào một bảng mới và đặt ST_IsValid (geom) vào mệnh đề where.
John Powell

Cảm ơn, tôi đã thử hack bộ đệm rồi, nhưng nó không hoạt động, nó muốn đầu vào hình học hơn là hình học (MultiPolygon). Tôi sẽ cố gắng chỉ chọn các đa giác hợp lệ và xem có bao nhiêu được lọc ra.
Mart

1
Đồng ý. Điều này xuất phát từ các điểm sản xuất st_makevalid và LineStrings cùng với các đa giác sẽ tạo ra GeometryCollection. Có một sửa chữa cho điều này mà tôi sẽ viết lên trong vài giờ. Tôi chuẩn bị lướt web :-)
John Powell

Câu trả lời:


15

Nếu bạn chỉ muốn Đa giác hoặc Đa linh kiện từ ST_MakeValid, bạn có thể sử dụng ST_Dump để trích xuất các hình học cấu thành và sau đó kiểm tra loại hình học. ST_MakeValid đôi khi sẽ tạo Điểm hoặc LineStrings, nơi GeometryCollection đến từ. Hãy thử một cái gì đó như:

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

Bạn có thể sử dụng mệnh đề IN thay vì điều kiện OR, mặc dù kết quả và kế hoạch truy vấn sẽ giống nhau. Nếu bạn chỉ muốn Multipolygons, bạn có thể gói ST_Dump trong hàm ST_Multi .

Row_number () over () sẽ chỉ trả về cho bạn một id duy nhất, bắt đầu từ một, cho mỗi hình học được trả về từ ST_Dump. Bạn cũng có thể sử dụng phần tử đường dẫn được trả về bởi ST_Dump, với cùng kết quả.

Có lẽ bạn sẽ muốn kết hợp điều này với một câu lệnh loại CREATE TABLE clean_geoms AS SELECT ...., vì một bản cập nhật trực tiếp không có khả năng hoạt động vì ST_MakeValid sẽ không tạo ra một ánh xạ từ một đến một.

Điều này chưa được kiểm chứng vì hiện tại tôi không có phương tiện, vì vậy có thể có dấu ngoặc đơn bị đặt sai, nhưng nguyên tắc chung là âm thanh. Hi vọng điêu nay co ich.


19

Bạn có thể thử ST_CollectionExtract để trích xuất [Đa] Đa giác từ GeometryCollections. Sử dụng ST_Multi để buộc chúng là MuliPolygons.

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

Sau khi hoàn thành, sử dụng ràng buộc KIỂM TRA để đảm bảo chúng vẫn hợp lệ. Xem chi tiết tại đây .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.