Есть ли в PostGIS функция растворения, кроме st_union?

22

Я ищу функцию для растворения общих границ между полигонами в таблице. ST_UNION () почти делает то, что я ищу, но он создает мультиполигон из всех многоугольников слоя независимо от того, имеют ли они общую границу или нет. Я бы предпочел только расторгнуть границы между полигонами, которые касаются друг друга. Я подумал, что должен быть какой-то способ использования ST_TOUCHES (), но тогда потребность в функции растворения кажется настолько распространенной, что я был бы удивлен, если бы не было встроенной функции для достижения этой цели.

Вариант использования выглядит следующим образом: я скачал данные Corine Landcover для большой европейской страны, и я хочу растворить границы между разными типами лесов (около 75 000 полигонов в одной таблице). Я пробовал ST_UNION, но он не дает мне выполнить ошибку «недостаточно памяти» (хотя 30 000 полигонов работали):

create table corine00 as 
  select st_union(the_geom) as the_geom, 
         sum(area_ha) as area_ha,
         substr(code_00,1,2) as code_00
  from clc00_c31_forests
  group by substr(code_00,1,2)

Примечание. Все коды лесов начинаются с «31», и я использую PostGIS 1.4, версия GEOS: 3.2.0-CAPI-1.6.0

Подземье
источник

Ответы:

21

ST_MemUnion () будет запускать наивный и медленный процесс памяти. Вы можете попробовать это, если ваша проблема достаточно мала, она может закончиться в разумные сроки. Вы также можете просто разбить свою проблему на две части, а затем запустить их вместе. Так как результат будет иметь гораздо меньше точек, чем входные данные, вы могли бы таким образом вписать всю проблему в память. Или используйте процедуру быстрого голодания на половинках и более медленную процедуру при окончательном слиянии.

Пол Рэмси
источник
4
Фантастически, что ты здесь, Пол, спасибо за то, что ты принес несравненный опыт.
fmark
1
Спасибо, похоже, моя проблема недостаточно мала. ST_MemUnion () теперь работает в течение 24 часов. Я постараюсь разделить проблему.
Подземье
5

Я считаю, что ST_Dump - это то, что вы хотите:

ST_Dump :

Возвращает набор строк geometry_dump (geom, path), которые составляют геометрию g1 .... Например, его можно использовать для разложения МНОГОПОЛИГОНОВ в ПОЛИГОНЫ. ...

Итак, для вашего случая:

 SELECT (ST_Dump( ST_Union( the_geom ) )).geom
 FROM clc00_c31_forests
 GROUP BY substr(code_00,1,2)

Я не уверен, как это будет взаимодействовать с созданием таблицы, которую вы пытаетесь сделать, но это должно дать вам геометрию как отдельные записи. После этого вы сможете выполнить пространственное соединение (используя && и ST_Contains) между двумя таблицами, чтобы собрать данные в геометрии.

yhw42
источник
2
Примечание: это будет полезно, только если вы решите проблемы с памятью ST_Union! :)
yhw42
4

Ваш PostGIS скомпилирован с GEOS 3.1.0+? Для этой версии было реализовано гораздо более быстрое каскадное объединение , но если его не найти, будет использоваться более старый код, который на несколько порядков медленнее.

Обновление : похоже, что ваш PostGIS использует подход каскадного объединения, но нехватка памяти реальна. Я бы попробовал увеличить объем доступной памяти для вашего экземпляра Postgres, вот несколько советов Пола Рэмси из FOSS4G PostGIS за 2007 год :

  • Доступ к диску медленный, поэтому можно повысить производительность, используя больше памяти для кэширования данных!
    • Увеличение shared_buffers
    • Физическая память - ОС нуждается в * 75%
  • Сортировка быстрее в памяти
    • Увеличение work_mem
  • Очистка диска происходит быстрее с большим объемом памяти
    • Увеличение maintenance_work_mem
  • Выделено на соединение
  • Также
    • Увеличение wal_buffers
    • Увеличение checkpoint_segments
    • Уменьшить random_page_cost

В вашем случае, я бы попытался увеличить shared_buffers, общая рекомендация - 25% вашей доступной памяти для сервера базы данных, но попробуйте увеличить его до 3-4-кратного его текущего значения и посмотреть, завершится ли он.

SCW
источник
postgis_geos_version () возвращает: 3.2.0-CAPI-1.6.0 ... Я думаю, это нормально. Попробую ST_Collect, спасибо.
Подземье
Что ж, ST_Collect, похоже, не стирает никаких границ, а также создает один гигантский мультиполигон.
Подземье
да, я неправильно прочитал страницу для ST_Collect. Я обновил свой ответ, чтобы дать более конкретные советы по настройке использования памяти Postgres.
2010 года