Chciałbym opowiedzieć Wam historię o tym, jak o mały włos kilka rodzin nie zdołałoby wybudować swoich wymarzonych domów. Ale czy na pewno kilka rodzin...?
To była bardzo ciepła sierpniowa sobota 2024 roku, gdzieś w spokojnych wybudowaniach wsi. Zygmunt od rana czuł jakiś dziwny niepokój, który potęgował się, gdy spoglądał na swoje ukochane wnuczęta. Tak, jakby im coś groziło. Kładł się na kanapie do popołudniowej drzemki. Dzieciaki ganiały w ogrodzie. Przymknął oczy a odgłosy ich zabawy zaczęły milknąć… Jednak ciszę przerwał jazgot wibrującego telefonu.
– Dzień dobry. Pan Zygmunt?
– Tomek? – odpowiedział niepewnie straszy mężczyzna.
– Za dwa lata się pan już nie wybuduje na tej działce.
– Ale jak? – zapytał przestraszonym głosem.
– Niech pan słucha. Jest szansa! Słyszy Pan?! Wtyczka używa źle sparametryzowanych algorytmów do aproksymacji łuków bufora! Musimy działać!
– Dzwoń po Kubę! Spotkajmy się natychmiast tam, gdzie zawsze. – zaordynował Zygmunt.
– Jesteśmy już w drodze…
***
Przygotowując narzędzia wspierające tworzenie planu ogólnego gminy, porównałem wyniki generowania Obszaru Uzupełnienia Zabudowy (OUZ) moim skryptem, z algorytmem zastosowanym we wtyczce APP 2. Zdziwiły mnie dość duże rozbieżności w liczbie obiektów. Nie w ich powierzchni, kształcie itp., ale w samej liczbie. Każdy, kto rozumie, że walka o możliwość zabudowy będzie się toczyć w sądach o Pawlakowe „trzy palce”, wie, że historia pana Zygmunta wcale nie jest żartem. W kontekście odpowiedzialności wobec klientów, znikanie OUZ było bardzo niepokojące (delikatnie mówiąc). Niestety, sprawa nie jest błaha…
Zacznijmy od rysunku, który jest wynikiem działania mojego algorytmu.
Jasny zielony – bufor 50m wokół „zgrupowania” budynków (wszystkie z właściwym numerem KST), w którym „obrys każdego z budynków w zgrupowaniu znajduje się w odległości nie większej niż 100 m od obrysu co najmniej jednego innego budynku w zgrupowaniu”. Odległość pomiędzy wskazanymi budynkami to 99,66 m. Na powiększeniu (B) widać, że poligon wygenerowany od budynków jest jeden, połączony. Wracając na rysunek (A) widzimy, że jest w nim pięć budynków (wszystkie z właściwym numerem KST). Ciemny zielony – mój OUZ końcowy, powstały po „cofnięciu” bufora o 40m. Rozczłonkowany, ale pamiętajmy, że warunek pięciu budynków dotyczy zgrupowania wyjściowego, z którego rozpoczyna działanie algorytm.
Więc o co chodzi? Otóż według wtyczki nikt się jednak na tym terenie się nie wybuduje, ponieważ nie ma tam żadnego OUZ.
Dlaczego? Wtyczka do generowania bufora używa funkcji QGIS native:buffer z parametrem 5 segmentów, w której aproksymacja zasięgu bufora nie spełnia założenia, że „dwa bufory 50 m od dwóch ścian budynków, które to ściany są odległe o 100 metrów, będą miały część wspólną lub wspólną krawędź” (tak jak te połączone na rysunku B).
# bufor wokół budynków z rozpuszczeniem granic
bufory = processing.run("native:buffer", {
'INPUT': warstwaZBudynkami,
'DISTANCE':50,
'SEGMENTS':5,
'DISSOLVE': True,
'MITER_LIMIT': 2,
'OUTPUT': 'memory:'
W moim skrypcie, gdzie wykorzystałem metodę Pythona geometry.buffer z tym samym parametrem 10 segmentów, udało się znaleźć taką część wspólną dla buforów budynków w odległych o 99,66 m. Ale to również mogło być przypadkowe przy odpowiedniej konfiguracji topologii budynków. Choć nie jestem pewien tej przypadkowości. Nie analizowałem jeszcze matematyki buforowania w bibliotece Pythona. (edit 23.10: metody dają te same rezultaty przy tej samej wartości parametru liczby segmentów).
# Tworzymy bufor 50m wokół zgrupowań i scalamy je (dissolve)
all_buffers = []
for feature in grouped_buildings_layer.getFeatures():
geometry = feature.geometry()
if geometry.isGeosValid():
buffer_geom = geometry.buffer(50, 10) # Bufor z 10 segmentami
if buffer_geom and buffer_geom.isGeosValid():
all_buffers.append(buffer_geom)
Jak to zauważyłem? Jest dość powszechną wiedzą, że aproksymacja odległości buforowania może się mocno różnić, w zależności od parametrów i funkcji generujących. Dlatego zgrupowania budynków określałem metodą grafu, licząc po kolei odległości między budynkami i dołączając do zgrupowania te, które leżą w odległości nie większej niż 100 m. Po tej operacji zauważyłem, że istnieją zgrupowania, które nie mają poligonu OUZ generowanego przez wtyczkę.
We wtyczce przyjęto inne założenie. Z potencjalnego OUZ usuwa się te poligony powstałe z 50m buforów budynków, które nie miały wewnątrz pięciu budynków. Zatem jeśli tak jak w przykładzie, bufory od budynków odległych mniej niż 100m od siebie przynajmniej się nie stykały wskutek słabej aproksymacji łuków, pozostały rozdzielone i budynki w nich liczone są osobno, pomimo faktu, że w rzeczywistości spełniały rozporządzeniowy warunek zgrupowania.
W tym konkretnym akurat przypadku aproksymacja każdym z algorytmów z parametrem 10 segmentów daje mocno zbliżone i poprawne wyniki tj. OUZ zostaje wygenerowany.
Zakres analizowanego obszaru w GPKG
Dane budynków niestety pochodzą z GML na licencji, zatem nie udostępniam. WFS z PODGiK nie sprawdzałem. Pamiętajmy, że to tylko przykład.
***
Siedzieli razem nad krawędzią doliny. Gotowe do nocy hamaki lekko bujały się na spokojnym, wieczornym wietrze. Patrzyli w ciszy na leniwie płynącą rzekę. Wiedzieli, że w kilku nowych domach, oddalonych zaledwie o parę kilometrów stąd, wkrótce zabłyśnie światło na gankach. Przeczuwali, że kiedy spotkają ich mieszkańców, swoich nowych sąsiadów i o tym wszystkim opowiedzą, to nikt nie uwierzy, jak niewiele brakowało…