Mam dane punktów wzdłuż ulic, chciałbym zamienić te kropki w proste kolorowe linie. Wszelkie wskazówki, jak można nazwać ten problem lub algorytmy, które mogą mi pomóc w rozwiązaniu tego problemu?
Miałem nadzieję, że użyję do tego PostGIS
funkcji, ale jestem otwarty na sugestie, to dane z .shp
pliku.
Edycja1: Zaktualizowano obraz, aby zademonstrować idealne rozwiązanie tego problemu.
Narysowanie linii byłoby oparte wyłącznie na odległości między tymi punktami, nic więcej nie mogę użyć do ich grupowania. Idealnie byłyby to punkty w maksymalnej określonej odległości wzdłuż rzutowanej linii? I przez rzutowaną linię mam na myśli znaleźć pierwszy punkt, a następnie następny najbliższy, a następnie rzutować linię i sprawdzić, czy są jakieś punkty na tej linii w maksymalnej odległości od któregokolwiek z tych już na linii.
Odpowiedzi:
W pobliżu
Możesz użyć zapytania rekurencyjnego, aby zbadać najbliższego sąsiada każdego punktu, zaczynając od każdego wykrytego końca linii, które chcesz zbudować.
Wymagania wstępne : przygotuj warstwę Postgis ze swoimi punktami, a drugą za pomocą jednego obiektu z wieloma liniami zawierającymi Twoje drogi. Dwie warstwy muszą znajdować się na tym samym CRS. Oto kod zestawu danych testowych, który utworzyłem, zmodyfikuj go w razie potrzeby. (Testowane na postgres 9.2 i postgis 2.1)
Oto kroki :
Wygeneruj dla każdego punktu listę wszystkich sąsiadów i ich odległości spełniających te trzy kryteria.
Odległość nie może przekraczać zdefiniowanego przez użytkownika stosunku odległości od najbliższego sąsiada (powinno to lepiej uwzględniać digitalizację nieregularną niż stała odległość)Ta część była zbyt trudna do wdrożenia, przyklejona do ustalonego promienia wyszukiwaniaNazwijmy tę tabelę „wykresem”
Wybierz punkt końca linii, łącząc się z wykresem i zachowując tylko punkt, który ma dokładnie jedną pozycję na wykresie.
Nazwijmy tę tabelę „eol” (koniec linii)
łatwym? że nagroda za wykonanie świetnego wykresu, ale trzymanie się rzeczy oszaleje w następnym kroku
Skonfiguruj zapytanie rekurencyjne, które będzie przełączać się między sąsiadami, zaczynając od każdego eol
Nazwijmy tę tabelę „recurse_eol”
Zachowaj tylko najdłuższą linię dla każdego punktu początkowego i usuń każdą dokładnie zduplikowaną ścieżkę Przykład: ścieżki 1,2,3,5 I 5,3,2,1 to ta sama linia odkryta przez dwie różne „końcówkę linii”
Ręcznie sprawdza pozostałe błędy (pojedyncze punkty, nakładające się linie, dziwnie ukształtowana ulica)
Zaktualizowany zgodnie z obietnicą, wciąż nie mogę zrozumieć, dlaczego czasami zapytanie rekurencyjne nie daje dokładnie tego samego wyniku, gdy zaczynasz od przeciwnego eol tego samego wiersza, więc niektóre duplikaty mogą na razie pozostać w warstwie wyników.
Nie wahaj się zapytać. Całkowicie rozumiem, że ten kod wymaga więcej komentarzy. Oto pełne zapytanie:
źródło
Jak wskazuje @FelixIP, pierwszym krokiem jest znalezienie punktów, które utworzą każdą linię. Możesz to zrobić, wywołując ST_ClusterWithin z maksymalną odległością separacji:
Następnie musisz użyć heurystyki, aby zbudować linię przechodzącą przez wszystkie punkty w każdym klastrze. Na przykład, jeśli możesz założyć, że żądane linie są monotoniczne Y, możesz posortować punkty w każdym klastrze i wprowadzić je do ST_MakeLine . Łącząc to wszystko razem wyglądałoby to tak:
źródło