This commit is contained in:
mattbk
2026-03-01 09:51:13 -06:00
commit 3d005fdc82
3 changed files with 105 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.Rproj.user
.Rhistory
.RData
.Ruserdata

13
farpn-map.Rproj Normal file
View File

@@ -0,0 +1,13 @@
Version: 1.0
RestoreWorkspace: Default
SaveWorkspace: Default
AlwaysSaveHistory: Default
EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 4
Encoding: UTF-8
RnwWeave: Sweave
LaTeX: pdfLaTeX

88
src/farpn-map.R Normal file
View File

@@ -0,0 +1,88 @@
library(jsonlite)
library(sf)
library(dplyr)
library(tidyr)
library(ggplot2)
library(geosphere)
library(rnaturalearth)
# API URL
api_spots <- "http://[300:6f6a:b087:4dda::8]/api/v1/spots"
# Get the spots
spots_raw <- fromJSON(api_spots) %>% mutate(across(c(de_longitude, de_latitude,
dx_longitude, dx_latitude),
as.numeric))
# Convert to spatial
spots <- spots_raw %>% st_as_sf(coords = c("dx_longitude", "dx_latitude"),
crs = "EPSG:4326")
spotters <- spots_raw %>% st_as_sf(coords = c("de_longitude", "de_latitude"),
crs = "EPSG:4326")
# Make lines
# https://stackoverflow.com/a/76197010
lines <- bind_rows(spots, spotters) %>%
group_by(id) %>%
dplyr::summarize(do_union=FALSE) %>% # do_union=FALSE doesn't work as well
st_cast("LINESTRING")
# Make geodesic lines
great_circles_list <- list()
for(i in 1:nrow(spots_raw)){
great_circles_list[[i]] <- as.data.frame(gcIntermediate(c(spots_raw[i,"dx_longitude"], spots_raw[i,"dx_latitude"]),
c(spots_raw[i,"de_longitude"], spots_raw[i,"de_latitude"])))
names(great_circles_list)[[i]] <- spots_raw[i,"id"]
}
great_circles <- bind_rows(great_circles_list,
.id = "id") %>%
st_as_sf(coords = c("lon", "lat"),
crs = "EPSG:4326") %>%
group_by(id) %>%
dplyr::summarize(do_union=FALSE) %>% # do_union=FALSE doesn't work as well
st_cast("LINESTRING") %>%
left_join(spots_raw, by = "id")
station_bbox <- matrix(c(st_bbox(spots),
st_bbox(spotters)),
nrow = 4,
ncol = 2) %>%
t() %>%
as.data.frame() %>%
summarize(xmin = min(V1),
ymin = min(V2),
xmax = max(V3),
ymax = max(V4))
# Pull in GIS basemaps etc.
countries <- ne_download(
scale = 50,
type = "admin_0_countries",
category = "cultural",
returnclass = "sf"
)
borders <- ne_download(
scale = 50,
type = "admin_1_states_provinces",
category = "cultural",
returnclass = "sf"
)
# Make simple map
ggplot() +
geom_sf(data = countries) +
geom_sf(data = borders) +
geom_sf(data = great_circles,
aes(color = band)) +
geom_sf(data = spots) +
geom_sf(data = spotters,
color = "green") +
geom_sf_text(data = spotters,
aes(label = de_call)) +
coord_sf(crs = "EPSG:4269",
xlim = c(station_bbox$xmin, station_bbox$xmax),
ylim = c(station_bbox$ymin, station_bbox$ymax)) +
theme_bw()