Объединение множества маленьких полигонов в большой полигон с помощью 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.