Membersihkan geometri di PostGIS?


12

Saya mencoba melakukan pemrosesan pada beberapa lapisan poligon yang sangat besar. Namun saya mengalami berbagai kesalahan geometri seperti:

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

Saya telah mencoba fungsi yang disarankan di sini: https://trac.osgeo.org/postgis/wiki/UsersWikiCleanPolygons

untuk membersihkan geometri, kode yang saya gunakan adalah:

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

Dengan hasil:

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

dan juga

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

Yang ini berfungsi, tetapi hanya jika saya pertama kali mengubah kolom geometri saya menjadi geometri

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

Yang kemudian meninggalkan saya dengan meja yang tidak lagi berfungsi dengan fungsi saya yang lain!

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

Saya telah mencoba mengubah kolom kembali ke geometri (MultiPolygon)

ALTER TABLE public.my_table ALTER COLUMN geom SET geometri DATA TIPE (MultiPolygon);

Tetapi ini gagal

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

Saya telah mencoba melalui PostGIS dalam Tindakan (Ed Kedua) http://www.manning.com/obe/ tapi saya hanya dapat menemukan fungsi untuk menemukan geometri yang tidak valid, tetapi kumpulan data saya sangat besar untuk memperbaikinya secara manual, saya benar-benar butuh sesuatu yang akan memperbaikinya secara otomatis.


Saya telah dapat mengisolasi poligon masalah, ketika saya mencoba dan menjalankan ST_MakeValid () saya mendapatkan hasilnya:

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

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

Saya melakukan pemeriksaan jenis pada kolom geometri saya, dan dikatakan jenisnya "MULTIPOLYGON"


ST_MakeValid mengoreksi sebanyak mungkin.
user30184

Saya mengerti, terima kasih, sebenarnya saya telah membuat kesalahan dalam pertanyaan saya di mana saya lupa menyebutkan bahwa itu adalah ST_Make_Valid yang menyebabkan masalah dengan kolom saya. Saya telah menggunakan ST_MakeValid tetapi saya harus mengubah kolom geom saya ke tipe data geometri untuk membuatnya berfungsi, dan begitu saya melakukannya saya tidak bisa mengembalikannya ke geometri (MultiPolygon)
Mart

2
Anda dapat menggunakan retasan ST_Buffer (geom, 0) yang akan berurusan dengan banyak geometri yang tidak valid. Anda juga dapat menggunakan ST_MakeValid. Akhirnya, Anda bisa mencoba memilih ke tabel baru dan meletakkan ST_IsValid (geom) di klausa mana.
John Powell

Terima kasih, saya sudah mencoba buffer hack, tetapi tidak berhasil, ia menginginkan input geometri daripada geometri (MultiPolygon). Saya akan mencoba hanya memilih poligon yang valid dan melihat berapa banyak yang disaring.
Mart

1
Baik. Ini berasal dari st_makevalid poin penghasil dan LineStrings bersama dengan poligon yang akan menghasilkan GeometryCollection. Ada perbaikan untuk ini yang akan saya tulis dalam beberapa jam. Saya akan berselancar :-)
John Powell

Jawaban:


15

Jika Anda hanya ingin Polygons atau Multipolygons dari ST_MakeValid Anda dapat menggunakan ST_Dump untuk mengekstrak geometri konstituen dan kemudian menguji untuk jenis geometri. ST_MakeValid terkadang akan menghasilkan Poin atau LineStrings yang merupakan asal GeometryCollection. Coba sesuatu seperti:

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

Anda bisa menggunakan klausa IN alih-alih kondisi ATAU, meskipun hasil dan rencana kueri akan sama. Jika Anda hanya ingin Multipolygons, Anda dapat membungkus ST_Dump dalam fungsi ST_Multi .

Row_number () over () hanya akan mengembalikan Anda id unik, mulai dari satu, untuk setiap geometri yang dikembalikan dari ST_Dump. Anda juga dapat menggunakan elemen path yang dikembalikan oleh ST_Dump, dengan hasil yang sama.

Anda mungkin ingin menggabungkan ini dengan CREATE TABLE dibersihkan_geoms SEBAGAI SELECT .... pernyataan jenis, karena pembaruan langsung tidak mungkin berfungsi sebagai ST_MakeValid wil notl umumnya (atau selalu) menghasilkan pemetaan satu ke satu dari yang saya masukkan ke output.

Ini tidak diuji karena saya tidak memiliki sarana, saat ini, sehingga mungkin ada tanda kurung salah tempat, tetapi prinsip umum adalah suara. Semoga ini membantu.


19

Anda dapat mencoba ST_CollectionExtract untuk mengekstrak [Multi] Poligon dari GeometryCollections. Gunakan ST_Multi untuk memaksa mereka sebagai MuliPolygons.

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

Setelah Anda selesai, gunakan PERIKSA kendala untuk memastikan mereka tetap valid. Lihat detailnya di sini .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.