Kaartjes maken met Open Data

R
Voor een onderzoek naar de aanpak van afvalgerelateerde overlast heb ik gebruik gemaakt van meerdere gemeentelijke open databronnen om kaartje te maken. In deze post leg ik uit hoe ik dat gedaan heb.
Publicatiedatum

22 september 2019

De gemeente Den Haag publiceert steeds meer open data. Voor mijn werk als onderzoeker bij de Rekenkamer Den Haag heb ik voor een onderzoek naar de aanpak van afvalgerelateerde overlast gebruik gemaakt van meerdere gemeentelijke open databronnen om bijvoorbeeld onderstaand kaartje te maken, waar het aantal meldingen van bijplaatsingen op een kaart van de stadsdelen Centrum en Segbroek zijn geplot.

In dit blog leg ik uit hoe ik dat gedaan heb.

Gebruikte bronnen

Ik ben niet het grootste programmeer- en R-talent, dus ik ben altijd op zoek naar goede voorbeelden en interessante bronnen. Ik heb van de volgende openbare bronnen gebruik gemaakt om deze afbeelding te genereren:

Gebruikte packages

De volgende packages zijn nodig om de kaart te kunnen genereren:

library(tidyverse)  # Om te kunnen filteren
library(lubridate)  # Om op datums te kunnen filteren
library(sf)         # Om de kaarten te maken

Gebruikte databestanden

Om de afbeelding te maken heb ik de volgende databestanden van het open data platform van de gemeente Den Haag gebruikt, die ik in een projectmap Data heb geplaatst:

Inlezen data

Met de volgende code heb ik de verschillende databestanden ingelezen:

# Inlezen meldingenregister
meldingen <- read_sf('https://ckan.dataplatform.nl/dataset/04a332fd-b38f-4716-9811-7e15fb32bd40/resource/43abc627-f718-44c3-98bf-dcc14e06d92a/download/meldingen.json')

# Inlezen stadsdelen
stadsdelen <- read_sf('https://ckan.dataplatform.nl/dataset/3a7494a8-87dc-403c-bf4e-bdd4fac6242d/resource/3de9bdcb-c949-4440-a731-f5238aaa089c/download/stadsdelen.json')

# Inlezen wijken
wijken <- read_sf('https://ckan.dataplatform.nl/dataset/c1059cef-be66-4a7a-9657-2f38f55794ed/resource/a175afe5-67e2-4e45-8b71-62f30377bf7d/download/wijken.json')

# Inlezen restafvalcontainers
restcontainers <- read_sf('https://ckan.dataplatform.nl/dataset/be4068d0-573b-4d24-86ff-c8054cb6f981/resource/d7b3f70f-1abe-4028-bd3d-8d9c435e1ebe/download/bakken.json') %>% 
  filter(AFVALFRACTIE_OMSC == 'Rest')

# Inlezen wegen
temp <- tempfile()
download.file('https://ckan.dataplatform.nl/dataset/4aa2f6df-1116-470e-9108-3b8a521ca908/resource/b2959b33-0fbd-42d5-bf3a-214c4e22bed8/download/wegdelen-shape.zip', temp)
tempdir <- temp %>%   
  unzip(junkpaths = TRUE)
wegen <- read_sf(tempdir[5])
rm(temp, tempdir)

Filteren data

Filteren stadsdelen en wijken

De data moet nu gefilterd worden. Ik begin met het filteren van de stadsdelen en wijken, aangezien dit als variabele is opgenomen in de data:

# Filteren stadsdelen op Centrum en Segbroek
stadsdelen_casus <- stadsdelen %>%
  filter(STADSDEELNAAM == 'Segbroek' | STADSDEELNAAM == 'Centrum')
  
# Filteren wijken op stadsdelen Centrum en Segbroek dmv stadsdeelcode
wijken_casus <- wijken %>%
  filter(STADSDEELCODE == 5 | STADSDEELCODE == 3)

Filteren meldingen

Vervolgens filter ik de meldingen op jaar (2018 en 2019):

# Filteren op jaar
meldingen_selectie <- meldingen %>%
  filter(year(DATUM_MELDING) == 2018 | year(DATUM_MELDING) == 2019)

Omdat niet aan alle geogecodeerde data hetzelfde coördinate reference system is toegevoegd en dat wel nodig is om alles in één figuur te kunnen plotten, definieer ik dat zelf (lees hier meer over wat een coördinate reference system is):

# coordinatensysteem toevoegen
meldingen_selectie <- st_transform(meldingen_selectie, 28992)

We zijn al een heel eind! Maar nu komt een spannend moment: we willen de geogecodeerde meldingen filteren op basis van het wel of niet vallen binnen de geometrische vorm van de twee stadsdelen in de casus. Dit kan met de st_within-functie van de sf-package:

# Bepalen of melding in een van 2 casussen zit
meldingen_selectie$locatie <- st_within(meldingen_selectie, 
                                        stadsdelen_casus) %>% lengths > 0 
# .. en hierop filteren
meldingen_selectie <- meldingen_selectie %>%
  filter(locatie == TRUE)

Filteren wegen

We zijn lekker bezig! We gaan nu hetzelfde trucje uithalen met de wegen, zodat we straks niet alle wegen van heel Den Haag plotten, maar alleen die in de twee stadsdelen vallen:

# coordinatensysteem toevoegen
wegen <- st_transform(wegen, 28992)
wegen_selectie <- wegen
wegen_selectie$locatie <- st_within(wegen_selectie, 
                                    stadsdelen_casus) %>% lengths > 0
# .. en hierop filteren
wegen_selectie <- wegen_selectie %>%
  filter(locatie == TRUE) %>%
  # Filteren op hoofdwegen om het aantal lijnen beperkt te houden
  filter(FUNCTIE == 'rijbaan lokale weg')

Filteren containers

En hetzelfde trucje met de containers:

restcontainers_selectie <- restcontainers %>% 
  mutate(locatie = st_within(restcontainers, stadsdelen_casus) %>% lengths > 0) %>% 
  filter(locatie == TRUE)

Filteren bijplaatsingen

In dit voorbeeld wil ik alleen bijplaatsingen plotten:

bijplaatsingen <- meldingen_selectie %>%
  filter(SUB_SUBCATEGORIE == 'Naast verzamelcontainer') %>% 
  mutate(categorie = 'Bijplaatsingen')

Omdat ik in mijn eigen analyse meerdere categorieën gebruikte, voegde ik die door middel van rbind() samen in een nieuw object meldingen_selectie. Dat is voor deze analyse niet nodig.

Plotten van de gegevens

Als alles goed is gegaan kunnen we nu de data plotten in één gave figuur!

plot_bijplaatsingen <- ggplot(data = stadsdelen_casus) +
  # Achtergrond van de stadsdelen wit:
  geom_sf(fill = 'white') + 
  # Wegen toevoegen en doorzichtig gemaakt zodat ze vaag worden weergegeven: 
  geom_sf(data = wegen_selectie, alpha = .1, size = .05) +  
  # Wijken toevoegen met een groene grens
  geom_sf(data = wijken_casus, fill = NA, color = 'forestgreen') +  
  # Restcontainers toevoegen met een donkergrijze kleur
  geom_sf(data = restcontainers_selectie, color = 'gray31', size = .5) + # Restcontainers donkergrijs
  # Bijplaatsingen plotten met een alpha van .1, zodat ze doorzichtig zijn
  geom_sf(data = bijplaatsingen, 
          mapping = aes(color = categorie), alpha = .1, show.legend = FALSE) +
  # Labels aan de wijken toevoegen:
  geom_sf_label(data = wijken_casus, aes(label = WIJKNAAM), size = 2, alpha = .5) + 
  # Labels aan de plot zelf toevoegen
  labs(title = 'Meldingen openbare ruimte',
       subtitle = 'Meldingen \'Bijplaatsingen\'.') 
       
# En nu daadwerkelijk plotten!
plot_bijplaatsingen

Conclusie

Met de open databronnen van de gemeente Den Haag én een paar gave R-packages kun je relatief makkelijk zelf een kaart van (een deel van) Den Haag maken en geografische data plotten. Met kleine aanpassingen aan de code hierboven kun je nu zelf kaarten met geografische data maken  :-D.