กำลังทำความสะอาดรูปทรงเรขาคณิตใน 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)

แก้ไขตาราง public.my_table แก้ไขคอลัมน์คอลัมน์ตั้งประเภทข้อมูลเรขาคณิต (MultiPolygon);

แต่สิ่งนี้ล้มเหลว

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 แก้ไขให้ถูกต้องมากที่สุด
30184

ฉันเห็นขอบคุณจริงฉันทำผิดพลาดในคำถามของฉันที่ฉันลืมที่จะพูดถึงว่ามันเป็น ST_Make_Valid ที่ทำให้เกิดปัญหากับคอลัมน์ของฉัน ฉันได้ใช้ ST_MakeValid แต่ฉันต้องเปลี่ยนคอลัมน์ Geom ของฉันเป็นข้อมูลชนิดรูปทรงเรขาคณิตที่จะได้ไปทำงานและเมื่อฉันทำอย่างนั้นฉันลาดเทรับมันกลับไปที่รูปทรงเรขาคณิต (MultiPolygon)
มาร์ท

2
คุณสามารถใช้แฮ็ค ST_Buffer (geom, 0) ซึ่งจะจัดการกับรูปทรงเรขาคณิตที่ไม่ถูกต้องมากมาย คุณยังสามารถใช้ ST_MakeValid ในที่สุดคุณสามารถลองเลือกลงในตารางใหม่และวาง ST_IsValid (geom) ในส่วนคำสั่ง where
John Powell

ขอบคุณฉันลองแฮ็คบัฟเฟอร์แล้ว แต่มันใช้งานไม่ได้มันต้องการอินพุตเรขาคณิตมากกว่าเรขาคณิต (MultiPolygon) ฉันจะลองเลือกรูปหลายเหลี่ยมที่ถูกต้องเท่านั้นและดูว่ามีการกรองจำนวนเท่าใด
Mart

1
ตกลง. สิ่งนี้มาจาก st_makevalid จุดผลิตและ LineStrings พร้อมกับรูปหลายเหลี่ยมซึ่งจะสร้าง GeometryCollection มีการแก้ไขสำหรับเรื่องนี้ซึ่งฉันจะเขียนขึ้นในสองสามชั่วโมง ฉันกำลังจะไปเล่นเซิร์ฟ :-)
John Powell

คำตอบ:


15

หากคุณต้องการให้รูปหลายเหลี่ยมหรือหลายรูปแบบจากST_MakeValidคุณสามารถใช้ST_Dumpเพื่อแยกรูปทรงที่เป็นส่วนประกอบแล้วทดสอบรูปทรงเรขาคณิต ST_MakeValid บางครั้งจะสร้างคะแนนหรือ LineStrings ซึ่งเป็นที่มาของ GeometryCollection ลองสิ่งที่ชอบ:

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

คุณสามารถใช้ส่วนคำสั่ง IN แทนเงื่อนไข OR แม้ว่าผลลัพธ์และแผนแบบสอบถามจะเหมือนกัน ถ้าคุณต้องการ Multipolygons เท่านั้นคุณสามารถล้อม ST_Dumpในฟังก์ชันST_Multi

row_number () บน () จะคืนค่า ID ที่ไม่ซ้ำกันให้คุณโดยเริ่มต้นจากหนึ่งสำหรับแต่ละเรขาคณิตที่ส่งคืนจาก ST_Dump คุณยังสามารถใช้องค์ประกอบเส้นทางที่ส่งคืนโดย ST_Dump ด้วยผลลัพธ์เดียวกัน

คุณน่าจะต้องการรวมสิ่งนี้กับคำสั่ง CREATE TABLE clean_geoms AS SELECT .... เนื่องจากการอัปเดตโดยตรงไม่น่าจะทำงานได้เหมือน ST_MakeValid โดยทั่วไป (หรือเสมอ) จะสร้างการแมปแบบหนึ่งต่อหนึ่งจากฉัน

นี่ยังไม่ได้ทดสอบเนื่องจากฉันไม่มีวิธีการในปัจจุบันดังนั้นอาจมีวงเล็บหายไป แต่หลักการทั่วไปคือเสียง หวังว่านี่จะช่วยได้


19

คุณสามารถลองST_CollectionExtractเพื่อแยก [หลาย] รูปหลายเหลี่ยมจาก GeometryCollections ใช้ ST_Multi เพื่อบังคับให้เป็น MuliPolygons

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

หลังจากเสร็จสิ้นใช้ข้อ จำกัด การตรวจสอบเพื่อให้แน่ใจว่าพวกเขายังคงใช้ได้ ดูรายละเอียดที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.