Я пытаюсь сделать некоторые обработки на очень больших слоях полигонов. Однако я сталкиваюсь с различными ошибками геометрии, такими как:
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 УСТАНОВИТЬ ТИП ДАННЫХ геометрия (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, вы можете использовать ST_Dump для извлечения составляющих геометрий, а затем проверить тип геометрии. ST_MakeValid иногда генерирует Points или LineStrings, откуда и происходит GeometryCollection. Попробуйте что-то вроде:
Вы можете использовать предложение IN вместо условия OR, хотя результат и план запроса будут одинаковыми. Если вам нужны только мультиполигоны, вы можете обернуть ST_Dump в функцию ST_Multi .
Row_number () over () просто вернет вам уникальный идентификатор, начиная с единицы, для каждой геометрии, возвращаемой из ST_Dump. Вы также можете использовать элемент пути, возвращаемый ST_Dump, с тем же результатом.
Вероятно, вы захотите объединить это с оператором типа CREATE TABLE cleaned_geoms AS SELECT ...., поскольку прямое обновление вряд ли будет работать, так как ST_MakeValid не будет обычно (или всегда) производить сопоставление «один к одному» из того, что я положил для вывода.
Это не проверено, так как в настоящее время у меня нет средств, поэтому могут быть неуместные скобки, но общий принцип обоснован. Надеюсь это поможет.
источник
Вы можете попробовать ST_CollectionExtract для извлечения [Multi] полигонов из GeometryCollections. Используйте ST_Multi, чтобы сделать их мультиполигонами.
По завершении используйте ограничение CHECK, чтобы убедиться, что они остаются действительными. Подробности здесь .
источник