BHGC / website

The Berkeley Hang Gliding Club (website)
https://www.bhgc.org/
4 stars 6 forks source link

Generating interactive and static maps #97

Open HenrikBengtsson opened 6 months ago

HenrikBengtsson commented 6 months ago

Here's an example illustrating how to generate a topology map showing the 300' and the 600' windsocks on Ed Levin using R:

library(leaflet)

m <- leaflet()
m <- m |> addTiles(urlTemplate = "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png")
m <- m |> setView(lat = 37.4611, lng = -121.8625, zoom = 17)

## 300' windsock
m <- m |> addMarkers(lat = 37.4611738, lng = -121.8646301, label = "300ft windsock", labelOptions = labelOptions(noHide = TRUE))

## 600' windsock
m <- m |> addMarkers(lat = 37.4612652, lng = -121.8604359, label = "600ft windsock", labelOptions = labelOptions(noHide = TRUE))

## Open (sic!) interactive leaflet map in web browser
print(m)

To save the same view as a static PNG file, use:

mapview::mapshot2(m, file = "edlevin.png")

This produces:

edlevin

Installation instructions

Assuming modern version of R, install packages using:

$ R
...
> install.packages(c("mapview", "webshot2"))
HenrikBengtsson commented 6 months ago

Here's how to pull free-flying and windsock information from OpenStreetMap and generate an standalone, interactive map;

library(osmdata)
library(leaflet)

## https://fontawesome.com/search?o=r&m=free
icons <- list(
        windsock = awesomeIcons(icon = "flag", markerColor = "gray",   iconColor = "white"),
          launch = awesomeIcons(icon = "play", markerColor = "green",  iconColor = "white"),
              lz = awesomeIcons(icon = "stop", markerColor = "red",    iconColor = "white"),
        training = awesomeIcons(icon = "play", markerColor = "orange", iconColor = "white"),
  groundhandling = awesomeIcons(icon = "user", markerColor = "blue",   iconColor = "white")
)

## Ed Levin & Mission Area
center <- c(lat = 37.465, lng = -121.86)
pad <- c(-1, -1, +1, +1) * 1/10
q <- opq(bbox = rep(center[c("lng", "lat")], times = 2) + pad)
q <- q |> add_osm_features(features = list(
    "sport" = "free_flying",
  "aeroway" = "windsock"
))
data <- q |> osmdata_sf()
print(data)

m <- leaflet(data)
m <- m |> addTiles(urlTemplate = "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png")

for (kk in seq_len(nrow(data$osm_points))) {
  point <- data$osm_points[kk, ]
  pos <- point$geometry[[1]]
  names(pos) <- c("lng", "lat")
  label <- point$name
  icon <- NULL

  site <- point[["free_flying:site"]]
  if (identical(site, "takeoff")) {
    icon <- icons$launch
  } else if (identical(site, "landing")) {
    icon <- icons$lz
  } else if (identical(site, "training")) {
    icon <- icons$training
  }

  type <- point[["free_flying:ground_handling"]]
  if (identical(type, "yes")) {
    icon <- icons$groundhandling
  }

  if (identical(point[["aeroway"]], "windsock")) {
    icon <- icons$windsock
  }

  m <- m |> addAwesomeMarkers(lat = pos["lat"], lng = pos["lng"], label = label, icon = icon)
}

m <- m |> setView(lat = center["lat"], lng = center["lng"], zoom = 15)
print(m)

To save as PNG;

mapview::mapshot2(m, file = "edlevin.png")

edlevin