Nothing
tmapGridShape = function(bbx, facet_row, facet_col, facet_page, o) {
gts = get("gts", envir = .TMAP_GRID)
g = get("g", envir = .TMAP_GRID)
design = getOption("tmap.design.mode")
fbbx = bb_asp(bbx, g$fasp)
rc_text = frc(facet_row, facet_col)
rowid = g$rows_facet_ids[facet_row]
colid = g$cols_facet_ids[facet_col]
bg = if (o$earth_boundary) {
if (!o$space || design) o$space.color = NA
eotw = end_of_the_world(o$crs_step4, earth_datum = o$earth_datum)
grid::gList(rndrectGrob(gp=gpar(fill=o$space.color, lwd=NA, lineend="square"), r = o$frame.r * o$scale, name = "inner_rect"),
sf::st_as_grob(eotw, gp = grid::gpar(fill = o$bg.color, lwd = NA), name = "inner_world"))
} else if (design || !o$bg) {
NULL
} else {
rndrectGrob(gp=gpar(fill=o$bg.color, lwd=NA, lineend="square"), r = o$frame.r * o$scale, name = "inner_rect")
}
clip = if (is.na(o$bg.color) && o$earth_boundary && !o$space_overlay) {
grid::as.path(bg)
} else TRUE
gtmap = grid::grobTree(bg,
vp = grid::vpStack(grid::viewport(layout.pos.col = colid, layout.pos.row = rowid, name = paste0("vp_facet_", rc_text)),
grid::viewport(xscale = fbbx[c(1,3)], yscale = fbbx[c(2,4)], name = paste0("vp_map_", rc_text), clip = clip)), name = paste0("gt_facet_", rc_text))
gts[[facet_page]] = grid::addGrob(gts[[facet_page]], gtmap, gPath = grid::gPath("gt_main"))
assign("gts", gts, envir = .TMAP_GRID)
NULL
}
tmapGridOverlay = function(bbx, facet_row, facet_col, facet_page, o) {
gts = get("gts", envir = .TMAP_GRID)
g = get("g", envir = .TMAP_GRID)
gt = gts[[facet_page]]
rc_text = frc(facet_row, facet_col)
frame.lwd = if (!o$frame) 0 else o$frame.lwd * o$scale
r = o$frame.r * o$scale
boundary = if (o$earth_boundary) {
fbbx = bb_asp(bbx, g$fasp)
eotw = end_of_the_world(o$crs_step4, earth_datum = o$earth_datum)
sf::st_as_grob(eotw, gp = grid::gpar(fill = NA, col = o$earth_boundary.color, lwd = o$earth_boundary.lwd), name = "outer_world", vp = grid::viewport(xscale = fbbx[c(1,3)], yscale = fbbx[c(2,4)]))
} else NULL
gframe = if (o$frame) {
pH = convertHeight(unit(1, "points"), unitTo = "npc", valueOnly = TRUE)*frame.lwd
pW = convertWidth(unit(1, "points"), unitTo = "npc", valueOnly = TRUE)*frame.lwd
if (o$frame.double_line) {
bgcol = substr(o$bg.color, 1, 7) # remove transparency
grid::grobTree(
rndrectGrob(width = 1-4*pW, height=1-4*pH, gp=gpar(col=bgcol, fill=NA, lwd=4*frame.lwd, lineend="square"), r = r, name = "outer_frame"),
rndrectGrob(gp=gpar(col=o$frame.color, fill=NA, lwd=1.5*frame.lwd, lineend="square", alpha = o$frame.alpha), r = r, name = "between_frame"),
rndrectGrob(width = 1-8*pW, height=1-8*pH, gp=gpar(col=o$frame.color, fill=NA, lwd=frame.lwd, lineend="square", alpha = o$frame.alpha), r = r, name = "inner_frame"))
} else {
rndrectGrob(width = 1, height = 1, gp=gpar(col=o$frame.color, fill=NA, lwd=frame.lwd, lineend="square", alpha = o$frame.alpha), r = r, name = "outer_frame")
#rectGrob(width = 1-0.5*pW, height = 1-0.5*pH, gp=gpar(col=frame.col, fill=NA, lwd=frame.lwd, lineend="square"), name = "outer_frame")
}
} else NULL
rowid = g$rows_facet_ids[facet_row]
colid = g$cols_facet_ids[facet_col]
if (o$earth_boundary && o$space_overlay) {
space_fill = local({
if (o$frame) {
gframe_path = roundrect_to_pathGrob(gframe)
} else {
gframe_path = viewport_frame_path()
}
boundary_npc = local({
x = as.vector(boundary$x)
x2 = (x - boundary$vp$xscale[1]) / diff(boundary$vp$xscale)
y = as.vector(boundary$y)
y2 = (y - boundary$vp$yscale[1]) / diff(boundary$vp$yscale)
boundary$vp = NULL
boundary$x = unit(x2, "npc")
boundary$y = unit(y2, "npc")
boundary
})
combine_paths(gframe_path, boundary_npc, fill = o$space.color)
})
gt = gt |>
grid::addGrob(space_fill, paste0("gt_facet_", rc_text))
}
if (o$earth_boundary) {
gt = gt |>
grid::addGrob(boundary, paste0("gt_facet_", rc_text))
}
gt = gt |>
add_to_gt(gframe, row = rowid, col = colid)
gts[[facet_page]] = gt
assign("gts", gts, envir = .TMAP_GRID)
NULL
}
## functions to create a grob that draws space 'space'
## needed because clipping by earth boundary does not always work (e.g. not for rasterGrobs #1170)
combine_paths = function(pg1, pg2, rule = "winding", fill = "black") {
# Combine coordinates and assign IDs
combined_x = unit.c(pg1$x, pg2$x)
combined_y = unit.c(pg1$y, pg2$y)
combined_id = c(rep(1, length(pg1$x)), rep(2, length(pg2$x)))
# Return compound path
pathGrob(
x = combined_x,
y = combined_y,
id = combined_id,
rule = rule,
gp = gpar(fill = fill, col = NA)
)
}
roundrect_to_pathGrob = function(roundrect, n_corner = 10, fill = "black", col = NA, rule = "winding") {
stopifnot(inherits(roundrect, "roundrect"))
# Extract and convert parameters to NPC coordinates
x0 = convertX(roundrect$x - roundrect$width / 2, "npc", valueOnly = TRUE)
x1 = convertX(roundrect$x + roundrect$width / 2, "npc", valueOnly = TRUE)
y0 = convertY(roundrect$y - roundrect$height / 2, "npc", valueOnly = TRUE)
y1 = convertY(roundrect$y + roundrect$height / 2, "npc", valueOnly = TRUE)
rx = convertWidth(roundrect$r, "npc", valueOnly = TRUE)
ry = convertHeight(roundrect$r, "npc", valueOnly = TRUE)
# Clamp corner radius to avoid overlaps
rx = min(rx, (x1 - x0) / 2)
ry = min(ry, (y1 - y0) / 2)
# Helper: ellipse arc between angles
arc = function(cx, cy, rx, ry, start, end, n = 10) {
theta = seq(start, end, length.out = n)
list(
x = cx + rx * cos(theta),
y = cy + ry * sin(theta)
)
}
# Define corner arcs (clockwise from upper-left)
ul = arc(x0 + rx, y1 - ry, rx, ry, pi / 2, pi, n_corner)
ur = arc(x1 - rx, y1 - ry, rx, ry, 0, pi / 2, n_corner)
lr = arc(x1 - rx, y0 + ry, rx, ry, -pi / 2, 0, n_corner)
ll = arc(x0 + rx, y0 + ry, rx, ry, -pi, -pi / 2, n_corner)
# Assemble path: arcs and straight edges between them
x_coords = c(
rev(ul$x),
ur$x[n_corner],
rev(ur$x),
lr$x[n_corner],
rev(lr$x),
ll$x[n_corner],
rev(ll$x),
ul$x[n_corner]
)
y_coords = c(
rev(ul$y),
ur$y[n_corner],
rev(ur$y),
lr$y[n_corner],
rev(lr$y),
ll$y[n_corner],
rev(ll$y),
ul$y[n_corner]
)
# Return as filled path grob
pathGrob(
x = unit(x_coords, "npc"),
y = unit(y_coords, "npc"),
id = rep(1, length(x_coords)),
rule = rule,
gp = gpar(fill = fill, col = col)
)
}
viewport_frame_path = function(fill = "black", col = NA, rule = "winding") {
# Clockwise path around the viewport (0,0) to (1,1)
x = unit(rev(c(0, 1, 1, 0, 0)), "npc")
y = unit(rev(c(0, 0, 1, 1, 0)), "npc")
pathGrob(
x = x,
y = y,
id = rep(1, length(x)),
rule = rule,
gp = gpar(fill = fill, col = col)
)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.