R Example#
knitr::opts_chunk$set(echo = TRUE)
library(httr2)
library(jsonlite)
library(sf)
library(dplyr)
library(leaflet)
library(viridis)
Set Up API Endpoints#
base_url <- "https://space2stats.ds.io"
fields_endpoint <- paste0(base_url, "/fields")
summary_endpoint <- paste0(base_url, "/summary")
Fetch Available Fields#
# Set up the request to fetch available fields
req <- request(base_url) |>
req_url_path_append("fields") # Append the correct endpoint
# Perform the request and get the response
resp <- req |> req_perform()
# Check the status code
if (resp_status(resp) != 200) {
stop("Failed to get fields: ", resp_body_string(resp))
}
# Parse the response body as JSON
available_fields <- resp |> resp_body_json()
# Print the available fields in a simplified format
print("Available Fields:")
print(unlist(available_fields))
Define Area of Interest (AOI)#
minx <- 29.038924
miny <- -4.468958
maxx <- 30.850461
maxy <- -2.310523
# Define Area of Interest (AOI) with NULL for properties to ensure it's treated as a valid dictionary
aoi <- list(
type = "Feature",
properties = NULL, # Empty properties
geometry = list(
type = "Polygon",
coordinates = list(
list(
c(minx, maxy),
c(minx, miny),
c(maxx, miny),
c(maxx, maxy),
c(minx, maxy)
)
)
)
)
Request Summary Data#
request_payload <- list(
aoi = aoi,
spatial_join_method = "centroid",
fields = list("sum_pop_2020"),
geometry = "point"
)
# Set up the base URL and create the request
req <- request(base_url) |>
req_url_path_append("summary") |>
req_body_json(request_payload)
# Perform the request and get the response
resp <- req |> req_perform()
# Turn response into a data frame
summary_data <- resp |> resp_body_string() |> fromJSON(flatten = TRUE)
# Extract coordinates and convert to a spatial data frame (sf object)
summary_data <- summary_data %>%
mutate(
x = sapply(geometry, function(g) fromJSON(g)$coordinates[1]),
y = sapply(geometry, function(g) fromJSON(g)$coordinates[2])
)
# Convert to sf, drop extra geometry fields
gdf <- st_as_sf(summary_data, coords = c("x", "y"), crs = 4326)
Visualization#
# Replace NA values in sum_pop_2020 with 0
gdf$sum_pop_2020[is.na(gdf$sum_pop_2020)] <- 0
# Create a custom binned color palette with non-uniform breaks
# For example: 0 (distinct color), 1-200000 (gradient), 200001+ (another color)
breaks <- c(0, 1, 1000, 10000, 50000, 100000, 200000, max(gdf$sum_pop_2020))
custom_pal <- colorBin(palette = c("lightgray", "yellow", "orange", "red", "purple", "blue"),
domain = gdf$sum_pop_2020, bins = breaks)
# Create the leaflet map with custom binned coloring
leaflet(gdf) %>%
addTiles() %>% # Add default OpenStreetMap map tiles
addCircleMarkers(
radius = 3, # Adjust size as needed
color = ~custom_pal(sum_pop_2020),
stroke = FALSE, fillOpacity = 0.7,
popup = ~paste("Hex ID:", hex_id, "<br>", "Population 2020:", sum_pop_2020) # Add a popup with details
) %>%
addLegend(
pal = custom_pal, values = gdf$sum_pop_2020, title = "Population 2020 (Custom Binned Scale)",
opacity = 1
)