Skip to content

Commit bbd6eb2

Browse files
committed
2 parents 35223ee + f179b89 commit bbd6eb2

57 files changed

Lines changed: 5193 additions & 221 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.quarto/xref/INDEX

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,8 @@
77
},
88
"vignettes/mapMementoR.qmd": {
99
"mapMementoR.html": "27879a28"
10+
},
11+
"pkgdown/gallery.qmd": {
12+
"gallery.html": "f1074075"
1013
}
1114
}

DESCRIPTION

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ Imports:
2727
utils,
2828
data.table,
2929
quarto,
30-
scales
30+
scales,
31+
geomtextpath
3132
Suggests:
3233
testthat (>= 3.0.0)
3334
Config/testthat/edition: 3

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export(choose_relief_colors)
4+
export(create_crop_mask)
45
export(create_memento_map)
56
export(geom_relief)
67
export(get_hillshade)
@@ -13,6 +14,7 @@ export(save_powerof10_to_yaml)
1314
import(data.table)
1415
import(dplyr)
1516
import(extrafont)
17+
import(geomtextpath)
1618
import(geosphere)
1719
import(gfonts)
1820
import(ggplot2)

R/create_crop_mask.R

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
##' Create a crop mask for map shapes
2+
##'
3+
##' This function generates a mask polygon that can be overlaid on a map to crop it to various shapes (circle, ellipse, etc.). The mask is a polygon with a hole in the desired shape.
4+
##'
5+
##' @param bbox Bounding box as a numeric vector c(xmin, ymin, xmax, ymax)
6+
##' @param crop_shape Shape to crop to. Options: "circle", "ellipse"
7+
##' @param bg_color Background color for the mask (should match plot background)
8+
##' @return A list with 'mask' (sf polygon object) and 'adjusted_bbox' (bbox, unchanged)
9+
##' @import sf
10+
##' @export
11+
##' @examples
12+
##' bbox <- c(-0.1, 51.5, 0.1, 51.6)
13+
##' result <- create_crop_mask(bbox, "circle", "#0a0e27")
14+
create_crop_mask <- function(bbox, crop_shape, bg_color) {
15+
if (is.null(crop_shape) || !crop_shape %in% c("circle", "ellipse")) {
16+
return(list(mask = NULL, adjusted_bbox = bbox))
17+
}
18+
19+
center_x <- base::mean(c(bbox[1], bbox[3]))
20+
center_y <- base::mean(c(bbox[2], bbox[4]))
21+
22+
# Create the inner boundary (the shape we want to preserve)
23+
if (crop_shape == "circle") {
24+
# For circle, use the smaller dimension as diameter to ensure it fits
25+
width <- bbox[3] - bbox[1]
26+
height <- bbox[4] - bbox[2]
27+
radius <- base::min(width, height) / 2
28+
29+
# Create circle coordinates
30+
angles <- base::seq(0, 2 * base::pi, length.out = 100)
31+
inner_coords <- base::data.frame(
32+
x = center_x + radius * base::cos(angles),
33+
y = center_y + radius * base::sin(angles)
34+
)
35+
} else if (crop_shape == "ellipse") {
36+
# Use bbox dimensions for ellipse (respects original aspect ratio)
37+
radius_x <- (bbox[3] - bbox[1]) / 2
38+
radius_y <- (bbox[4] - bbox[2]) / 2
39+
40+
angles <- base::seq(0, 2 * base::pi, length.out = 100)
41+
inner_coords <- base::data.frame(
42+
x = center_x + radius_x * base::cos(angles),
43+
y = center_y + radius_y * base::sin(angles)
44+
)
45+
}
46+
47+
# Create outer boundary (rectangular bbox)
48+
outer_coords <- base::data.frame(
49+
x = c(bbox[1], bbox[3], bbox[3], bbox[1], bbox[1]),
50+
y = c(bbox[2], bbox[2], bbox[4], bbox[4], bbox[2])
51+
)
52+
53+
# Create polygon with hole: outer boundary with inner boundary cut out
54+
# The hole is created by reversing the direction of the inner polygon
55+
mask_polygon <- sf::st_polygon(
56+
list(
57+
base::as.matrix(outer_coords[, c("x", "y")]),
58+
base::as.matrix(inner_coords[base::nrow(inner_coords):1, c("x", "y")])
59+
)
60+
)
61+
62+
# Convert to sfc and set CRS to match typical lat/lon
63+
mask_sf <- sf::st_sfc(mask_polygon, crs = 4326)
64+
65+
return(list(mask = mask_sf, adjusted_bbox = bbox))
66+
}

0 commit comments

Comments
 (0)