Code
library(httr)
library(dplyr)
library(leaflet)
library(leaflegend)
library(DT)
- 1
- Interactive mapping
- 2
- Map legends
- 3
- Nice data tables
November 6, 2024
For day 1 (points) of the 30 Day Map Challenge, I decided to map locations of wind turbines in Iowa using data from the US Wind Turbine Database (USWTDB). I drove through Iowa on a road trip last year and was amazed to see how many turbines there were. It was especially mesmerizing at night when all the red warning lights on top of them were blinking in sync. The USWTDB has a nice online viewer, but I chose to get the data via their API and plot the data in R.
USWTDB Citation:
Hoen, B.D., Diffendorfer, J.E., Rand, J.T., Kramer, L.A., Garrity, C.P., and Hunt, H.E., 2018, United States Wind Turbine Database (ver. 7.1, August 2024): U.S. Geological Survey, American Clean Power Association, and Lawrence Berkeley National Laboratory data release, https://doi.org/10.5066/F7TX3DN0.
First I will get data for one state using the API:
I used {leaflet} Cheng et al. (2024) to make an interactive plot of the individual wind turbine locations.
There are a lot of individual turbines (6481) that are part of a smaller group of wind farms/projects, so I’ll group by the project and compute the total capacity and mean lat/lon.
projects <- df |>
group_by(p_name) |>
summarise(n_turbines = n(),
total_cap_MW = round(sum(t_cap, na.rm = TRUE)/1e3),
lat_mean = mean(ylat, na.rm = TRUE),
long_mean = mean(xlong,na.rm = TRUE)) |>
arrange(desc(total_cap_MW))
projects |> select(p_name, n_turbines, total_cap_MW) |>
DT::datatable(options = list(pageLength = 5), rownames = FALSE)
I decided to make a second map, where I plot a circle for each project with size proportional to total capacity. The circles are centered at the mean lat/lon of all the turbines in each project.
# define some plot parameters that are repeated in the code
basesz <- 7
wh_col <- "green"
leaflet(data = projects) |>
addTiles() |>
leaflegend::addSymbolsSize(lng = ~long_mean, lat = ~lat_mean,
values = ~total_cap_MW,
shape = 'circle',
color = wh_col,
opacity = 0.5,
baseSize = basesz,
popup = paste(projects$p_name, "<br>",
projects$total_cap_MW, "MW")
) |>
leaflegend::addLegendSize(values = ~total_cap_MW,
color = wh_col,
shape = 'circle',
breaks = 4,
baseSize = basesz,
title = 'Capacity (MW)')
R version 4.4.1 (2024-06-14)
Platform: x86_64-apple-darwin20
Running under: macOS Sonoma 14.7
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-x86_64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: America/Denver
tzcode source: internal
attached base packages:
[1] stats graphics grDevices datasets utils methods base
other attached packages:
[1] DT_0.33 leaflegend_1.2.1 leaflet_2.2.2 dplyr_1.1.4
[5] httr_1.4.7
loaded via a namespace (and not attached):
[1] vctrs_0.6.5 cli_3.6.3 knitr_1.48
[4] rlang_1.1.4 xfun_0.49 renv_1.0.9
[7] generics_0.1.3 jsonlite_1.8.9 glue_1.8.0
[10] htmltools_0.5.8.1 sass_0.4.9 fansi_1.0.6
[13] rmarkdown_2.29 jquerylib_0.1.4 crosstalk_1.2.1
[16] evaluate_1.0.1 tibble_3.2.1 fastmap_1.2.0
[19] yaml_2.3.10 lifecycle_1.0.4 compiler_4.4.1
[22] htmlwidgets_1.6.4 pkgconfig_2.0.3 rstudioapi_0.17.1
[25] leaflet.providers_2.0.0 digest_0.6.37 R6_2.5.1
[28] tidyselect_1.2.1 utf8_1.2.4 curl_5.2.3
[31] pillar_1.9.0 magrittr_2.0.3 bslib_0.8.0
[34] withr_3.0.2 tools_4.4.1 cachem_1.1.0
---
title: "Mapping Wind Turbines"
date: 2024-11-06
#date-modified: today
image: IA_turbines.png
format:
html:
code-link: true
code-fold: show
code-tools: true
toc: true
fig-width: 9
fig-height: 7
tbl-cap-location: bottom
editor: visual
code-annotations: hover
categories: [R,energy,mapping,leaflet,energy]
freeze: auto
draft: false
bibliography: references.bib
---
# Introduction
For day 1 (points) of the [30 Day Map Challenge](https://30daymapchallenge.com/), I decided to map locations of wind turbines in Iowa using data from the [US Wind Turbine Database (USWTDB)](https://eerscmap.usgs.gov/uswtdb/). I drove through Iowa on a road trip last year and was amazed to see how many turbines there were. It was especially mesmerizing at night when all the red warning lights on top of them were blinking in sync. The USWTDB has a nice online [viewer](https://eerscmap.usgs.gov/uswtdb/viewer/), but I chose to get the data via their [API](https://eerscmap.usgs.gov/uswtdb/api-doc/) and plot the data in R.
USWTDB Citation:
Hoen, B.D., Diffendorfer, J.E., Rand, J.T., Kramer, L.A., Garrity, C.P., and Hunt, H.E., 2018, United States Wind Turbine Database (ver. 7.1, August 2024): U.S. Geological Survey, American Clean Power Association, and Lawrence Berkeley National Laboratory data release, https://doi.org/10.5066/F7TX3DN0.
## Load libraries
```{r}
#| label: libraries
#| message: false
library(httr)
library(dplyr)
library(leaflet) # <1>
library(leaflegend) # <2>
library(DT) # <3>
```
1. Interactive mapping
2. Map legends
3. Nice data tables
## Data
First I will get data for one state using the API:
```{r}
#| label: tbl-turbine-data
#| tbl-cap: Example wind turbine data retrieved from the from USWTDB API.
wh_state <- "IA"
req_url <- paste0("https://eersc.usgs.gov/api/uswtdb/v1/turbines?t_state=eq.", wh_state)
resp <- httr::GET(req_url)
df <- jsonlite::fromJSON(httr::content(resp, as = "text", encoding = "UTF-8"))
df |> head() |> DT::datatable(options = list(pageLength = 5), rownames = FALSE)
```
## Map of turbine locations
I used {leaflet} @leaflet to make an interactive plot of the individual wind turbine locations.
```{r}
#| label: fig-map-points
#| fig-cap: !expr glue::glue('Interactive map of individual wind turbine locations in {wh_state}. Click on points for more information. Data from USWTDB.')
leaflet(data = df) |>
addProviderTiles(provider = providers$CartoDB.Positron) |>
addCircleMarkers(lng = ~xlong, lat = ~ylat,
stroke = FALSE,
radius = 3,
popup = paste("Project: ", df$p_name, "<br>",
"Model: ", df$t_model, "<br>",
"Capacity: ", df$p_cap/1000 ," MW"))
```
## Group by project
There are a lot of individual turbines (`r nrow(df)`) that are part of a smaller group of wind farms/projects, so I'll group by the project and compute the total capacity and mean lat/lon.
```{r}
#| label: tbl-projects
#| tbl-cap: !expr glue::glue('Table of projects and total capacity for {wh_state}')
projects <- df |>
group_by(p_name) |>
summarise(n_turbines = n(),
total_cap_MW = round(sum(t_cap, na.rm = TRUE)/1e3),
lat_mean = mean(ylat, na.rm = TRUE),
long_mean = mean(xlong,na.rm = TRUE)) |>
arrange(desc(total_cap_MW))
projects |> select(p_name, n_turbines, total_cap_MW) |>
DT::datatable(options = list(pageLength = 5), rownames = FALSE)
```
# Map projects
I decided to make a second map, where I plot a circle for each *project* with size proportional to total capacity. The circles are centered at the mean lat/lon of all the turbines in each project.
- Making a legend with the proportional circle sizes is tricky; I used the awesome {leaflegend} @leaflegend package to make the legend for circle size.
```{r}
#| label: fig-project-map
#| fig-cap: !expr glue::glue('Map of mean wind project locations and total capacity by project in {wh_state}. Click on points for more information. Data from USWTDB.')
# define some plot parameters that are repeated in the code
basesz <- 7
wh_col <- "green"
leaflet(data = projects) |>
addTiles() |>
leaflegend::addSymbolsSize(lng = ~long_mean, lat = ~lat_mean,
values = ~total_cap_MW,
shape = 'circle',
color = wh_col,
opacity = 0.5,
baseSize = basesz,
popup = paste(projects$p_name, "<br>",
projects$total_cap_MW, "MW")
) |>
leaflegend::addLegendSize(values = ~total_cap_MW,
color = wh_col,
shape = 'circle',
breaks = 4,
baseSize = basesz,
title = 'Capacity (MW)')
```
# SessionInfo
::: {.callout-tip collapse="true"}
## Expand for Session Info
```{r, echo = FALSE}
sessionInfo()
```
:::
# References