Load required libraries
library(dplyr)
library(sf)
library(jsonlite)
library(leaflet)
library(stringr)
library(htmlwidgets)
# if needed, run first:
# install.packages("BelgiumMaps.StatBel", repos = "http://www.datatailor.be/rcube", type = "source")
library(BelgiumMaps.StatBel)
Load/fetch requried data
Used in example:
Load arrondissement borders
# load district/arrondissement spatial structure from package BelgiumMaps.StatBel
data('BE_ADMIN_DISTRICT')
# convert to simple features dataset-structure
arronds = st_as_sf(BE_ADMIN_DISTRICT)
# filter on on arrondissementen located in Flanders and Brussels
arronds = arronds %>%
filter(TX_RGN_DESCR_NL %in% c('Vlaams Gewest', 'Brussels Hoofdstedelijk Gewest'))
# rough plot, to verify that spatial data is as expected
plot(arronds, max.plot = 1)
Fetch open data VDAB office locations
# fetch open data in JSON-format
vdab.kantoren = as_tibble(fromJSON('http://opendata.vdab.be/vdab/locaties.json'))
vdab.kantoren # dataset with office locations, including coordinates
Describe and change VDAB-data
# count te different types of VDAB offices
vdab.kantoren %>%
group_by(typelocatie) %>%
tally()
vdab.kantoren = vdab.kantoren %>%
mutate(
# add a variable 'popup' with the the HTML-snippet per office,
# which will be shown in the map-popup
popup = str_glue("<h3>{title}</h3><br /><b>Type: </b>{typelocatie}<br /><b>Adres</b>: {straatNr} {plaats}<br /><b>Teleloon</b>: {telefoonnummer}"),
# make sure that coordinates are not a character, but numeric variables
lat = as.numeric(lat),
lon = as.numeric(lon))
Construct interactive map
Minimal map example
# basic interactive map with a oneliner
# (width-argument not needed, only for online-output)
leaflet(vdab.kantoren, width = '100%') %>% addTiles() %>% addMarkers()
Save stand-alone map
saveWidget(m.kantoren, 'vdab_api_popup_map.html')
LS0tDQp0aXRsZTogIlIgdGlkeXZlcnNlIC0gVkRBQiBvcGVuIGRhdGEgZXhhbXBsZSBtYXAiDQphdXRob3I6ICJNYWFydGVuIEhlcm1hbnMgLSBAaGVybWFuc20iDQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOiANCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQotLS0NCg0KIyBMb2FkIHJlcXVpcmVkIGxpYnJhcmllcw0KDQpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShqc29ubGl0ZSkNCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkoaHRtbHdpZGdldHMpDQoNCiMgaWYgbmVlZGVkLCBydW4gZmlyc3Q6DQojIGluc3RhbGwucGFja2FnZXMoIkJlbGdpdW1NYXBzLlN0YXRCZWwiLCByZXBvcyA9ICJodHRwOi8vd3d3LmRhdGF0YWlsb3IuYmUvcmN1YmUiLCB0eXBlID0gInNvdXJjZSIpDQpsaWJyYXJ5KEJlbGdpdW1NYXBzLlN0YXRCZWwpIA0KYGBgDQoNCiMgTG9hZC9mZXRjaCByZXF1cmllZCBkYXRhDQoNClVzZWQgaW4gZXhhbXBsZToNCg0KKiBbVkRBQiBvZmZpY2UtbG9jYXRpb25zIGFzIG9wZW4gZGF0YV0oaHR0cHM6Ly93d3cudmRhYi5iZS90cmVuZHMvb3Blbl9kYXRhL2xvY2F0aWVzKSAoSlNPTi1maWxlKS4NCiogQWRtaW5pc3RyYXRpdmUgYm91bmRhcmllcyBmb3IgQmVsZ2lhbiAqYXJyb25kaXNzZW1lbnRlbiosIGNvdXJ0ZXN5IG9mIHRoZSBbQmVsZ2l1bU1hcHMuU3RhdEJlbF0oaHR0cHM6Ly9naXRodWIuY29tL2Jub3NhYy9CZWxnaXVtTWFwcy5TdGF0QmVsKSBSIHBhY2thZ2UuIA0KDQojIyBMb2FkIGFycm9uZGlzc2VtZW50IGJvcmRlcnMNCg0KYGBge3IsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQojIGxvYWQgZGlzdHJpY3QvYXJyb25kaXNzZW1lbnQgc3BhdGlhbCBzdHJ1Y3R1cmUgZnJvbSBwYWNrYWdlIEJlbGdpdW1NYXBzLlN0YXRCZWwNCmRhdGEoJ0JFX0FETUlOX0RJU1RSSUNUJykgDQoNCiMgY29udmVydCB0byBzaW1wbGUgZmVhdHVyZXMgZGF0YXNldC1zdHJ1Y3R1cmUNCmFycm9uZHMgPSBzdF9hc19zZihCRV9BRE1JTl9ESVNUUklDVCkgDQoNCiMgZmlsdGVyIG9uIG9uIGFycm9uZGlzc2VtZW50ZW4gbG9jYXRlZCBpbiBGbGFuZGVycyBhbmQgQnJ1c3NlbHMNCmFycm9uZHMgPSBhcnJvbmRzICU+JQ0KICBmaWx0ZXIoVFhfUkdOX0RFU0NSX05MICVpbiUgYygnVmxhYW1zIEdld2VzdCcsICdCcnVzc2VscyBIb29mZHN0ZWRlbGlqayBHZXdlc3QnKSkNCmBgYA0KDQpgYGB7cn0NCiMgcm91Z2ggcGxvdCwgdG8gdmVyaWZ5IHRoYXQgc3BhdGlhbCBkYXRhIGlzIGFzIGV4cGVjdGVkDQpwbG90KGFycm9uZHMsIG1heC5wbG90ID0gMSkNCmBgYA0KDQojIyBGZXRjaCBvcGVuIGRhdGEgVkRBQiBvZmZpY2UgbG9jYXRpb25zIA0KDQpgYGB7cn0NCiMgZmV0Y2ggb3BlbiBkYXRhIGluIEpTT04tZm9ybWF0DQp2ZGFiLmthbnRvcmVuID0gYXNfdGliYmxlKGZyb21KU09OKCdodHRwOi8vb3BlbmRhdGEudmRhYi5iZS92ZGFiL2xvY2F0aWVzLmpzb24nKSkNCnZkYWIua2FudG9yZW4gIyBkYXRhc2V0IHdpdGggb2ZmaWNlIGxvY2F0aW9ucywgaW5jbHVkaW5nIGNvb3JkaW5hdGVzDQpgYGANCg0KDQojIyBEZXNjcmliZSBhbmQgY2hhbmdlIFZEQUItZGF0YQ0KDQoNCmBgYHtyfQ0KIyBjb3VudCB0ZSBkaWZmZXJlbnQgdHlwZXMgb2YgVkRBQiBvZmZpY2VzDQp2ZGFiLmthbnRvcmVuICU+JQ0KICBncm91cF9ieSh0eXBlbG9jYXRpZSkgJT4lDQogIHRhbGx5KCkNCmBgYA0KDQoNCmBgYHtyfQ0KdmRhYi5rYW50b3JlbiA9IHZkYWIua2FudG9yZW4gJT4lDQogIG11dGF0ZSgNCiAgICAjIGFkZCBhIHZhcmlhYmxlICdwb3B1cCcgd2l0aCB0aGUgdGhlIEhUTUwtc25pcHBldCBwZXIgb2ZmaWNlLA0KICAgICMgd2hpY2ggIHdpbGwgYmUgc2hvd24gaW4gdGhlIG1hcC1wb3B1cA0KICAgIHBvcHVwID0gc3RyX2dsdWUoIjxoMz57dGl0bGV9PC9oMz48YnIgLz48Yj5UeXBlOiA8L2I+e3R5cGVsb2NhdGllfTxiciAvPjxiPkFkcmVzPC9iPjogIHtzdHJhYXROcn0ge3BsYWF0c308YnIgLz48Yj5UZWxlbG9vbjwvYj46IHt0ZWxlZm9vbm51bW1lcn0iKSwNCiAgICANCiAgICAjIG1ha2Ugc3VyZSB0aGF0IGNvb3JkaW5hdGVzIGFyZSBub3QgYSBjaGFyYWN0ZXIsIGJ1dCBudW1lcmljIHZhcmlhYmxlcw0KICAgIGxhdCA9IGFzLm51bWVyaWMobGF0KSwNCiAgICBsb24gPSBhcy5udW1lcmljKGxvbikpDQpgYGANCg0KDQoNCiMgQ29uc3RydWN0IGludGVyYWN0aXZlIG1hcA0KDQojIyBNaW5pbWFsIG1hcCBleGFtcGxlDQoNCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQ0KIyBiYXNpYyBpbnRlcmFjdGl2ZSBtYXAgd2l0aCBhIG9uZWxpbmVyDQojICh3aWR0aC1hcmd1bWVudCBub3QgbmVlZGVkLCBvbmx5IGZvciBvbmxpbmUtb3V0cHV0KQ0KbGVhZmxldCh2ZGFiLmthbnRvcmVuLCB3aWR0aCA9ICcxMDAlJykgJT4lIGFkZFRpbGVzKCkgJT4lIGFkZE1hcmtlcnMoKQ0KYGBgDQoNCiMjIFN0eWxlZCBtYXAgZXhhbXBsZSB3L3QgcG9wdXBzDQoNClN0eWxpbmc6DQoNCiogUG9wdXBzIHdpdGggVkRBQi1vZmZpY2UgaW5mb3JtYXRpb24uDQoqIEN1c3RvbSB0aWxlIGJhY2tncm91bmQNCiogQ3VzdG9tIGNvbG9yICYgc3ltYm9sIG1hcmtlcnMsIGJhc2VkIG9uIGRpc2NyZXRlIHZhbHVlcyAob2ZmaWNlLXR5cGUpDQoqIE92ZXJsYXkgb2YgKmFycm9uZGlzc2VtZW50Ki1wb2x5Z29uczogbm93IGdyZXkvd2hpdGUtc3R5bGVkLCBjb3VsZCBiZSBjb2xvcmVkIGJhc2VkIG9uIGUuZy4gdW5lbXBsb3ltZW50LXJhdGUuIA0KDQpgYGB7cn0NCiMgY3JlYXRlIHR3byBpY29ucyB3aXRoIGRpZmZlcmVudCBjb2xvciAmIHN5bWJvbCBmb3IgdGhlIHR3byB0eXBlcyBvZiBWREFCLW9mZmljZXMNCiMgZm9yIGRpZmZlcmVudCBzeW1ib2xzLCBjZi4gaHR0cHM6Ly9yc3R1ZGlvLmdpdGh1Yi5pby9sZWFmbGV0L21hcmtlcnMuaHRtbCANCmthbnRvb3JfaWNvbnMgPC0gYXdlc29tZUljb25MaXN0KA0KICAna2FudG9vciBtZXQgb250aGFhbCcgPSBtYWtlQXdlc29tZUljb24oDQogICAgaWNvbiA9ICJ1c2VyIiwgDQogICAgbGlicmFyeSA9ICJmYSIsIA0KICAgIG1hcmtlckNvbG9yID0gImJsdWUiKSwNCiAgJ29wbGVpZGluZ3NjZW50cnVtJyA9IG1ha2VBd2Vzb21lSWNvbigNCiAgICBpY29uID0gImdyYWR1YXRpb24tY2FwIiwgDQogICAgbGlicmFyeSA9ICJmYSIsIA0KICAgIG1hcmtlckNvbG9yID0gInJlZCIpKQ0KYGBgDQoNCmBgYHtyfQ0KbS5rYW50b3JlbiA9IGxlYWZsZXQoYXJyb25kcywgd2lkdGggPSAnMTAwJScpICU+JSANCiAgIyBhZGQgbWluaW1hbGlzdGljLXN0eWxlIG1hcCBibGFja2dyb3VuZCB0aWxlcw0KICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVycyRDYXJ0b0RCLlBvc2l0cm9uKSAlPiUgDQogIA0KICAjIGFkZCBncmV5IGFycm9uZGlzc2VtZW50IHBvbHlnb25zIHcvdCB3aGl0ZSBib3JkZXINCiAgYWRkUG9seWdvbnMoZmlsbENvbG9yID0gICdncmV5MjAnLCBjb2xvciA9ICd3aGl0ZScpICU+JSANCiAgDQogICMgYWRkIGN1c3RvbSBzdHlsZWQgbWFya2VycyB3L3QgcG9wdXBzDQogIGFkZEF3ZXNvbWVNYXJrZXJzKA0KICAgIGRhdGEgPSB2ZGFiLmthbnRvcmVuLA0KICAgIGxuZyA9IH5sb24sIGxhdCA9IH5sYXQsDQogICAgaWNvbiA9IH5rYW50b29yX2ljb25zW3R5cGVsb2NhdGllXSwNCiAgICBwb3B1cCA9IH5wb3B1cCkNCmBgYA0KDQpgYGB7cn0NCm0ua2FudG9yZW4NCmBgYA0KDQojIFNhdmUgc3RhbmQtYWxvbmUgbWFwDQoNCmBgYHtyfQ0Kc2F2ZVdpZGdldChtLmthbnRvcmVuLCAndmRhYl9hcGlfcG9wdXBfbWFwLmh0bWwnKQ0KYGBgDQoNCg==