Łączenie wielu małych wielokątów w celu utworzenia większego wielokąta za pomocą PostGIS?

47

Mam następującą warstwę używającą SRID 27700 w Postgis:

wprowadź opis zdjęcia tutaj

Jest to każdy region administracyjny w Wielkiej Brytanii i (jak widać z grupowania kolorów) każdy z nich ma pole tekstowe określające region, w którym się znajduje.

Chciałbym zrobić większe wielokąty hrabstwa z mniejszych w danym hrabstwie, więc EG na powyższym zdjęciu wszystkie wielokąty w kolorze turkusowym utworzyłyby jeden duży wielokąt z pojedynczego zewnętrznego pierścienia, który zawiera wszystkie bieguny w tym kolor, podobnie jak wszystkie fioletowe, brązowe, różowe, szare itp. powinny wszystkie tworzyć jeden wielokąt.

Próbowałem już:

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

Ale ciągle generuje uszkodzone geometrie, które mam duże problemy z dalszym przetwarzaniem.

Próbuję stworzyć prostszą mapę na poziomie hrabstwa z głównymi obszarami wyjściowymi w.

Żadne rozwiązania nie muszą też być w Postgis, mam zainstalowany pełny stos OS4Geo, najnowszą wersję QGis i więcej narzędzi, niż mogę sobie wyobrazić.

Jedyne rzeczy, których nie mam, to duzi chłopcy, tacy jak ArcGis (chociaż mogę gdzieś leżeć gdzieś w pobliżu Stare Mapinfo)


Dla przypomnienia zestaw danych, który próbuję utworzyć, ma towarzyszyć książce GIS, którą piszę, skierowanej do programistów .NET, którzy chcą pisać aplikacje GIS przy użyciu .NET


Po wypróbowaniu poniższych sugestii najlepiej działało rozwiązanie „Paul Ramseys”.

Mam teraz ładny, uproszczony plik hrabstw i dzielnic, który jest po prostu wystarczająco prosty dla mojej książki, ale wystarczająco skomplikowany, aby umożliwić mi zademonstrowanie ciekawego geograficznego przestrzennego SQL.

Chociaż ostatecznie rozwiązanie Paula było dla mnie skuteczne, skorzystałem również z innych odpowiedzi, na przykład w celu uproszczenia mapy wielokątów i dalszego zmniejszenia złożoności.

Na rzeczy, którą zaobserwowałem, robiąc to, chociaż ST_Collect jest rzeczywiście szybszy niż ST_Union, biegnij za biegiem, ale to on był głównie odpowiedzialny za złamane geometrie. Domyślam się, że wzrost prędkości jest uzyskiwany kosztem mniejszej dokładności w funkcji rdzenia.

shawty
źródło
Ten proces jest znany jako „rozpuszczenie”. Nie mam doświadczenia z PostGIS, ale wierzę, że możesz użyć polecenia ST_Union do wykonania rozpuszczenia.
dmahr,
Cześć dmahr, dziękuję za wyjaśnienie, nie byłem pewien, jak to się nazywa, jednak jeśli przeczytasz moje pytanie, zobaczysz, że już próbowałem :-)
shawty
Ups, przepraszam ... nie widziałem tego. Czy wypróbowałeś instrukcję select bez astext(multi())części? Po prostu odchodzę od tego, co widzę w innych przykładach rozwiązania PostGIS.
dmahr,
Jeszcze nie, spróbuje teraz. Tks. Czy masz link do rozwiązywania przykładów?
shawty
Edytuj ekspresowo, jeśli chcesz „pojedynczy pierścień zewnętrzny”, czy nie. (patrz moja odpowiedź)
Peter Krauss,

Odpowiedzi:

43

ST_Union działałby, ale praca na linii prawie na pewno nie jest czysta. Tak więc granice twoich małych rzeczy nie wszystko idealnie się podoba. Możesz delikatnie przyciągnąć je do siatki, aby spróbować zwiększyć szanse na wyrównanie wierzchołków, ale założę się, że nadal będziesz mieć kilka przypadków, które nie działają. Albo będą poza tolerancją, albo, co bardziej prawdopodobne, będą miejsca, w których wierzchołki nie zostaną sparowane, więc po jednej stronie jest linia, a po drugiej wierzchołek.

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

Jeśli masz PostGIS 2.0, zbudowanie struktury topologicznej z tolerancją może doprowadzić do odpowiedzi, której szukasz, jeśli masz trochę szczęścia.

Paul Ramsey
źródło
Dobra wskazówka do korekcji geometrii, ale o „… jednym dużym wielokącie z pojedynczego pierścienia zewnętrznego, który zawiera wszystkie polisy…”?
Peter Krauss,
Nie wiedziałem o „SnapTo”. Spróbuję :-) Tks. Niestety, nie, jeszcze nie używam PG 2, aktualizacja jest w przygotowaniu.
shawty
Nie jestem pewien, czy Twoja składnia jest poprawna. Według postgis.net/docs/ST_Union.html nie ma podpisu, który akceptuje liczbę w drugim parametrze.
Aren Cambre
Masz rację, nawias był w niewłaściwym miejscu. Edytowane.
Paul Ramsey
czy istnieje odpowiednik mysql? ciągle się Incorrect parameter count in the call to native function 'ST_Union'pojawia i nie wiem, czy to ograniczenie MySQL.
Jayen
7

Mówisz, że trzeba „... uformować jeden duży wielokąt z pojedynczego zewnętrznego pierścienia, który zawiera wszystkie polisy…”. Zrób to ST_ExteriorRing,

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

Możesz użyć ST_Union (), zgodnie z sugestią, lub przetestować za pomocą ST_Collection ().


UWAGI: aby uniknąć małych krzywych lub „złamanych geometrii”, możesz użyć st_convexhull i / lub ST_Simplify dla każdej geom,

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

i sprawdź swoje geometrie,

SELECT * FROM (
   SELECT gid, ST_IsValid(geom) as valid, ST_IsSimple(geom) as simple 
   FROM GEOMTABLE) AS t  
WHERE NOT(valid AND simple); 
Peter Krauss
źródło
Przepraszam za zamieszanie: Przez mój opis rozumiałem jeden większy wielokąt utworzony z mniejszych, zdaję sobie sprawę, że w zależności od kontekstu „Pierścień zewnętrzny” może oznaczać różne rzeczy dla różnych ludzi, moim zamiarem było opisanie pojedynczego wielokąta utworzonego z granica obecna wokół każdej grupy wielokątów.
shawty
7

Funkcja ST_Collect jest funkcją „agregującą” w terminologii PostgreSQL

SELECT ST_Collect(GEOM) FROM GEOMTABLE GROUP BY ATTRCOLUMN” zwróci osobną GEOMETRYKOLEKCJĘ dla każdej odrębnej wartości ATTRCOLUM

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

Uwaga: ST_Collect jest znacznie szybszy niż ST_Union

Mapperz
źródło
3
Próbowałem tego i uzyskałem nieco inne wyniki, ale czy potrzebuję kolekcji geometrii? Zasadniczo staram się zrobić jeden duży wielokąt, opcjonalnie z dziurami (szczególnie w Derbyshire i Nottinghamshire, gdzie oba derby i Nottingham tworzą osobne dzielnice w samym środku. Zauważyłem jednak różnicę prędkości, więc to kewl.
shawty
2

Z twojego pytania zakładam, że używasz produktu linii granicznej Ordnance Survey. W takim przypadku zawiera on już zestaw danych na poziomie hrabstwa, więc nie trzeba próbować go generować z obszarów parafialnych niższego poziomu.

Jeśli nie używasz Boundary-Line, radzę zrobić to, ponieważ jest bezpłatne na licencji OS OpenData i ma poziom hrabstwa jako plik kształtu, który można załadować bezpośrednio do PostGIS.

CHenderson
źródło
2
Co powiesz na udostępnienie linku tym, którzy go nie znają? dzięki.
jonatr
1
Cześć CHEnderson, w rzeczywistości masz rację, tak. Korzystam z zestawu danych warstwy granicznej z OS Opendata, niestety granice hrabstwa nie są kompletne, rzeczywisty plik kształtu hrabstwa zawiera tylko te, które są nazwane hrabstwami, londyńskie dzielnice zawierają obszary wokół Londyn i inne pliki mają pewne części, niektóre niższe i mniejsze poziomy niż inne. Jedynym plikiem, który ma cały zarys Zjednoczonego Królestwa, a następnie jakąkolwiek szansę na wydobycie wszystkich powiatów i granic miejskich na jednej warstwie, jest warstwa parafialna, dlatego próbuję to zrobić.
shawty
Zainteresowanych możesz pobrać granice hrabstwa i nie tylko, tutaj: ordnancesurvey.co.uk/oswebsite/products/os-opendata.html
shawty