🗺️ Knowledgemile Maps 🗺️
Supporting knowledgemile Park project with an interactive map of the 'urban climate' and the 'biodiversity' of its surroundings from open data sources.
Made with Rstudio and build on Shiny Dashboards and Leaflet for R.
The research question of this project was: "How can biodiversity and urban climate of the knowledge mile park be mapped that creates added value for discussions and meetings with stakeholders?"
🔎 Table of content
The index of this document. In this document you can find references to used sources. There is also a short description about how this project can be replicated.
🔦 Features
The following features are implemented
Maps
- Hittestress:
- Mogelijk wateroverlast panden:
- Tree's datasets:
- Groene daken
Map features
- minimap | guide | link to source |
- bigzoom | guide | link to source |
- measure | guide | link to source |
Theme
We used a combination of a bootstrap theme and some custom css (usage of css in shiny). Bootstrap theme is called "superhero" (source). Usage:
## ui.R ##
library(shinythemes)
shinyUI(bootstrapPage(
theme = shinytheme("superhero"),
includeCSS("style.css"),
...
)
)
Or a theme selector:
shinythemes::themeSelector() # <--- Add this somewhere in the UI
🛠 Development Knowledgemile Maps
How to continue with the Knowledgemile Maps
Show and hide leaflet layers
We first make a leaflet plot inside the server.R
. Each layer is assigned to a group. The legend of that layer is then connected to the same group. We can show and hide a layer using a observer and a proxy of leaflet. We use an observer so that only a small part of the leaflet plot is redrawn. The input$dropbox
is a vector of the selected choices straight from the ui.R
.
## server.R ##
output$map <- renderLeaflet({
leaflet(...)
...
})
...
observe({
proxy <- leafletProxy("map")
if ("hittestress" %in% input$DropDown) {
proxy %>%
showGroup("hittestress")
}
if (!("hittestress" %in% input$DropDown)) {
proxy %>%
hideGroup("hittestress")
}
Performance of the data
We transformed some large files into .shp files. We also filtert the data so it only contains data from Amsterdam.
We first made an Amsterdam polygon from combining all Amsterdam neighbourhoods (Buurten
). After that we made the crs of the raw data the same as the project. At last, we filterd the raw data on the Amsterdam polygon.
AmsterdamPolygon <- st_union(Buurten)
data_hittestress <- projectRaster(data_hittestress,crs="+proj=longlat +datum=WGS84 +no_defs")
hittestress_Amsterdam <- raster::intersect(hittestress_new,as(AmsterdamPolygon,"Spatial"))
With this Amsterdam polygon we manipulate raster data of hittestress and waterbergendvermogen
hittestress <- raster("RIVM_R88_20170621_gm_actueelUHI.tif")
hittestress <- projectRaster(hittestress,crs="+proj=longlat +datum=WGS84 +no_defs")
hittestress_Amsterdam <- raster::intersect(hittestress,as(AmsterdamPolygon,"Spatial"))
#save as rasterlayer
hittestress_amsterdam_small <- writeRaster(hittestress_Amsterdam,
filename = "raster_amsterdam_hittestress",
format = "GTiff",
overwrite=TRUE)
We then exported this data into a new file. The server can load this new file much faster.
Mobile styling
So we added some code to change top banner color of supported mobile browsers.
tags$head(
tags$meta(name="theme-color", content="#FFFF00"),
tags$meta(name="msapplication-navbutton-color", content="#FFFF00"),
tags$meta(name="apple-mobile-web-app-status-bar-style", content="#FFFF00")
),
Packages used
The following packages are used.
copy & paste this code below into a R console to install them
install.packages("shiny")
install.packages("markdown")
install.packages("shinyWidgets")
install.packages("shinyhelper")
install.packages("htmlwidgets")
install.packages("rgdal")
install.packages("sf")
install.packages("sp")
install.packages("maps")
install.packages("maptools")
install.packages("leaflet")
install.packages("leaflet.extras")
install.packages("raster")
install.packages("tidyverse")
install.packages("shinythemes")
install.packages("devtools")
install.packages("mapview")
install.packages("RColorBrewer")
install.packages("htmlwidgets")
Coordinate Reference Systems
We used the following CRS throughout the project:
+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
crs <- "+proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0"
📦 Deployment
Hosting dashboard
To make the dashboard publicly available, you can make install shiny server yourself:
- Shiny Server
Official instructions
Better instructions
OR use a service:
- shinyapps.io
- Rstudio Connect (More advanced)
File structure
.
├── style.css # css stylesheet
├── server.R # server side R script
├── global.R # global R script
├── ui.R # Ui side R script
├── data
│ ├── groene_daken_2.shp
│ ├── raster_amsterdam_hittestress.tif
│ ├── GEBIED_BUURTEN.json
│ ├── ...groen_daken_2.* # All other shp file extensions
│ ├── knowledge_mile_bomen_1.shp
│ ├── ...knowledge_mile_bomen_1.* # All other shp file extensions
│ ├── knowledge_mile_bomen_2.shp
│ ├── ...knowledge_mile_bomen_2.* # All other shp file extensions
│ ├── knowledge_mile_bomen_3.shp
│ ├── ...knowledge_mile_bomen_3.* # All other shp file extensions
│ ├── knowledge_mile_bomen_4.shp
│ └── ...knowledge_mile_bomen_4.* # All other shp file extensions
├── img
│ ├── logo.png # Knowledgemile logo used in this document
│ └── HVA-logo_ZW.png # Hva logo used in this document
└── README.md # This document
🏷 Unfinished business
The following features weren't finished in time.
Printing
We found some javascript code that can print a leaflet map. But this only works in chrome and is buggy.
rowanwins leaflet easyprint
Server Code:
## server.R ##
leaflet(...) %>%
onRender(
"function(el, x) {
L.easyPrint({
sizeModes: ['A4Landscape', 'A4Portrait','a3Size'],
filename: 'map',
exportOnly: false,
hideControlContainer: true
}).addTo(this);
}"
)
ui Code:
## ui.R ##
jsfile <- "https://rawgit.com/rowanwins/leaflet-easyPrint/gh-pages/dist/bundle.js"
# inside shinyUI:
tags$head(tags$script(src = jsfile))
More datasets
There are a lot of datasets that can be included in the KnowledgeMile Maps. Here is an opensource datasets that could be included:
- Geluid in Nederland (Lden):
Story Telling
It would be nice to have a discription and a legend per dataset about the dataset. We only have made one legend for 'Hittestress'. The legend can also be toggled by the group element in leaflet.
leaflet(...) %>%
... %>%
addLegend(pal = pal,
values = values(data_hittestress),
position = "bottomright",
title = "Hittestress in (celcius)",
group = "hittestress")
🏷 Banner
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#
# #
# _ __ _ _ __ __ _ _ #
#| |/ / | | | | | \/ (_) | __CS____________ | #
#| ' / _ __ _____ _| | ___ __| | __ _ ___ | \ / |_| | ___ hp___________/ | | \ / | #
#| < | '_ \ / _ \ \ /\ / / |/ _ \/ _` |/ _` |/ _ \ | |\/| | | |/ _ \ \ | | | | |nm ,' / #
#| . \| | | | (_) \ V V /| | __/ (_| | (_| | __/ | | | | | | __/ | | | | | | `./ _____| #
#|_|\_\_| |_|\___/ \_/\_/ |_|\___|\__,_|\__, |\___| |_| |_|_|_|\___| \ | |_,--dam---' \ _/ \ / #
# | _ _ |_ |_) _ _ _|_ o _ _ __ __/ | | |_,-| | | wap=. \/\ #
# \_|(_)_> | | |_)(_|_> |_ | (_|(_|| | |___/ ~ GLOBAL ~ \ /| | |__| / \_ / `\ #
# `/ | _| \ \ / wp `\ #
# ---- \ \_/ \_ kp--mp--rp' / \ #
# Minor: Data Science | \_ \/____|__,-\ ,/ `\ #
# Track: Urban Analytics \ \_ / \ _\ / `\ #
# Semester: 2 `\ \/___,--|---' |_/ ` #
# Projectsite: https://knowledgemile.amsterdam/ `\ | \ ___/ #
# Auteurs: Josh Bleijenberg; \_lp-----wc/ #
# Bastiaan Groen; #
# contactpersonen: Maarten Terpstra; _ _ __ ____ ____ #
# Corine Laan; ( \/ ) / _\ ( _ \/ ___) #
# ---- / \/ \/ \ ) __/\___ \ #
# \_)(_/\_/\_/(__) (____/ #
# | Github pagina: #
# | https://github.com/BastiaanGroen/knowledgemilemaps #
# #
#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-#