knitr::opts_chunk$set(echo = TRUE)
library("opensensmapr")
library("dplyr")
library("lubridate")
library("units")
library("sf")
library("leaflet")
library("readr")
library("jsonlite")
library("here")
library("maps")
online <- TRUE # access online API or use local data backup?
analysis_date <- lubridate::as_datetime("2018-01-01 00:00:00")
if(online) {
# retrieve data from openSenseMap API
all_boxes <- osem_boxes()
pm25_boxes <- osem_boxes(
exposure = 'outdoor',
date = analysis_date, # ±4 hours
phenomenon = 'PM2.5'
)
# update local data
all_json <- toJSON(all_boxes, digits = NA, pretty = TRUE)
write(all_json, file = here("data/all_boxes.json"))
pm25_json <- toJSON(pm25_boxes, digits = NA, pretty = TRUE)
write(pm25_json, file = here("data/pm25_boxes.json"))
} else {
# load data from file and fix column types
all_boxes_file <- fromJSON(here("data/all_boxes.json"))
all_boxes <- type_convert(all_boxes_file,
col_types = cols(
exposure = col_factor(levels = NULL),
model = col_factor(levels = NULL),
grouptag = col_factor(levels = NULL)))
class(all_boxes) <- c("sensebox", class(all_boxes))
pm25_boxes_file <- fromJSON(here("data/pm25_boxes.json"))
pm25_boxes <- type_convert(pm25_boxes_file,
col_types = cols(
exposure = col_factor(levels = NULL),
model = col_factor(levels = NULL),
grouptag = col_factor(levels = NULL)))
class(pm25_boxes) <- c("sensebox", class(pm25_boxes))
}
knitr::kable(data.frame(nrow(all_boxes), nrow(pm25_boxes)),
col.names = c(
"# senseBoxes",
paste("# senseBoxes with PM2.5 measurements around", format(analysis_date, "%Y-%m-%d %T %Z"))))
plot(pm25_boxes)
ms <- st_sfc(st_point(c(7.62571, 51.96236)))
st_crs(ms) <- 4326
pm25_boxes_sf <- st_as_sf(pm25_boxes, remove = FALSE, agr = "identity")
names(pm25_boxes_sf) <- c(names(pm25_boxes), "geometry")
pm25_boxes_sf <- cbind(pm25_boxes_sf, dist_to_ms = st_distance(ms, pm25_boxes_sf))
max_dist <- set_units(7, km) # km from city center
ms_boxes <- pm25_boxes_sf[pm25_boxes_sf$dist_to_ms < max_dist,c("X_id", "name")]
ms_boxes
sense_icon <- awesomeIcons(
icon = 'cube',
iconColor = '#ffffff',
library = 'fa',
markerColor = 'green'
)
leaflet() %>%
addTiles() %>%
addAwesomeMarkers(data = ms_boxes,
popup = ~paste0("Name: ", name, "
Id: ",
"", X_id, ""),
label = ~name,
icon = sense_icon)
if(online) {
class(ms_boxes) <- c("sensebox", class(ms_boxes))
ms_data <- osem_measurements(ms_boxes, phenomenon = "PM2.5",
from = lubridate::as_datetime("2017-12-31 20:00:00"),
to = lubridate::as_datetime("2018-01-01 04:00:00"),
columns = c("value", "createdAt", "lat", "lon", "boxId",
"boxName", "exposure", "sensorId",
"phenomenon", "unit", "sensorType"))
# update local data
data_json <- toJSON(ms_data, digits = NA, pretty = TRUE)
write(data_json, file = here("data/ms_data.json"))
} else {
# load data from file and fix column types
ms_data_file <- fromJSON(here("data/ms_data.json"))
ms_data <- type_convert(ms_data_file,
col_types = cols(
sensorId = col_factor(levels = NULL),
unit = col_factor(levels = NULL)))
class(ms_data) <- c("sensebox", class(ms_data))
}
summary(ms_data %>%
select(value,sensorId,unit))
plot(value~createdAt, ms_data,
type = "p", pch = '*', cex = 2, # new year's style
col = factor(ms_data$sensorId),
xlab = NA,
ylab = unique(ms_data$unit),
main = "Particulates measurements (PM2.5) on New Year 2017/2018",
sub = paste(nrow(ms_boxes), "stations in Münster, Germany\n",
"Data by openSenseMap.org licensed under",
"Public Domain Dedication and License 1.0"))
top_measurements <- ms_data %>%
arrange(desc(value))
top_boxes <- top_measurements %>%
distinct(sensorId, .keep_all = TRUE)
knitr::kable(x = top_boxes %>%
select(value, createdAt, boxName) %>%
head(n = 3),
caption = "Top 3 boxes")
knitr::kable(top_boxes %>% filter(value == max(top_boxes$value)) %>%
select(sensorId, boxName),
col.names = c("Top sensor identifier", "Top box name"))
top_boxes_sf <- top_boxes %>%
filter(value == max(top_boxes$value)) %>%
st_as_sf(coords = c('lon', 'lat'), crs = 4326)
bbox <- sf::st_bbox(top_boxes_sf)
world <- map("world", plot = FALSE, fill = TRUE) %>%
sf::st_as_sf() %>%
sf::st_geometry()
plot(world,
xlim = round(bbox[c(1,3)], digits = 1),
ylim = round(bbox[c(2,4)], digits = 1),
axes = TRUE, las = 1)
plot(top_boxes_sf, add = TRUE, col = "red", cex = 2)
title("senseBox stations in Münster with highest PM2.5 measurements")
fireworks_icon <- makeIcon(
# icon source: https://commons.wikimedia.org/wiki/File:Fireworks_2.png
iconUrl = "320px-Fireworks_2.png", iconWidth = 160)
leaflet(data = top_boxes_sf) %>%
addTiles() %>%
addMarkers(popup = ~as.character(boxName),
label = ~as.character(boxName),
icon = fireworks_icon)
devtools::session_info()