Skip to content

Instantly share code, notes, and snippets.

@paleolimbot
Created June 12, 2019 16:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paleolimbot/1458846b37dbf34a991e8a95e899058a to your computer and use it in GitHub Desktop.
Save paleolimbot/1458846b37dbf34a991e8a95e899058a to your computer and use it in GitHub Desktop.
library(tidyverse)
library(sf)
box <- st_bbox(c(xmin = -120, xmax = -60, ymin = 45, ymax = 80), crs = 4326)
poly <- tibble(geometry = st_as_sfc(box)) %>% st_as_sf()
boundary <- st_cast(poly, "LINESTRING")
boundary_points <- st_make_grid(boundary, what = "corners") %>%
tibble(geometry = .) %>%
st_as_sf() %>%
filter(st_intersects(., boundary, sparse = FALSE))
boundary_df <- cbind(
as_tibble(boundary_points)[-1],
st_coordinates(boundary_points)
) %>%
mutate(
is_left = X == min(X),
is_right = X == max(X),
is_top = Y == max(Y),
is_bottom = Y == min(Y)
) %>%
crossing(tibble(side = c("top", "bottom", "left", "right"))) %>%
filter(
(side == "left" & is_left) |
(side == "right" & is_right) |
(side == "top" & is_top) |
(side == "bottom" & is_bottom)
) %>%
arrange(side, X, Y) %>%
group_by(side) %>%
transmute(
x = X,
y = Y,
i = 1:n(),
xend = lead(x),
yend = lead(y),
col = if_else(i %% 2 == 0, "black", "white")
) %>%
ungroup() %>%
filter(!is.na(xend), !is.na(yend))
boundary_df_projected <- cbind(
boundary_df %>% select(side, i),
ggspatial::xy_transform(boundary_df$x, boundary_df$y, to = 3979),
ggspatial::xy_transform(boundary_df$xend, boundary_df$yend, to = 3979) %>%
set_names(c("xend", "yend"))
)
ggplot() +
geom_segment(
aes(x, y, xend = xend, yend = yend),
boundary_df_projected %>% filter(i %% 2 == 0),
col = "white"
) +
geom_segment(
aes(x, y, xend = xend, yend = yend),
boundary_df_projected %>% filter(i %% 2 != 0),
col = "black"
) +
coord_sf(crs = 3979)
@paleolimbot
Copy link
Author

library(tidyverse)
#> Registered S3 methods overwritten by 'ggplot2':
#>   method         from 
#>   [.quosures     rlang
#>   c.quosures     rlang
#>   print.quosures rlang
#> Registered S3 method overwritten by 'rvest':
#>   method            from
#>   read_xml.response xml2
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.1.3, PROJ 4.9.3

box <- st_bbox(c(xmin = -120, xmax = -60, ymin = 45, ymax = 80), crs = 4326)
poly <- tibble(geometry = st_as_sfc(box)) %>% st_as_sf()
boundary <- st_cast(poly, "LINESTRING")

boundary_points <- st_make_grid(boundary, what = "corners") %>%
  tibble(geometry = .) %>%
  st_as_sf() %>%
  filter(st_intersects(., boundary, sparse = FALSE))
#> although coordinates are longitude/latitude, st_intersects assumes that they are planar


boundary_df <- cbind(
  as_tibble(boundary_points)[-1], 
  st_coordinates(boundary_points)
) %>%
  mutate(
    is_left = X == min(X),
    is_right = X == max(X),
    is_top = Y == max(Y),
    is_bottom = Y == min(Y)
  ) %>%
  crossing(tibble(side = c("top", "bottom", "left", "right"))) %>%
  filter(
    (side == "left" & is_left) | 
      (side == "right" & is_right) |
      (side == "top" & is_top) |
      (side == "bottom" & is_bottom)
  ) %>%
  arrange(side, X, Y) %>%
  group_by(side) %>%
  transmute(
    x = X,
    y = Y,
    i = 1:n(),
    xend = lead(x),
    yend = lead(y), 
    col = if_else(i %% 2 == 0, "black", "white")
  ) %>%
  ungroup() %>%
  filter(!is.na(xend), !is.na(yend))

boundary_df_projected <- cbind(
  boundary_df %>% select(side, i),
  ggspatial::xy_transform(boundary_df$x, boundary_df$y, to = 3979),
  ggspatial::xy_transform(boundary_df$xend, boundary_df$yend, to = 3979) %>%
    set_names(c("xend", "yend"))
)

ggplot() +
  geom_segment(
    aes(x, y, xend = xend, yend = yend),
    boundary_df_projected %>% filter(i %% 2 == 0),
    col = "white"
  ) +
  geom_segment(
    aes(x, y, xend = xend, yend = yend),
    boundary_df_projected %>% filter(i %% 2 != 0),
    col = "black"
  ) +
  coord_sf(crs = 3979)

Created on 2019-06-12 by the reprex package (v0.2.1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment