Poniższa ilustracja pokazuje problem :
jak w (a) Mam zestaw rozłącznych wielokątów, takich jak geometrie w PostGIS. Potrzebuję czegoś w rodzaju (b) , „mozaiki” tego zestawu wielokątów, budując ją według kryteriów „regionu wpływu” ... Jest jak konstrukcja Voronoi (zilustrowana przez (c) ): w rzeczywistości, jeśli wielokąty były punkty, regiony wpływu to Voronoi.
Podsumowując: Potrzebuję algorytmu SQL (lub jakiegoś specyficznego dla PostGIS), który generuje „mozaikę” zestawu rozłącznych wielokątów. (być może pętla małych operacji ST_Buffer i ST_Difference)
PS: Potrzebuję, podobnie jak Voronoi, aby delimitacja przestrzeni (kwadratowa ramka w (b) ) była ignorowana.
Ten problem jest podobny do tego dotyczącego linii .
EDYCJA (po komentarzu @FelixIP)
Wolę pozostać we wszechświecie wektorowym , aby nie stracić precyzji (np. Używając ST_DelaunayTriangles oraz dodając i odejmując wnętrza według oryginalnych wielokątów, dostosowując rozwiązanie do podwójnego wykresu ) ... Niektóre proste i automatyczne pakiety, takie jak pprepair (wspomagane jak narzędzia topologiczne QGIS nie są automatyczne). Ale raster jest być może prostszy i wymaga mniej procesora.
Ta ilustracja „procesu GRID” jest również słuszna jako rozwiązanie, zakładając, że może ona pozwolić na taką samą precyzję i „wzrost regionu wpływów euklidesowych”.
W ARCGIS istnieje narzędzie analizy przestrzennej znane jako alokacja euklidesowa , więc być może istnieje podobne rozwiązanie PostGIS , zaczynające się od zestawu wielokątów (klasyfikowanie, rasteryzacja i odzyskiwanie wielokątów).
źródło
Odpowiedzi:
Tak więc przygotuję dla ciebie ciasto - talerz z owocami, używając narzędzi PostGIS, tak jak prosiłeś, jeśli poprawnie zrozumiałem pytanie, i jak wspomniałem, odpowiedzialność za działanie piekarnika PostGIS spoczywa na jej zespole kreatywnym.
Poproszę, aby nikt mnie nie obraził w moim humorystycznym stylu i zrozumiałem to jako grę!
Oryginalny plik to pokrojone owoce i proste kształty (zwane dalej owocami), patrz rysunek 1 poniżej.
Oto mój przepis, w czym pomogą mi drodzy programiści, o których dowiecie się później. Zacznijmy, a do tego stworzymy ciasto, w którym zostaną złożone nasze owoce, dla którego uruchom skrypt:
create table poly_extent as SELECT ST_SetSRID(ST_Buffer(ST_Envelope(ST_Extent(geom)),0.05),4326) as geom FROM poly;
Zobacz wynik na ryc. 2 poniżej
Teraz, jeśli jest niewiele owoców, jak na moim zdjęciu, utwórz granicę zewnętrznego bufora na owocu, lub jeśli jest wiele owoców, utwórz granicę bufora ujemnego, dla którego uruchom skrypt:
create table poly_buff_dump as SELECT ((ST_Dump(ST_Boundary(ST_Union(ST_Buffer((geom),0.01, 'join=mitre mitre_limit=5.0'))))).geom) geom FROM poly;
I pokrój linie buforowe wokół każdego owocu
UPDATE poly_buff_dump SET geom=ST_RemovePoint(geom, ST_NPoints(geom)-1) WHERE ST_IsClosed(geom)=true;
Zobacz wynik na ryc. 3 poniżej(Właściwie myślałem, że w rezultacie dostanę linie przerywane (na przykład w kole), ale jeśli liczby są trudne, czasami uzyskuje się przerwy, nieprawidłowe, na przykład jedna strona prostokąta odpadła itp. )
Następnie musisz w wygodny sposób podzielić uzyskane linie na równe segmenty i wyodrębnić z nich punkty
create table poly_buff_dump_pt as SELECT (ST_DumpPoints((geom))).geom geom FROM poly_buff_segm;
Wynik, patrz rysunek 4 poniżej
Teraz uruchom narzędzie Voronoi, w tym miejscu użyłem narzędzia sugerowanego przez link MickyT: /gis//a/172246/120129 , w wyniku czego utworzysz tabele o nazwie „voronoi ”Za to, że„ mój pierwszy asystent ”jest niezależny od szefa kuchni dzięki szefowi kuchni! :-).
Drugim sposobem na tym etapie jest uruchomienie funkcji ST_VoronoiPolygons.
Wynik, patrz rysunek 5 poniżej
Teraz odetnij dodatkowe części, uruchamiając skrypt:
create table poly_voronoi_cut as SELECT ST_Intersection(a.geom, b.geom) geom FROM voronoi a INNER JOIN poly_extent b ON ST_Intersects(a.geom, b.geom);
Wynik, patrz rysunek 6 poniżej.Teraz uruchom skrypt, aby wyrównać typ danych geodezyjnych w LineString:
create table poly_voronoi_dump as SELECT (ST_Dump(geom)).geom as geom FROM poly_voronoi_cut;
A teraz poproszę „mojego drugiego partnera”, aby podjął obowiązki i wymieszał tort wel (Jeff - /gis//a/785/120129 ), wyrównując go w jednej warstwie i do tego , dziękuję za to!CREATE TABLE poly_overlay_cut AS SELECT geom FROM ST_Dump(( SELECT ST_Polygonize(geom) AS geom FROM ( SELECT ST_Union(geom) AS geom FROM ( SELECT ST_ExteriorRing(geom) AS geom FROM poly_voronoi_dump) AS lines ) AS noded_lines ) );
Teraz nadszedł czas, aby zabrać się do pracy, dla której uruchamiam skrypt:create table poly_voronoi_union as SELECT b.id, (ST_ConvexHull(ST_Union(a.geom, b.geom))) geom FROM poly_overlay_cut a INNER JOIN poly_buff_dump b ON ST_Intersects(a.geom, b.geom) GROUP BY b.id, a.geom, b.geom;
i inny skrypt:create table poly_voronoi_union_area as SELECT ST_Union(ST_ConvexHull(ST_BuildArea(geom))) as geom FROM poly_voronoi_union GROUP BY id;
patrz rysunek 7 poniżejJak widać na zdjęciu, nasze cięcia mają małe warstwy, które można usunąć, jako opcję za pomocą ST_SnapToGrid (lub w inny sposób):
I na koniec wycinamy nasze pieczone owoce z naszego ciasta, nawet trochę się zmęczyłem stojąc przy piekarniku :-)
create table polygon_voronoi_result as SELECT (ST_Dump(ST_Difference(a.geom, b.geom))).geom as geom FROM poly_voronoi_union_area_snap as a JOIN poly b ON ST_Intersects(a.geom, b.geom);
Wynik patrz rysunek 8Wszystko od tego dnia, teraz wszyscy nauczą się piec pyszne ciasta - talerz owoców. Pomóż sobie wszystkim i wybierz części, które lubisz dla wszystkich.
(Szkoda, że tak naprawdę nie mogę nakarmić wszystkich ludzi, nie elektronicznymi ciastkami, ale prawdziwymi ciastkami, być może głód skończy się na Ziemi ...)
Edycja: Wiśnia na torcie może wyglądać tak :-):
lub
Popraw skrypt 01.04.2020:
Z tobą był dobry i uczciwy Mr.Baker, dziękuję wszystkim i powodzenia: -) ...
Oryginalne rozwiązania.
Ten skrypt nazywa się: ST_VoronoiDiagramsFromPolygons.
źródło
ST_Buffer
iST_ConvexHull
? Istnieje alternatywny algorytm?ST_ConvexHull
, to tylko ciekawość, jakie wyniki możemy uzyskać po Figurze 6,poly_voronoi_union
bez ST_ConvexHull.Postgis nie mają dedykowanej funkcji dla voronoi, ale Qgis zawiera funkcję vornoi, która mogłaby tworzyć wielokąty voronoi z punktów, więc używając qgis wykonałem następujące kroki, aby uzyskać te wyniki:
- tworzyć punkty z wielokątów za pomocą
extract nodes
funkcji.-make wielokątów vornoi za pomocą funkcji voroi w Qgis.
-zrób połączenie przestrzenne w Qgis.
-rozpuszczać wyniki.
źródło
OK - Pomyślałem o tym trochę i odkryłem, że to było coś, na co ostatnio patrzyłem.
Weź swoje początkowe polisy:
Wygeneruj nowy atrybut z liczbą (w moim przypadku 100). Użyj narzędzia Wektor-> Narzędzia badawcze -> Losowe punkty wewnątrz wielokątów, to wygeneruje (100) punktów wewnątrz każdego wielokąta:
Następnie Vector-> Narzędzia geometrii -> Voronoi, aby wygenerować polisy na podstawie tej warstwy punktowej.
Teraz możesz użyć narzędzia Wektor -> Zapytanie przestrzenne: Wybierz punkty, które należą do jednego wielokąta (lub jednego z wielokątów). Użyj narzędzia zapytań przestrzennych, aby wygenerować zaznaczenie wielokątów voronoi, które odnoszą się do tego wielokąta. Dodaj atrybut do wielokąta voroni, który odpowiada wielobokowi będącemu przedmiotem zainteresowania. (Właśnie użyłem 1,2,3,4)
Teraz możesz Wektor-> Narzędzia Geoprocessing-> rozpuścić na podstawie nowego atrybutu.
źródło
Losowe punkty to dobry pomysł, aby wygenerować wielokąt voronoi z wielokątów, działa całkiem dobrze, ale jest całkiem zły dla wielokątów blisko siebie:
ST_ApproximateMedialAxis to kolejna dobra alternatywa, jeśli używa się PostGIS: Obliczanie diagramów Voronoi dla wielokątów
źródło