Uniwersytet Zielonogórski
Projekt zaliczeniowy — GIS w R
# Wczytaj trzy warstwy z GeoPackage (wygenerowane przez R/01_load_spatial.R)
# i od razu zrzutuj na PUWG-1992 (EPSG:2180) — w tym układzie odległości
# i powierzchnie są w metrach.

miasta <- sf::st_read(here::here("data", "processed", "miasta_padel.gpkg"),
                      quiet = TRUE) |>
  sf::st_transform(EPSG_PUWG92)

wojewodztwa <- sf::st_read(here::here("data", "processed", "wojewodztwa.gpkg"),
                           quiet = TRUE) |>
  sf::st_transform(EPSG_PUWG92)

drogi <- sf::st_read(here::here("data", "processed", "drogi.gpkg"),
                    quiet = TRUE) |>
  sf::st_transform(EPSG_PUWG92)

# Granica Polski jako jeden multipoligon (st_union łączy wszystkie 16
# poligonów województw w jeden). Używamy potem do przycinania.
polska <- sf::st_union(wojewodztwa)

# OSM zwraca też odcinki dróg poza granicą kraju — st_intersection
# obcina je do Polski.
drogi <- sf::st_intersection(drogi, polska)
drogi <- drogi[sf::st_geometry_type(drogi) %in% c("LINESTRING", "MULTILINESTRING"), ]

# Upraszczamy geometrię dróg (próg 100 m) — mapa renderuje się szybciej
drogi_simpl <- drogi |>
  sf::st_simplify(dTolerance = 100, preserveTopology = FALSE) |>
  dplyr::group_by(typ) |>
  dplyr::summarise(.groups = "drop")

Kluczowe operacje powyżej: st_read (wczytanie GeoPackage) → st_transform (zmiana układu na PUWG-1992) → st_union (16 województw w 1 granicę Polski) → st_intersection (obcięcie dróg do granic kraju) → st_simplify (mniej wierzchołków = szybszy render).

Streszczenie

Sprawozdanie analizuje przestrzenny rozkład klubów padlowych w Polsce w 2026 roku. W bazie znajduje się 40 klubów w 29 miastach, oferujących łącznie 147 kortów (średnio 3,7 kortu na klub). Analiza pokazuje, że oferta padlowa jest silnie skoncentrowana wokół metropolii — zwłaszcza Warszawy, Krakowa i Trójmiasta — natomiast wschodnie i północne województwa pozostają w znacznej mierze niedoreprezentowane.

Wykorzystaliśmy trzy typy danych przestrzennych (punkty, linie, poligony), agregację atrybutów (aggregate()) oraz tesselację Woronoja (st_voronoi).

1 Wprowadzenie

Padel — sport rakietowy, w którym dwie pary zawodników rozgrywają mecz na zamkniętym korcie ze szklanymi ścianami — w ciągu ostatnich kilku lat przestał być w Polsce egzotyczną ciekawostką. Liczba kortów w Europie podwaja się w cyklu kilkuletnim, a w Polsce pierwsze obiekty komercyjne otwierano dopiero w drugiej dekadzie XXI wieku. Towarzyszy temu charakterystyczny problem nierówności geograficznej — kapitał i operatorzy koncentrują inwestycje w ośrodkach o wysokiej sile nabywczej.

Sprawozdanie pyta:

  1. Gdzie geograficznie znajdują się kluby padlowe w Polsce?
  2. Jak duża część kraju jest blisko jakiegokolwiek klubu?

2 Dane źródłowe — skąd je wzięliśmy i gdzie są zapisane

Tabela 1. Trzy warstwy danych przestrzennych użyte w raporcie.
Warstwa Geometria Liczba obiektów Źródło Plik w projekcie
Miasta z klubami padlowymi punkty 29 ręczna lista miast (CSV) data/processed/miasta_padel.gpkg
Drogi szybkiego ruchu linie 30061 OpenStreetMap (motorway + trunk) data/processed/drogi.gpkg
Województwa poligony 16 GADM 4.1 level 1 data/processed/wojewodztwa.gpkg

Skąd wzięły się dane o klubach (warstwa punktów). Ręcznie zweryfikowaliśmy listę 40 klubów padlowych w 29 polskich miastach (stan na 2026 r.) na podstawie publicznych stron klubów oraz Map Google. Dla każdego miasta zapisaliśmy: liczbę działających klubów, łączną liczbę kortów oraz przybliżone współrzędne geograficzne miasta (centroid). Surowe dane: data/raw/miasta_padel.csv.

Uwaga o precyzji. Punkty na mapach reprezentują miasta, nie konkretne adresy klubów. Dla analizy na skali kraju (1000+ km) jest to wystarczająca precyzja. Dla 5 klubów w Warszawie nie próbujemy ich rozróżnić przestrzennie — sumujemy je w jeden punkt z 27 kortami.

Skąd wzięły się granice województw (warstwa poligonów). Pobrane z bazy GADM 4.1, poziom administracyjny 1 (województwa). Pakiet pobrany w R/01_load_spatial.R, rozpakowany do data/raw/gadm/, przekonwertowany na GeoPackage w data/processed/wojewodztwa.gpkg.

Skąd wzięły się drogi szybkiego ruchu (warstwa linii). Pobrane z OpenStreetMap przez Overpass API za pomocą pakietu osmdata. Pobieramy dwa typy: highway = motorway (autostrady) oraz highway = trunk (drogi ekspresowe). Wynik zapisujemy w data/processed/drogi.gpkg.

Układ współrzędnych. Wszystkie warstwy w data/processed/ są w WGS84 (EPSG:4326). Przy wczytywaniu do raportu od razu przerzucamy je na EPSG:2180 (PUWG-1992) — polski państwowy układ, który zachowuje odległości w metrach na terenie Polski. To pozwala poprawnie liczyć powierzchnie w km².

3 Mapa 1 — Przegląd kraju

Mapa zbiera wszystkie trzy warstwy w jednym widoku: poligony województw jako tło, drogi szybkiego ruchu jako linie, miasta z klubami jako punkty (wielkość punktu odpowiada łącznej liczbie kortów w mieście).

Mapa 1. Miasta z klubami padlowymi (punkty), sieć dróg szybkiego ruchu (linie) i województwa (poligony).

Mapa 1. Miasta z klubami padlowymi (punkty), sieć dróg szybkiego ruchu (linie) i województwa (poligony).

Co widać? Trzy ośrodki dominujące — aglomeracja warszawska, Kraków i Trójmiasto — gromadzą większość kortów w kraju. Wzdłuż osi autostrady A2 (Poznań–Warszawa) widać korytarz inwestycji padlowych. Województwa wschodnie (lubelskie, podkarpackie, podlaskie) oraz zachodniopomorskie i lubuskie mają pojedyncze miasta z klubami.

4 Mapa 2 — Agregacja kortów per województwo

Operacja aggregate() na obiekcie sf sumuje atrybut (liczba_kortow) w obrębie każdego poligonu (wojewodztwa). Wynikiem jest nowy obiekt sf, w którym każde województwo ma policzoną sumę kortów wszystkich miast leżących w jego granicach.

# aggregate.sf() to przestrzenny odpowiednik aggregate() z bazowego R:
# - bierze atrybut "liczba_kortow" z warstwy punktowej (miasta)
# - dla każdego poligonu z warstwy `by` (wojewodztwa) wybiera punkty,
#   które w nim leżą (przestrzenne "group_by")
# - stosuje funkcję agregującą FUN (tu: sum)
# Wynik: nowy obiekt sf z geometrią województw + zsumowaną liczbą kortów.
korty_per_woj <- aggregate(
  miasta["liczba_kortow"],
  by = wojewodztwa,
  FUN = sum,
  na.rm = TRUE
)
# Województwa bez żadnego klubu: aggregate zwraca NA — zamieniamy na 0
korty_per_woj$liczba_kortow[is.na(korty_per_woj$liczba_kortow)] <- 0
# Dorzucamy nazwę województwa (aggregate gubi pozostałe kolumny,
# ale zachowuje kolejność wierszy)
korty_per_woj$wojewodztwo <- wojewodztwa$wojewodztwo

# Liczba miast z klubami na województwo — kolumna `wojewodztwo` jest już
# w danych (dodana przez st_join punkt → poligon przy generacji CSV).
liczba_miast <- miasta |>
  sf::st_drop_geometry() |>
  dplyr::group_by(wojewodztwo) |>
  dplyr::summarise(liczba_miast = dplyr::n(), .groups = "drop")

Kluczowa operacja: aggregate(miasta["liczba_kortow"], by = wojewodztwa, FUN = sum) — dla każdego województwa wybiera punkty (miasta) które w nim leżą i sumuje ich atrybut liczba_kortow. To jest przestrzenna agregacja wymagana przez prowadzącego.

Mapa 2. Łączna liczba kortów padlowych zsumowana w granicach każdego województwa (klasyfikacja Jenksa, 5 klas).

Mapa 2. Łączna liczba kortów padlowych zsumowana w granicach każdego województwa (klasyfikacja Jenksa, 5 klas).

Tabela 2. Liczba miast z klubami padlowymi i suma kortów w województwie.
Województwo Miast z klubami Kortów łącznie
Mazowieckie 4 35
Śląskie 4 18
Pomorskie 4 15
Małopolskie 1 13
Dolnośląskie 1 12
Łódzkie 1 9
Wielkopolskie 1 9
Kujawsko-Pomorskie 2 6
Zachodniopomorskie 2 6
Warmińsko-Mazurskie 2 5
Lubelskie 1 4
Lubuskie 2 4
Podkarpackie 1 3
Podlaskie 1 3
Świętokrzyskie 1 3
Opolskie 1 2

Co widać? Na czele stoi województwo Mazowieckie (35 kortów w 4 miastach), co odzwierciedla skalę aglomeracji warszawskiej. Województwa z 0 kortów to obszary, które nie mają w bazie żadnego klubu padlowego — co potwierdza nierównomierność oferty.

5 Mapa 3 — Tesselacja Woronoja

Diagram Woronoja dzieli kraj na komórki — każdy punkt na mapie należy do tej komórki, której centralny punkt (klub) leży najbliżej. Wielkość komórki to bezpośrednia miara strefy oddziaływania klubu: duża komórka oznacza, że alternatywny klub jest daleko.

# Krok 1: st_voronoi działa na pojedynczej geometrii (jeden MULTIPOINT),
# więc najpierw scalamy 29 osobnych punktów w jeden obiekt.
miasta_mp <- sf::st_union(miasta)

# Krok 2: Właściwa tesselacja — zwraca obiekt typu GEOMETRYCOLLECTION
# zawierający komórki Woronoja jako poligony.
voronoi_raw <- sf::st_voronoi(miasta_mp)

# Krok 3: Wyciągamy z geometrycollection same poligony i opakowujemy
# w obiekt sf (żeby móc je rysować i robić joiny).
voronoi_polys <- sf::st_collection_extract(voronoi_raw, "POLYGON")
voronoi_sf <- sf::st_sf(geom = voronoi_polys, crs = sf::st_crs(miasta))

# Krok 4: Każdej komórce przypisujemy atrybuty miasta, które w niej leży
# (st_contains: dla każdej komórki znajdź punkt-miasto wewnątrz).
voronoi_sf <- sf::st_join(voronoi_sf, miasta, join = sf::st_contains)

# Krok 5: st_voronoi rysuje komórki w nieskończoność (po bbox punktów) —
# obcinamy je do granic Polski przez st_intersection.
voronoi_pl <- sf::st_intersection(voronoi_sf, polska)

# Krok 6: Powierzchnia każdej komórki w km² (st_area w PUWG zwraca m²,
# units::set_units konwertuje na km²).
voronoi_pl$pow_km2 <- as.numeric(
  sf::st_area(voronoi_pl) |> units::set_units("km^2")
)

sr_pow  <- round(mean(voronoi_pl$pow_km2, na.rm = TRUE), 0)
max_pow <- round(max(voronoi_pl$pow_km2, na.rm = TRUE), 0)

Kluczowe operacje: st_union (scal punkty) → st_voronoi (tesselacja) → st_collection_extract (wybierz POLYGON) → st_join (komórka ← miasto) → st_intersection (obetnij do Polski) → st_area + set_units("km^2") (powierzchnia).

Mapa 3. Tesselacja Woronoja — kraj podzielony na rejony najbliższego miasta z klubem padlowym. Kolor odpowiada powierzchni komórki w km².

Mapa 3. Tesselacja Woronoja — kraj podzielony na rejony najbliższego miasta z klubem padlowym. Kolor odpowiada powierzchni komórki w km².

Co widać? Średnia powierzchnia rejonu to 10 765 km², ale największa komórka ma aż 25 213 km² — to pojedyncze miasto obsługujące dużą część Polski wschodniej lub północnej. Duże (ciemne) komórki tworzą charakterystyczny pas od Pomorza Środkowego, przez Warmię i Podlasie, do Lubelszczyzny i Bieszczad. Małe komórki w okolicach Warszawy, Krakowa i Trójmiasta odpowiadają wysycaniu rynku w aglomeracjach.

6 Synteza i wnioski

  1. Koncentracja w aglomeracjach. Trzy województwa (Mazowieckie, Śląskie, Pomorskie) gromadzą 46% wszystkich kortów w kraju.

  2. Padel-pustynie. Tesselacja Woronoja pokazuje regiony, w których pojedyncze miasto obsługuje obszar znacznie większy niż średni (10 765 km²) — Warmia, Podlasie, Bieszczady.

  3. Korytarze inwestycyjne. Mapa 1 ujawnia, że miasta z klubami padlowymi układają się wzdłuż głównych autostrad (A2, A4) — co sugeruje, że operatorzy lokalizują kluby tam, gdzie jest infrastruktura transportowa obsługująca największą bazę klientów.

7 Bibliografia i źródła danych