Biorąc pod uwagę dużą (~ 1 milion) próbkę nierównomiernie rozmieszczonych punktów - czy można wygenerować nieregularną siatkę (pod względem wielkości, ale może również mieć nieregularny kształt, jeśli to możliwe?), Która będzie zawierać określoną minimalną ilość n punktów?
Dla mnie nie ma większego znaczenia, jeśli generetowane „komórki” takiej siatki zawierają dokładnie n liczby punktów lub co najmniej n punktów.
Jestem świadomy rozwiązań takich jak genvecgrid w ArcGIS lub Create Grid Layer w QGIS / mmgis, jednak wszystkie one utworzą regularne siatki, które skutkują wyjściem z pustymi komórkami (mniejszy problem - mógłbym je po prostu odrzucić) lub komórkami z liczbą punktów mniej niż n (większy problem, ponieważ potrzebuję rozwiązania do agregacji tych komórek, prawdopodobnie przy użyciu niektórych narzędzi stąd ?).
Googling bezskutecznie i jestem otwarty na rozwiązania komercyjne (ArcGIS i rozszerzenia) lub bezpłatne (Python, PostGIS, R).
źródło
Odpowiedzi:
Widzę MerseyViking zaleciła QuadTree . Chciałem zasugerować to samo i aby to wyjaśnić, oto kod i przykład. Kod jest zapisany,
R
ale powinien być łatwy do przeniesienia, powiedzmy, do Pythona.Pomysł jest niezwykle prosty: podziel punkty w przybliżeniu na pół w kierunku x, a następnie rekurencyjnie podziel dwie połówki wzdłuż kierunku y, zmieniając kierunki na każdym poziomie, aż nie będzie już konieczne dzielenie.
Ponieważ celem jest ukrycie rzeczywistych lokalizacji punktów, przydatne jest wprowadzenie losowości do podziałów . Jednym szybkim i prostym sposobem na dokonanie tego jest podzielenie na zestaw kwantyli małej losowej kwoty od 50%. W ten sposób (a) jest mało prawdopodobne, aby wartości podziału były zbieżne ze współrzędnymi danych, tak że punkty będą jednoznacznie wpadać do kwadrantów utworzonych przez podział, oraz (b) współrzędnych punktów nie będzie można dokładnie odtworzyć z kwadratu.
Ponieważ intencją jest utrzymanie minimalnej
k
liczby węzłów w każdym liściu czterokąta, implementujemy ograniczoną formę czterokąta. Będzie obsługiwał (1) punkty grupowania w grupy posiadające pomiędzyk
i 2 *k
-1 każdy element oraz (2) mapowanie kwadrantów.Ten
R
kod tworzy drzewo węzłów i liści końcowych, rozróżniając je według klasy. Etykietowanie klas przyspiesza przetwarzanie końcowe, takie jak drukowanie, przedstawione poniżej. Kod używa wartości liczbowych dla identyfikatorów. Działa to do głębokości 52 w drzewie (przy użyciu podwójnych; jeśli używane są długie liczby całkowite bez znaku, maksymalna głębokość wynosi 32). W przypadku głębszych drzew (które są bardzo mało prawdopodobne w żadnej aplikacji, ponieważ w grę wchodzą co najmniejk
* 2 ^ 52 punkty), identyfikatory musiałyby być łańcuchami.Należy zauważyć, że rekurencyjna konstrukcja tego algorytmu typu „dziel i rządź” (i w konsekwencji większość algorytmów przetwarzania końcowego) oznacza, że wymagany czas to O (m), a użycie pamięci RAM to O (n), gdzie
m
jest liczba komórki in
jest liczbą punktów.m
jest proporcjonalne don
podzielonej przez minimalną punktów na komórkę,k
. Jest to przydatne do szacowania czasów obliczeń. Na przykład, jeśli podzielenie n = 10 ^ 6 punktów na komórki 50-99 punktów (k = 50) zajmuje 13 sekund, m = 10 ^ 6/50 = 20000. Jeśli zamiast tego chcesz podzielić na 5-9 punktów na komórkę (k = 5), m jest 10 razy większy, więc czas wzrasta do około 130 sekund. (Ponieważ proces dzielenia zestawu współrzędnych wokół ich środków przyspiesza, gdy komórki stają się mniejsze, faktyczny czas wyniósł zaledwie 90 sekund.) Aby przejść do k = 1 punkt na komórkę, zajmie to około sześć razy dłużej jeszcze dziewięć minut i możemy spodziewać się, że kod będzie trochę szybszy.Zanim przejdziemy dalej, wygenerujmy interesujące dane o nieregularnych odstępach i stwórzmy ograniczony quadree (czas, który upłynął 0,29 sekundy):
Oto kod do tworzenia tych wykresów. Wykorzystuje
R
polimorfizm:points.quadtree
będzie wywoływany za każdym razem, gdypoints
funkcja zostanie zastosowana na przykład doquadtree
obiektu. Siła tego jest widoczna w ekstremalnej prostocie funkcji pokolorowania punktów zgodnie z ich identyfikatorem skupienia:Wykreślenie samej siatki jest nieco trudniejsze, ponieważ wymaga wielokrotnego przycinania progów użytych do partycjonowania quadtree, ale to samo rekurencyjne podejście jest proste i eleganckie. W razie potrzeby użyj wariantu, aby zbudować wielokątne reprezentacje ćwiartek.
Jako inny przykład wygenerowałem 1 000 000 punktów i podzieliłem je na grupy po 5-9 sztuk. Czas wyniósł 91,7 sekundy.
Jako przykład interakcji z GIS , wypiszmy wszystkie komórki z czterema drzewami jako plik kształtu wielokąta za pomocą
shapefiles
biblioteki. Kod emuluje procedury obcinanialines.quadtree
, ale tym razem musi wygenerować opisy wektorowe komórek. Są one wyprowadzane jako ramki danych do użytku zshapefiles
biblioteką.Same punkty można odczytać bezpośrednio, używając
read.shp
lub importując plik danych o współrzędnych (x, y).Przykład zastosowania:
(Użyj tutaj dowolnego pożądanego zasięgu, aby
xylim
przejść do podregionu lub rozszerzyć mapowanie na większy region; ten kod domyślnie określa zakres punktów).Już samo to wystarczy: przestrzenne połączenie tych wielokątów z pierwotnymi punktami zidentyfikuje skupiska. Po zidentyfikowaniu operacje „podsumowania” w bazie danych wygenerują statystyki podsumowujące punkty w każdej komórce.
źródło
shapefiles
pakietu lub możesz eksportować współrzędne (x, y) w tekście ASCII i czytać je za pomocąread.table
. (2) Zalecam zapisanieqt
w dwóch formach: po pierwsze, jako punktowy plik kształtu, wxy
którymid
pola są zawarte jako identyfikatory klastrów; po drugie, gdzie narysowane segmenty liniilines.quadtree
są zapisywane jako plik kształtu polilinii (lub gdzie analogiczne przetwarzanie zapisuje komórki jako plik kształtu wieloboku). Jest to tak proste, jak modyfikowanielines.quadtree.leaf
danych wyjściowychxylim
jako prostokąta. (Zobacz zmiany.)quad
: (1) zainicjujid=1
; (2) zmianaid/2
naid*2
wlower=
linii; (3) wprowadź podobną zmianę jakid*2+1
wupper=
wierszu. (Przeredaguję moją odpowiedź, aby to odzwierciedlić.) To powinno również zadbać o obliczenie obszaru: w zależności od Twojego GIS wszystkie obszary będą dodatnie lub wszystkie będą ujemne. Jeśli wszystkie są negatywne, odwróć listy dlax
iy
wcell.quadtree.leaf
.Sprawdź, czy ten algorytm zapewnia wystarczającą anonimowość dla próbki danych:
Na przykład, jeśli minimalny próg wynosi 3:
źródło
Podobnie jak w przypadku interesującego rozwiązania Paulo, co powiesz na zastosowanie algorytmu podziału drzewa quad?
Ustaw głębokość, na którą ma iść quadtree. Możesz również mieć minimalną lub maksymalną liczbę punktów na komórkę, aby niektóre węzły były głębsze / mniejsze niż inne.
Podziel swój świat, odrzucając puste węzły. Opłucz i powtarzaj, aż kryteria zostaną spełnione.
źródło
Innym podejściem jest utworzenie bardzo drobnej siatki i użycie algorytmu max-p. http://pysal.readthedocs.org/en/v1.7/library/region/maxp.html
źródło