Чистка геометрії в 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 (MultiPolygon);

Але це не вдається

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

Я спробував пройти PostGIS в дії (Другий Ед) 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, але мені потрібно змінити мій стовпчик геометрії на тип даних геометрії, щоб змусити його працювати, і як тільки я це зробити, я не можу повернути його до геометрії (MultiPolygon)
березня

2
Ви можете використовувати хак ST_Buffer (geom, 0), який матиме справу з багатьма невірними геометріями. Ви також можете використовувати ST_MakeValid. Нарешті, ви можете спробувати вибрати в новій таблиці та поставити ST_IsValid (geom) в пункт де.
Джон Пауелл

Дякую, я вже спробував зламати буфер, але він не спрацював, він хотів ввести геометрію, а не геометрію (MultiPolygon). Я спробую лише вибрати дійсні багатокутники і побачити, скільки відфільтровано.
березня

1
Добре. Це відбувається від st_makevalid-точок, що виробляють і LineStrings, а також багатокутників, які дадуть GeometryCollection. Для цього є виправлення, яке я напишу через пару годин. Я збираюся займатися серфінгом :-)
Джон Пауелл

Відповіді:


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 замість умови АБО, хоча план результатів та запитів буде однаковим. Якщо вам потрібні лише багатополігони, ви можете зафіксувати ST_Dump у функції ST_Multi .

Row_number () over () просто поверне вам унікальний ідентифікатор, починаючи з одного, для кожної геометрії, повернутої з ST_Dump. Ви також можете використовувати елемент шляху, повернений ST_Dump, з тим же результатом.

Ви, мабуть, захочете поєднати це із СТВОРИТИМ ТАБЛИКОю_ очищення_на_яви AS AS SELECT .... тип операції, оскільки пряме оновлення навряд чи спрацює, оскільки ST_MakeValid wil notl, як правило (або завжди), створює відображення від одного до одного, яке я поставив до виводу.

Це в даний час не перевірено, оскільки у мене немає засобів, тому можуть бути неправильні дужки, але загальний принцип є здоровим. Сподіваюсь, це допомагає.


19

Ви можете спробувати ST_CollectionExtract для вилучення [Multi] полігонів з GeometryCollections. Використовуйте ST_Multi, щоб примусити їх як MuliPolygons.

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

Після завершення скористайтеся обмеженням ПЕРЕВІРИТИ, щоб переконатися, що вони залишаються дійсними. Деталі дивіться тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.