Usiłuję utworzyć wielokąty voronoi w QGIS, które uwzględniają „dziury” w domenie ogólnej. Przykładem może być:
W rzeczywistości stworzyłem Voronoi na tym obrazie za pomocą QGIS za pomocą polecenia GRASS, a następnie za pomocą narzędzia „Różnica”, aby utworzyć dziury. Oddzielny wielokątny plik kształtu, który zawiera zakres otworów, został użyty jako warstwa „Różnica”. Przykładową aplikacją byłoby tworzenie wielokątów wokół punktów próbkowania, które zostały zebrane między strukturami, które należy wykluczyć z analizy.
Pojawiają się tutaj dwa problemy:
Funkcja „różnicy” nie działa w 100% poprawnie, a niektóre granice wielokątów rozciągają się na „dziury”. Można to naprawić, znajdując wiersz w tabeli atrybutów, który nie ma numeru identyfikacyjnego wielokąta (lub identyfikatora „0”).
Ten rodzaj „dziurkowania” po fakcie może skutkować nieciągłymi wielokątami, jak pokazuje czerwona strzałka na obrazie.
Moje pytanie brzmi: czy istnieje narzędzie lub wtyczka Voronoi, które mogą uznać obecność „dziur” w środku domeny za proces jednoetapowy, a także wyeliminować generowanie nieciągłych wielokątów? Wyobrażam sobie, że takie narzędzie przedłużyłoby granicę wielokąta do najbliższego przecięcia z inną granicą, chyba że ta inna granica najpierw uderzy o granicę „dziury”.
źródło
Odpowiedzi:
Może to być możliwe przy użyciu rastrów. Najpierw przekonwertuj punkty i wielokąty graniczne na raster wysokiej rozdzielczości. Ustaw maskę dla swoich granic za pomocą
r.mask
. Następnie uruchomr.grow.distance
GRASS i użyjValue= output
. To da ci za każdy piksel, który jest najbliższym punktem. Przekształć to z powrotem w wielokąty wektorowe. Konieczne mogą być dodatkowe kroki, aby pozbyć się wielokątów taśmy.źródło
Jest to z pewnością możliwe w przypadku rastrów.
Mam nadzieję, że ten zrzut ekranu lepiej pokazuje problem. Część B voronoi jest bliżej „w linii prostej” od oryginalnego centrum voronoi, ale nie bierze to pod uwagę faktu, że obejście budynku zajęłoby więcej czasu. Rozumiem pytanie PO, że voronoi muszą wziąć pod uwagę tę dodatkową odległość, aby obejść budynek.
Podoba mi się sugestia @ Guillaume. Jednak gdy spróbowałem, miałem problemy
r.grow.distance
z uhonorowaniem maski (patrz poniżej. Fale nie powinny przechodzić przez budynki).Moja wiedza na temat Trawy nie jest tak silna, jak mogłaby być, więc może robię coś głupiego. Zdecydowanie sprawdź najpierw tę sugestię, ponieważ będzie to o wiele mniej pracy niż moja ;-)
Krok 1 - Utwórz powierzchnię kosztów
Pierwszym krokiem jest stworzenie powierzchni kosztowej. Tę czynność należy wykonać tylko raz.
użyj kalkulatora rastrowego, aby przekształcić go w powierzchnię kosztów. Ustawię „na zewnątrz” na 1, a „wewnątrz” na 9999. To sprawi, że poruszanie się po budynkach będzie wyjątkowo trudne.
((„mask @ 1” = 1) * 1) + ((„mask @ 1” = 0) * 9999)
Możesz uzyskać więcej „organicznych” wyników, dodając trochę szumu do powierzchni kosztów (np. Użyj losowej liczby od 1 do 3, a nie tylko 1 dla pikseli zewnętrznych).
Krok 2. Utwórz skumulowane rastry kosztów dla każdego centrum Voronoi
Teraz możemy uruchomić (dla jednej komórki voronoi na raz) algorytm GRASS
r.cost.coordinates
względem naszej warstwy powierzchni kosztowej.Jako współrzędną początkową użyj centrum Vornoi. Jako współrzędną końcową wybierz jeden z rogów swojego obszaru. Sugeruję użycie „Knights Tour”, ponieważ daje to płynniejsze wyniki.
Wynik pokazuje linie równego czasu podróży z jednego centrum voronoi. Zwróć uwagę, jak opaski owijają się wokół budynków.
Nie wiem, jak najlepiej to zautomatyzować. Może przetwarzanie w trybie wsadowym lub w pyqgis.
Krok 3. Scal rastry
Prawdopodobnie będzie to wymagać kodu. Algorytm byłby
Takie podejście powinno dać raster, w którym każda komórka jest podzielona na kategorie według najbliższego centrum voronoi, biorąc pod uwagę przeszkody.
Następnie możesz użyć rastra do wielokąta. Następnie możesz użyć wtyczki Uogólnij, aby usunąć artefakty efektu „kroku” z rastra.
Przepraszamy za niejasność za kroki 2 i 3 ... Mam nadzieję, że ktoś wpadnie na bardziej eleganckie rozwiązanie :)
źródło
Uwaga 1 : Nie byłem w stanie odtworzyć proponowanego problemu, ponieważ narzędzie Różnica działało dla mnie dobrze w kilku testach, które przeprowadziłem (być może było to spowodowane prostą geometrią problemu lub dlatego, że narzędzie zostało ulepszone od czasu pytania zapytał 1 rok temu).
Proponuję jednak obejście w PyQGIS, aby uniknąć użycia narzędzia Różnica . Wszystko opiera się na lokalnym przecięciu dwóch warstw wejściowych (patrz rysunek poniżej):
Uwaga 2 : Ponieważ nie chcę używać narzędzia Różnica , nie jestem w stanie uniknąć tworzenia „taśm” (patrz wtedy), więc musiałem uruchomić to
v.clean
narzędzie, aby je wyeliminować. Ponadto, jak powiedział @Chris W,Po tych niezbędnych przesłaniach umieszczam kod:
co prowadzi do tego wyniku:
Dla jasności byłby to wynik bez użycia
v.clean
narzędzia:Różnica w stosunku do wyniku @LeaningCactus polega na tym, że do tej pory geometrie nie są zepsute i można je „wyczyścić” bez błędów .
źródło