Interesuje mnie zbadanie średniej szerokości wielokąta reprezentującego powierzchnię drogi. Mam również linię środkową drogi jako wektor (która czasami nie jest dokładnie w środku). W tym przykładzie linia środkowa drogi jest czerwona, a wielokąt jest niebieski:
Jednym z podejść brutalnej siły, o którym myślałem, jest buforowanie linii małymi przyrostami, przecięcie bufora siatką kabaretki, przecięcie wielokąta drogowego siatką kabaretki, obliczenie przecinanego obszaru dla obu środków skrzyżowania i kontynuowanie tego aż do błąd jest niewielki. Jest to jednak prymitywne podejście i zastanawiam się, czy istnieje bardziej eleganckie rozwiązanie. Ponadto ukrywałoby to szerokość dużej drogi i małej drogi.
Interesuje mnie rozwiązanie wykorzystujące oprogramowanie ArcGIS 10, PostGIS 2.0 lub QGIS. Widziałem to pytanie i pobrałem narzędzie Dana Pattersona do ArcGIS10, ale nie byłem w stanie obliczyć, czego chcę.
Właśnie odkryłem narzędzie Minimalnej ograniczającej geometrii w ArcGIS 10, które pozwala mi produkować następujące zielone wielokąty:
To wydaje się być dobrym rozwiązaniem dla dróg, które biegną wzdłuż siatki, ale inaczej by nie działały, więc nadal jestem zainteresowany innymi sugestiami.
Odpowiedzi:
Częścią problemu jest znalezienie odpowiedniej definicji „średniej szerokości”. Niektóre są naturalne, ale będą się różnić, przynajmniej nieznacznie. Dla uproszczenia rozważ definicje oparte na właściwościach łatwych do obliczenia (co wykluczy te oparte na przykład na transformacji osi środkowej lub sekwencjach buforów).
Jako przykład weźmy pod uwagę, że archetypowa intuicja wielokąta o określonej „szerokości” jest małym buforem (powiedzmy o promieniu rz kwadratowymi końcami) wokół długiej, dość prostej polilinii (powiedzmy o długości L ). Myślimy o 2r = w jako jego szerokości. A zatem:
Jego obwód P jest w przybliżeniu równy 2L + 2w;
Jego powierzchnia A jest w przybliżeniu równa w L.
Szerokość w i długość L można następnie odzyskać jako pierwiastki kwadratowe x ^ 2 - (P / 2) x + A; w szczególności możemy oszacować
Gdy masz pewność, że wielokąt jest naprawdę długi i chudy, dla dalszego przybliżenia możesz wziąć 2L + 2 w, aby równać się 2L, skąd
Błąd względny w tym przybliżeniu jest proporcjonalny do w / L: im chudszy wielokąt, tym bliżej w / L jest do zera, i tym lepsze jest przybliżenie.
Podejście to jest nie tylko niezwykle proste (wystarczy podzielić obszar przez obwód i pomnożyć przez 2), przy dowolnej formule nie ma znaczenia, w jaki sposób wielokąt jest zorientowany lub gdzie się znajduje (ponieważ takie ruchy euklidesowe nie zmieniają ani obszaru, ani obwód).
Możesz rozważyć użycie jednej z tych formuł w celu oszacowania średniej szerokości dowolnych wielokątów reprezentujących segmenty ulic. Błąd popełniany w pierwotnym oszacowaniu w (z formułą kwadratową) pojawia się, ponieważ obszar A zawiera również małe kliny na każdym zagięciu oryginalnej polilinii. Jeśli suma kątów zgięcia wynosi t radianów (jest to całkowita bezwzględna krzywizna polilinii), wtedy naprawdę
P = 2L + 2w + 2 Pi tw i
A = L w + Pi tw ^ 2.
Podłącz je do poprzedniego rozwiązania (formuła kwadratowa) i uprość. Kiedy dym zniknie, zniknął wkład z terminu t krzywizny ! To, co pierwotnie wyglądało na przybliżenie, jest idealnie dokładne dla nie przecinających się buforów polilinii (z kwadratowymi końcami). W przypadku wielokątów o zmiennej szerokości jest to rozsądna definicja średniej szerokości.
źródło
Tutaj pokazuję małą optymalizację dotyczącą rozwiązania @whuber i mówię o „szerokości bufora”, ponieważ jest to przydatne do zintegrowania rozwiązania bardziej ogólnego problemu: czy istnieje funkcja odwrotna st_buffer, która zwraca oszacowanie szerokości?
W tym problem, @celenius pytanie o szerokości ulicy ,
sw
rozwiązanie jestgdzie
sw
jest „średnia szerokość”,g1
środkowa liniag2
, a ulicag2
to POLYGON . Użyłem tylko standardowej biblioteki OGC, przetestowałem z PostGIS i rozwiązałem inne poważne praktyczne aplikacje z tą samą funkcją bufor_width.DEMONSTRACJA
A2
Jest to obszarg2
,L1
długość osi środkowej (g1
I)g2
.Przypuśćmy, że możemy wygenerować
g2
przezg2=ST_Buffer(g1,w)
, i żeg1
jest prosty, więcg2
jest prostokątem o długościL1
i szerokości2*w
, aNie jest to ta sama formuła @whuber, ponieważ tutaj
w
jest połowag2
szerokości prostokąta ( ). Jest to dobry estymator, ale jak widzimy w testach (poniżej), nie jest dokładny, a funkcja wykorzystuje go jako wskazówkę, aby zmniejszyćg2
obszar i jako ostateczny estymator.W tym przypadku nie oceniamy buforów za pomocą „endcap = kwadrat” lub „endcap = okrągły”, które potrzebują sumy do
A2
obszaru bufora punktowego o tym samymw
.ODNIESIENIA: na podobnym forum w 2005 r. W. Huber wyjaśnia podobne i inne rozwiązania.
TESTY I POWODY
W przypadku linii prostych wyniki, zgodnie z oczekiwaniami, są dokładne. Ale w przypadku innych geometrii wyniki mogą być rozczarowujące. Być może głównym powodem jest to, że cały model dotyczy dokładnych prostokątów lub geometrii, które można przybliżyć do „prostokąta paska”. Oto „zestaw testowy” do sprawdzenia granic tego przybliżenia (patrz
wfactor
wyniki powyżej).WYNIKI:
Z PROSTOKĄTAMI (linia środkowa to PROSTA LINIA):
Z INNYMI GEOMETRIAMI (linia środkowa złożona):
O tym
btype
patrz przewodnik ST_Buffer z dobrymi ilustracjami i zastosowanymi tutaj LINESTRINGAMI.WNIOSKI :
w_estim
jest zawsze lepszy niżw_near
;g2
geometrii „zbliżonych do prostokątnych” , jest w porządku, dowolnawfactor
wfactor=~0.01
1% błędu naw_estim
. Do tego współczynnika użyj innego estymatora.Ostrożność i zapobieganie
Dlaczego występuje błąd oszacowania? Kiedy używasz
ST_Buffer(g,w)
, spodziewasz się, według „modelu paska prostokątnego”, że nowy obszar dodany przez bufor szerokościw
wynosi okołow*ST_Length(g)
lubw*ST_Perimeter(g)
… Kiedy nie, zwykle przez nakładki (patrz linie zagięte) lub „stylizację”, kiedy oszacowanie średniejw
usterki . To jest główne przesłanie testów.Aby wykryć ten problem w dowolnym królu bufora , sprawdź zachowanie generowania bufora:
WYNIKI:
źródło
Jeśli możesz połączyć dane wielokąta z danymi linii środkowej (przestrzennie lub tabelarycznie), po prostu zsumuj obszary wielokątów dla każdego wyrównania linii środkowej i podziel przez długość linii środkowej.
źródło
Opracowałem wzór na średnią szerokość wielokąta i umieściłem go w funkcji Python / ArcPy. Moja formuła wywodzi się z (ale w znacznym stopniu rozszerza) najprostszego pojęcia średniej szerokości, które widziałem omówione gdzie indziej; to znaczy średnica koła mającego taki sam obszar jak twój wielokąt. Jednak w powyższym pytaniu i moim projekcie bardziej interesowała mnie szerokość najwęższej osi. Ponadto interesowała mnie średnia szerokość dla potencjalnie złożonych, niewypukłych kształtów.
Moim rozwiązaniem było:
To jest:
Funkcja to:
Oto wyeksportowana mapa ze średnią szerokością (i kilkoma innymi atrybutami geometrii dla odniesienia) w różnych kształtach przy użyciu funkcji z góry:
źródło
area / perimeter * 4
.Inne rozwiązanie z przybliżoną osią środkową:
Wynik z pewnością będzie zły dla tych wielokątów, w których przybliżona oś środkowa nie jest pojedynczą linią ciągłą, więc możesz to sprawdzić przed krokiem 1 i wrócić
NULL
lub coś w tym rodzaju.Oto przykład funkcji PostgreSQL (uwaga: musisz zainstalować rozszerzenia Postgis i Postgis_sfcgal ):
Niekorzyść:
To rozwiązanie nie będzie działać w przypadkach, gdy wielokąt jest prawie prostokątny, a człowiek może intuicyjnie zdefiniować jego długość, ale przybliżona oś środkowa ma małe rozgałęzienia w pobliżu krawędzi, a zatem algorytm zwraca Brak.
Przykład:
źródło