library(tidyverse) # Om te kunnen filteren
library(lubridate) # Om op datums te kunnen filteren
library(sf) # Om de kaarten te maken
Kaartjes maken met Open Data
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:
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:
Meldingen openbare ruimte Den Haag waar de meldingen een geografische locatie hebben;
Afval apart containers Den Haag om de locaties van ORAC’s te kunnen bepalen;
Wegdelen Shapefile Den Haag om hoofdwegen op de kaart weer te kunnen geven
Stadsdelen Den Haag om de meldingen en wegdelen te filteren (verkleinen) tot het gebied van de 2 stadsdelen;
Wijken Den Haag om wijkgrenzen aan te kunnen geven en wijknamen weer te geven.
Inlezen data
Met de volgende code heb ik de verschillende databestanden ingelezen:
# Inlezen meldingenregister
<- read_sf('https://ckan.dataplatform.nl/dataset/04a332fd-b38f-4716-9811-7e15fb32bd40/resource/43abc627-f718-44c3-98bf-dcc14e06d92a/download/meldingen.json')
meldingen
# Inlezen stadsdelen
<- read_sf('https://ckan.dataplatform.nl/dataset/3a7494a8-87dc-403c-bf4e-bdd4fac6242d/resource/3de9bdcb-c949-4440-a731-f5238aaa089c/download/stadsdelen.json')
stadsdelen
# Inlezen wijken
<- read_sf('https://ckan.dataplatform.nl/dataset/c1059cef-be66-4a7a-9657-2f38f55794ed/resource/a175afe5-67e2-4e45-8b71-62f30377bf7d/download/wijken.json')
wijken
# Inlezen restafvalcontainers
<- read_sf('https://ckan.dataplatform.nl/dataset/be4068d0-573b-4d24-86ff-c8054cb6f981/resource/d7b3f70f-1abe-4028-bd3d-8d9c435e1ebe/download/bakken.json') %>%
restcontainers filter(AFVALFRACTIE_OMSC == 'Rest')
# Inlezen wegen
<- tempfile()
temp download.file('https://ckan.dataplatform.nl/dataset/4aa2f6df-1116-470e-9108-3b8a521ca908/resource/b2959b33-0fbd-42d5-bf3a-214c4e22bed8/download/wegdelen-shape.zip', temp)
<- temp %>%
tempdir unzip(junkpaths = TRUE)
<- read_sf(tempdir[5])
wegen 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 %>%
stadsdelen_casus filter(STADSDEELNAAM == 'Segbroek' | STADSDEELNAAM == 'Centrum')
# Filteren wijken op stadsdelen Centrum en Segbroek dmv stadsdeelcode
<- wijken %>%
wijken_casus filter(STADSDEELCODE == 5 | STADSDEELCODE == 3)
Filteren meldingen
Vervolgens filter ik de meldingen op jaar (2018 en 2019):
# Filteren op jaar
<- meldingen %>%
meldingen_selectie 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
<- st_transform(meldingen_selectie, 28992) meldingen_selectie
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
$locatie <- st_within(meldingen_selectie,
meldingen_selectie%>% lengths > 0
stadsdelen_casus) # .. 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
<- st_transform(wegen, 28992)
wegen <- wegen
wegen_selectie $locatie <- st_within(wegen_selectie,
wegen_selectie%>% lengths > 0
stadsdelen_casus) # .. 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 %>%
restcontainers_selectie mutate(locatie = st_within(restcontainers, stadsdelen_casus) %>% lengths > 0) %>%
filter(locatie == TRUE)
Filteren bijplaatsingen
In dit voorbeeld wil ik alleen bijplaatsingen plotten:
<- meldingen_selectie %>%
bijplaatsingen 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!
<- ggplot(data = stadsdelen_casus) +
plot_bijplaatsingen # 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.