Объединение множества маленьких полигонов в большой полигон с помощью PostGIS?


47

У меня есть следующий слой, используя SRID 27700 в Postgis:

введите описание изображения здесь

Это каждый административный регион в Великобритании, и (как вы можете видеть из цветовой группировки) у каждого из них есть текстовое поле, в котором указывается округ, в котором они находятся.

То, что я хотел бы сделать, это сделать большие полигоны округа из меньших в данном округе, поэтому EG на рисунке выше всех полигонов цвета чирка сформировал бы один большой полигон из одного внешнего кольца, которое содержит все полисы в этом цвет, как и все остальные, фиолетовый, коричневый, розовый, серый и т. д. должен образовывать один многоугольник.

Я уже пробовал следующее:

insert into parishesmerged (geometry)
select astext(multi(ST_Union(the_geom))) as the_geom from parishes
group by county_name

Но он продолжает генерировать нарушенные геометрии, которые у меня потом возникают большие проблемы при дальнейшей обработке.

Я пытаюсь сделать более простую карту уровня округа с основными областями вывода в.

Любые решения тоже не обязательно должны быть в Postgis, у меня установлен полный стек OS4Geo, последняя версия QGis и больше утилит, чем я могу потрясти.

Единственные вещи, которых у меня нет, - это большие парни вроде ArcGis (хотя у меня где-то где-то валяется Old Mapinfo)


Напомним, что набор данных, который я пытаюсь создать, должен сопровождать книгу ГИС, которую я пишу, для программистов .NET, желающих писать ГИС-приложения с использованием .NET


Попробовав приведенные ниже предложения, лучше всего подошел вариант «Пола Рамсея».

Теперь у меня есть хороший упрощенный файл для округов и районов, который достаточно прост для моей книги, но достаточно сложен, чтобы позволить мне продемонстрировать некоторые интересные геопространственные SQL.

Несмотря на то, что решение Пола, в конечном счете, было тем, что сработало для меня, я также использовал другие ответы на такие вещи, как упрощение карты полигонов и дальнейшее снижение сложности.

Однако, кое-что я заметил при этом, хотя ST_Collect действительно быстрее, чем ST_Union, запуск для запуска также был главным образом причиной неисправных геометрий. Я предполагаю, что увеличение скорости достигается за счет меньшей точности в основной функции.


Этот процесс известен как «распустить». У меня нет опыта работы с PostGIS, но я считаю, что вы можете использовать команду ST_Union для выполнения роспуска.
— dmahr

Привет, dmahr, спасибо за разъяснения, не был уверен, как он назывался, однако, если вы прочитаете мой вопрос, то увидите, что я уже попробовал это :-)
— shawty

Ой, прости ... не видел этого. Вы пробовали выбрать заявление без astext(multi())части? Я просто исхожу из того, что вижу в других примерах PostGIS.
— dmahr

Пока нет, попробую сейчас. Tks. У вас есть ссылка для распуска примеров?
— Shawty

Пожалуйста, отредактируйте для экспресс, если вы хотите "единственное внешнее кольцо" или нет. (см. мой ответ)
— Питер Краусс

Ответы:


43

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

 CREATE TABLE merged AS
 SELECT ST_Union(ST_SnapToGrid(the_geom,0.0001)) 
 FROM parishes
 GROUP BY county_name;

Если у вас PostGIS 2.0, построение структуры топологии с допуском может дать вам ответ, который вы ищете, если вам повезет.


Хорошая подсказка для коррекции геометрии, но насчет "... одного большого многоугольника из одного внешнего кольца, содержащего все полисы ..."?
— Питер Краусс

Я не знал о SnapTo, я попробую :-) Tks. К сожалению, нет, пока не используется PG 2, хотя обновление еще не завершено.
— Shawty

Не уверен, что ваш синтаксис правильный. Согласно postgis.net/docs/ST_Union.html , нет подписи, которая принимает число во втором параметре.
— Арен Камбре

Вы правы, скобка была не в том месте. Ред.
— Пол Рэмси

Есть ли MySQL эквивалентно этому? я продолжаю получать, Incorrect parameter count in the call to native function 'ST_Union'и я не знаю, если это ограничение MySQL.
— Jayen

7

Вы говорите, что нужно "... сформировать один большой многоугольник из одного внешнего кольца, которое содержит все полисы ...". ST_ExteriorRing делает это,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_Union(GEOM)))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

Вы можете использовать ST_Union (), как предложено, или протестировать с помощью ST_Collection ().


ЗАМЕЧАНИЯ: чтобы избежать маленьких петель или «сломанных геометрий», вы можете использовать st_convexhull и / или ST_Simplify для каждого geom,

SELECT ST_MakePolygon(ST_ExteriorRing(ST_union(ST_Simplify(GEOM,0.5))))
FROM GEOMTABLE GROUP BY ATTRCOLUMN

и проверьте свою геометрию,

SELECT * FROM (
   SELECT gid, ST_IsValid(geom) as valid, ST_IsSimple(geom) as simple 
   FROM GEOMTABLE) AS t  
WHERE NOT(valid AND simple); 

Извините за путаницу: в моем описании я имел в виду один большой многоугольник, созданный из меньших. Я понимаю, что в зависимости от контекста «Внешнее кольцо» может означать разные вещи для разных людей, я намеревался описать один многоугольник, созданный из граница присутствует вокруг каждой группы полигонов.
— Shawty

7

Функция ST_Collect является «агрегатной» функцией в терминологии PostgreSQL

« SELECT ST_Collect(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN» вернет отдельную GEOMETRYCOLLECTION для каждого отдельного значения ATTRCOLUM

http://postgis.net/docs/ST_Collect.html

Примечание: ST_Collect намного быстрее, чем ST_Union


3
Я попробовал это и получил немного другие результаты, но нужна ли мне геометрическая коллекция? По сути, я пытаюсь сделать один большой многоугольник, необязательно с отверстиями в нем (В частности, в Дербишире и Ноттингемшире, где и Дерби, и Ноттингем образуют отдельные районы прямо в центре. Хотя я наблюдал разницу в скорости, так что это Кьюл.
— Shawty

2

Исходя из вашего вопроса, я предполагаю, что вы используете продукт Boundary-Line от Ordnance Survey. Если это так, то он уже включает в себя набор данных уровня округа, поэтому нет необходимости пытаться генерировать его самостоятельно из приходских районов более низкого уровня.

Если вы не используете Boundary-Line, тогда я рекомендую вам сделать это, так как она бесплатна под лицензией OS OpenData и имеет уровень округа в виде файла формы, который вы можете загрузить непосредственно в PostGIS.


2
Как насчет предоставления ссылки для тех, кто ее не знает? Благодарю.
— Джонатр

1
Привет, CHEnderson, вы на самом деле правы, да, я использую набор данных пограничного уровня из ОС Opendata, к сожалению, границы округов не полны, фактический файл формы округа включает только те, которые названы округами, лондонские районы содержат области вокруг У Лондона и других файлов есть некоторые части, некоторые более низкие и меньшие уровни, чем другие. Единственный файл, в котором есть весь план Великобритании, а впоследствии и любой шанс выделить все верхние уровни округов и муниципальных границ в один слой, - это уровень приходов, поэтому я и пытаюсь это сделать.
— Shawty

Для тех, кто заинтересован, вы можете загрузить границы округа и многое другое прямо здесь: ordnancesurvey.co.uk/oswebsite/products/os-opendata.html
— shawty
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.