| Title: | Hierarchical Exploded-View Cartography |
|---|---|
| Description: | Tools for generating hierarchical exploded-view maps from dense administrative boundary data. The package applies rigid-body translations to polygon geometries using a centroid-driven vector field, preserving the internal geometry of each feature while separating units within and across regions. Parameters can be derived analytically from dataset geometry using closed-form models for regional separation and local expansion. The package also includes grouped layouts, optional bounded collision refinement, and an interactive focus-map widget for selected-area inspection in 'htmlwidgets' and 'Shiny'. It implements the methodology described in George Arthur (2026) <https://github.com/PrigasG/explodemap> "A Hierarchical Vector-Based Framework for Multi-Scale Exploded-View Cartography". |
| Authors: | George Arthur [aut, cre] |
| Maintainer: | George Arthur <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.3.0 |
| Built: | 2026-06-27 11:32:03 UTC |
| Source: | https://github.com/prigasg/explodemap |
Applies rigid display offsets to all features in each named region. This is intended as a reproducible finishing step for publication or dashboard layouts after an exploded map has already been computed.
apply_region_offsets( x, offsets, region_col = NULL, offset_region_col = "region", dx_col = "dx_m", dy_col = "dy_m", update_plots = TRUE )apply_region_offsets( x, offsets, region_col = NULL, offset_region_col = "region", dx_col = "dx_m", dy_col = "dy_m", update_plots = TRUE )
x |
An |
offsets |
A data frame, or a path to a CSV file, containing one row per region and numeric offset columns. |
region_col |
Name of the region column in |
offset_region_col |
Name of the region column in |
dx_col |
Name of the horizontal offset column in |
dy_col |
Name of the vertical offset column in |
update_plots |
Logical; when |
Offsets are interpreted in the coordinate units of the projected
geometry being adjusted. The default column names dx_m and
dy_m assume a metric projected CRS, matching the package's
exploded-map workflow.
For an sf input, an sf object with the same attributes
and CRS as x; geometries belonging to each listed region are
translated by the supplied offsets, and the normalized offset table is
stored in the display_offsets attribute. For an
exploded_map, returns the same S3 object structure with
sf_exp, sf_exp_wgs, stored plots, and
display_offsets updated. For a grouped_exploded_map,
returns the same S3 object structure with sf_grouped,
sf_grouped_wgs, stored plots, and display_offsets updated.
The offsets are rigid translations, so polygon shape, area, and
within-region relative geometry are preserved.
library(sf) x <- st_sf( region = c("A", "B"), geometry = st_sfc( st_point(c(0, 0)), st_point(c(10, 0)), crs = 3857 ) ) offsets <- data.frame(region = "B", dx_m = 5, dy_m = 2) apply_region_offsets(x, offsets, region_col = "region")library(sf) x <- st_sf( region = c("A", "B"), geometry = st_sfc( st_point(c(0, 0)), st_point(c(10, 0)), crs = 3857 ) ) offsets <- data.frame(region = "B", dx_m = 5, dy_m = 2) apply_region_offsets(x, offsets, region_col = "region")
Legacy / low-level handoff (superseded, but not deprecated).
This is the original handoff: it bundles the grouped geometry and
the absolute anchors into a dragmapr_layout list. The preferred path is now
as_dragmapr_state(), which emits a geometry-free dragmapr::dragmapr_state()
– the shared editorial composition contract that state = arguments accept
across focus_map(), render_dragged_map(), and update_exploded_layout().
as_dragmapr() remains supported for existing offset-table / CSV workflows
and is not scheduled for removal, but new code should prefer the state-first
API.
as_dragmapr(result)as_dragmapr(result)
result |
A |
A dragmapr_layout list containing editable sf geometry and anchors.
as_dragmapr_state() for the preferred state-first handoff.
Produces a dragmapr::dragmapr_state() – the shared editorial composition
contract – from a grouped_exploded_map. Unlike as_dragmapr(), which
bundles geometry and absolute anchors into a handoff list, this emits the
geometry-free state that the interactive editor and static renderers
consume: the exploded anchors (anchor_x/anchor_y) are converted to the
metre deltas (dx_m/dy_m) relative to the current region centroids that
dragmapr expects, and the projected CRS plus a provenance geometry_id
are recorded so the state can be reapplied safely in a later session.
as_dragmapr_state(result, geometry_id = NULL, level = NULL)as_dragmapr_state(result, geometry_id = NULL, level = NULL)
result |
A |
geometry_id |
Optional single string identifying the source geometry.
Defaults to the layout label in |
level |
Optional geography-level label. Defaults to the region column. |
Keep layout (the computed geometry + diagnostics, i.e. result) and
state (this editorial overlay) separate. The layout can be recomputed
freely while the state preserves manual edits, which is what makes the
compute -> compose -> render workflow reproducible.
A dragmapr_state (see dragmapr::dragmapr_state()).
Adds hhs_region, state_label, and state_geoid columns to state or
territory polygons and transforms long-lat data to a projected CRS.
as_hhs_states(states, crs = 5070)as_hhs_states(states, crs = 5070)
states |
An |
crs |
Target projected CRS used when |
An sf object filtered to HHS-assigned states and territories.
Assign generated spatial groups
assign_spatial_groups( x, method = c("quadrants", "clusters", "individual"), groups = 6L, seed = 1L, group_col = "region" )assign_spatial_groups( x, method = c("quadrants", "clusters", "individual"), groups = 6L, seed = 1L, group_col = "region" )
x |
An |
method |
One of |
groups |
Number of clusters for |
seed |
Random seed for deterministic clustering. |
group_col |
Name of the output grouping column. |
x with group_col assigned.
Clear explodemap download cache
cache_clear(key = NULL)cache_clear(key = NULL)
key |
Specific cache key to clear, or NULL to clear all |
Invisibly returns NULL. The function is called for its side effect
of deleting cached .rds files and reporting what was removed.
List cached datasets
cache_list()cache_list()
Invisibly returns a character vector of cached .rds file names.
The visible output is a message listing the cache directory and file sizes,
or a message that the cache is empty.
Returns a one-row data.frame suitable for binding across datasets to build a calibration table.
calibration_row(x)calibration_row(x)
x |
An |
A one-row data.frame
Extracts w_bar, R_local, n_bar, n_regions, and the tightness ratio from a projected sf object with a grouping column.
compute_stats( sf_obj, region_col, centroid_fun = c("centroid", "point_on_surface") )compute_stats( sf_obj, region_col, centroid_fun = c("centroid", "point_on_surface") )
sf_obj |
Projected sf object |
region_col |
Name of the grouping column |
centroid_fun |
"centroid" (default) or "point_on_surface" |
A named list of geometry statistics
Counts coordinate rows in an sf or sfc object. This is a lightweight
utility for upload limits, performance warnings, simplification decisions,
and diagnostics.
count_geometry_vertices(x)count_geometry_vertices(x)
x |
An |
A single numeric vertex count.
Implements Analytical Results 1 and 2 from the paper: alpha_r = gamma_r * w_bar / (2 * sin(pi / n_regions)) alpha_l = gamma_l * 2 * R_local / sqrt(n_bar)
derive_params(stats, gamma_r = 3, gamma_l = 1.136, p = 1.25)derive_params(stats, gamma_r = 3, gamma_l = 1.136, p = 1.25)
stats |
Output of |
gamma_r |
Regional clearance coefficient (default 3.0) |
gamma_l |
Local clearance coefficient (default 1.136) |
p |
Distance scaling exponent (default 1.25) |
Named list with alpha_r, alpha_l, p, gamma_r, gamma_l
Diagnose grouped layout quality
diagnose_layout(result, label_col = NULL, label_size = NULL)diagnose_layout(result, label_col = NULL, label_size = NULL)
result |
A |
label_col |
Optional label column for approximate label overlap checks. |
label_size |
Approximate label size in map units. |
A layout_quality_report list.
Computes the 85th percentile of distances from child-unit centroids to their region centroid. The 85th percentile is preferred over the maximum because the maximum is sensitive to outlier units and produces over-conservative block radii.
estimate_block_radii( sf_obj, region_col, quantile_p = 0.85, centroid_fun = c("centroid", "point_on_surface") )estimate_block_radii( sf_obj, region_col, quantile_p = 0.85, centroid_fun = c("centroid", "point_on_surface") )
sf_obj |
Projected sf object with region column |
region_col |
Grouping column name |
quantile_p |
Quantile for radius estimation (default 0.85) |
centroid_fun |
"centroid" or "point_on_surface" |
data.frame with columns: region, block_radius, cx, cy, n_units
Combines Level 1 (local explosion within regions) with Level 2/3 (anchor-based region block placement). This is the full three-level extension from Section 12 of the paper.
explode_grouped( sf_obj, region_col, mode = c("auto", "auto_collision", "manual"), anchors = NULL, initial_layout = NULL, preserve_manual = FALSE, alpha_l = NULL, p = 1.25, gamma_l = 1.136, kappa = 1.8, padding = 50000, delta = 15000, lambda = 0.18, eta = 0.18, padding_sep = 20000, anchor_expand = NULL, anchor_buffer = NULL, density_scale = NULL, block_sep = NULL, max_iter = 60, fix_invalid = TRUE, centroid_fun = c("centroid", "point_on_surface"), plot = TRUE, export = NULL, label = "Grouped Layout", quiet = FALSE )explode_grouped( sf_obj, region_col, mode = c("auto", "auto_collision", "manual"), anchors = NULL, initial_layout = NULL, preserve_manual = FALSE, alpha_l = NULL, p = 1.25, gamma_l = 1.136, kappa = 1.8, padding = 50000, delta = 15000, lambda = 0.18, eta = 0.18, padding_sep = 20000, anchor_expand = NULL, anchor_buffer = NULL, density_scale = NULL, block_sep = NULL, max_iter = 60, fix_invalid = TRUE, centroid_fun = c("centroid", "point_on_surface"), plot = TRUE, export = NULL, label = "Grouped Layout", quiet = FALSE )
sf_obj |
Projected sf object with region column |
region_col |
Grouping column name |
mode |
"auto", "auto_collision", or "manual" |
anchors |
For mode = "manual": data.frame with anchor positions |
initial_layout |
Optional existing/manual anchor layout used when
|
preserve_manual |
When |
alpha_l |
Local expansion parameter for Level 1 (metres) |
p |
Distance scaling exponent (default 1.25) |
gamma_l |
Local clearance coefficient (default 1.136); used if alpha_l is NULL |
kappa |
Radial expansion factor (default 1.8) |
padding |
Base padding (default 50000) |
delta |
Log-density scaling (default 15000) |
lambda |
Spring coefficient (default 0.18) |
eta |
Repulsion step (default 0.18) |
padding_sep |
Minimum block separation (default 20000) |
anchor_expand, anchor_buffer, density_scale, block_sep
|
Optional aliases
for |
max_iter |
Max collision iterations (default 60) |
fix_invalid |
Auto-repair invalid geometries (default TRUE) |
centroid_fun |
"centroid" or "point_on_surface" |
plot |
Print plots (default TRUE). Automatically suppressed inside a
live Shiny session; use |
export |
NULL, TRUE, or file path |
label |
Title for plots |
quiet |
If |
The guarantees of Propositions 1-3 apply strictly at Level 1. Higher levels preserve structural grouping and directional correspondence rather than topological coverage.
A grouped_exploded_map S3 object (inherits from exploded_map)
explode_section() is a dashboard-oriented helper for exploratory maps.
It applies an exploded layout only to the requested section, then recombines
the untouched remainder of the layer as geographic context. The result can
be passed directly to focus_map() with context_col to fade or hide the
non-selected features.
explode_section( sf_obj, section_col, section, region_col = section_col, layout = c("explode", "grouped"), context = c("fade", "hide", "none"), role_col = ".explodemap_role", all_values = "all", ... )explode_section( sf_obj, section_col, section, region_col = section_col, layout = c("explode", "grouped"), context = c("fade", "hide", "none"), role_col = ".explodemap_role", all_values = "all", ... )
sf_obj |
Projected |
section_col |
Column containing the high-level sections users choose
from, such as |
section |
Selected section value. Values in |
region_col |
Column used for the explosion inside the selected section.
Defaults to |
layout |
|
context |
|
role_col |
Name of the role column added to the output. Focus features
are marked |
all_values |
Values that mean "all sections". Default |
... |
Passed to |
An exploded_map or grouped_exploded_map object with recombined
focus/context geometry and extra diagnostics.
poly <- function(xmin, ymin, xmax, ymax) { sf::st_polygon(list(rbind( c(xmin, ymin), c(xmax, ymin), c(xmax, ymax), c(xmin, ymax), c(xmin, ymin) ))) } municipalities <- sf::st_sf( NAME = c("A", "B", "C", "D"), nj_region = c("South", "South", "North", "North"), county_name = c("Atlantic", "Cape May", "Bergen", "Hudson"), geometry = sf::st_sfc( poly(0, 0, 1000, 1000), poly(2000, 0, 3000, 1000), poly(0, 2000, 1000, 3000), poly(2000, 2000, 3000, 3000), crs = 3857 ) ) focused <- explode_section( municipalities, section_col = "nj_region", section = "South", region_col = "county_name", alpha_r = 1800, alpha_l = 1200, plot = FALSE, quiet = TRUE ) focus_map( focused, label_col = "NAME", context_col = ".explodemap_role", context_mode = "fade" )poly <- function(xmin, ymin, xmax, ymax) { sf::st_polygon(list(rbind( c(xmin, ymin), c(xmax, ymin), c(xmax, ymax), c(xmin, ymax), c(xmin, ymin) ))) } municipalities <- sf::st_sf( NAME = c("A", "B", "C", "D"), nj_region = c("South", "South", "North", "North"), county_name = c("Atlantic", "Cape May", "Bergen", "Hudson"), geometry = sf::st_sfc( poly(0, 0, 1000, 1000), poly(2000, 0, 3000, 1000), poly(0, 2000, 1000, 3000), poly(2000, 2000, 3000, 3000), crs = 3857 ) ) focused <- explode_section( municipalities, section_col = "nj_region", section = "South", region_col = "county_name", alpha_r = 1800, alpha_l = 1200, plot = FALSE, quiet = TRUE ) focus_map( focused, label_col = "NAME", context_col = ".explodemap_role", context_mode = "fade" )
Explode any sf object with an existing grouping column
explode_sf( sf_obj, region_col = "region", gamma_r = 3, gamma_l = 1.136, p = 1.25, alpha_r = NULL, alpha_l = NULL, refine = FALSE, refine_min_gap = NULL, refine_max_shift = NULL, refine_max_iter = 20, refine_step = 0.5, refine_within = c("region", "all"), allow_other = FALSE, fix_invalid = TRUE, centroid_fun = c("centroid", "point_on_surface"), plot = TRUE, export = NULL, label = "Custom Dataset", quiet = FALSE )explode_sf( sf_obj, region_col = "region", gamma_r = 3, gamma_l = 1.136, p = 1.25, alpha_r = NULL, alpha_l = NULL, refine = FALSE, refine_min_gap = NULL, refine_max_shift = NULL, refine_max_iter = 20, refine_step = 0.5, refine_within = c("region", "all"), allow_other = FALSE, fix_invalid = TRUE, centroid_fun = c("centroid", "point_on_surface"), plot = TRUE, export = NULL, label = "Custom Dataset", quiet = FALSE )
sf_obj |
Projected sf object (metric CRS) |
region_col |
Name of the column defining groups |
gamma_r |
Regional clearance coefficient (default 3.0) |
gamma_l |
Local clearance coefficient (default 1.136) |
p |
Distance scaling exponent (default 1.25) |
alpha_r |
Optional manual override for regional separation (metres).
May be supplied independently of |
alpha_l |
Optional manual override for local expansion (metres).
May be supplied independently of |
refine |
If TRUE, apply a bounded collision-refinement pass after the analytical displacement. Default is FALSE. |
refine_min_gap |
Optional minimum boundary-to-boundary gap in map units.
If NULL and |
refine_max_shift |
Optional maximum correction per feature in map units.
If NULL and |
refine_max_iter |
Maximum refinement iterations. |
refine_step |
Fraction of each gap deficit corrected per iteration. |
refine_within |
Refine pairs within each |
allow_other |
If TRUE, permits "Other" units |
fix_invalid |
If TRUE, auto-repairs invalid geometries |
centroid_fun |
"centroid" (default) or "point_on_surface" |
plot |
Print plots on return. Automatically suppressed when called
inside a live Shiny session; use |
export |
NULL, TRUE, or file path |
label |
Title for plots |
quiet |
If |
An exploded_map S3 object
Joins the lookup to sf_obj before exploding. Unmatched units are
labelled "Other".
explode_sf_with_lookup( sf_obj, join_col, lookup, lookup_key = join_col, region_col = "region", quiet = FALSE, ... )explode_sf_with_lookup( sf_obj, join_col, lookup, lookup_key = join_col, region_col = "region", quiet = FALSE, ... )
sf_obj |
Projected sf object |
join_col |
Column in sf_obj to join on |
lookup |
data.frame with join key and region column |
lookup_key |
Column name in lookup matching join_col |
region_col |
Column name in lookup containing region labels |
quiet |
If |
... |
Passed to |
An exploded_map S3 object
Downloads administrative boundaries automatically, groups them into regions,
derives displacement parameters via Analytical Results 1-2, and returns an
exploded_map S3 object.
explode_state( state_fips = NULL, crs = NULL, region_map = NULL, level = c("cousub", "county"), n_regions = NULL, sf_data = NULL, gamma_r = 3, gamma_l = 1.136, p = 1.25, alpha_r = NULL, alpha_l = NULL, refine = FALSE, refine_min_gap = NULL, refine_max_shift = NULL, refine_max_iter = 20, refine_step = 0.5, refine_within = c("region", "all"), allow_other = FALSE, fix_invalid = TRUE, centroid_fun = c("centroid", "point_on_surface"), plot = TRUE, export = NULL, label = if (!is.null(state_fips)) paste0("FIPS ", state_fips) else "Custom Dataset", quiet = FALSE )explode_state( state_fips = NULL, crs = NULL, region_map = NULL, level = c("cousub", "county"), n_regions = NULL, sf_data = NULL, gamma_r = 3, gamma_l = 1.136, p = 1.25, alpha_r = NULL, alpha_l = NULL, refine = FALSE, refine_min_gap = NULL, refine_max_shift = NULL, refine_max_iter = 20, refine_step = 0.5, refine_within = c("region", "all"), allow_other = FALSE, fix_invalid = TRUE, centroid_fun = c("centroid", "point_on_surface"), plot = TRUE, export = NULL, label = if (!is.null(state_fips)) paste0("FIPS ", state_fips) else "Custom Dataset", quiet = FALSE )
state_fips |
2-digit FIPS code (e.g. |
crs |
Projected CRS EPSG code (metric units, e.g. |
region_map |
Named list mapping region labels to county/COUSUB name
vectors (e.g. |
level |
Boundary level: |
n_regions |
For |
sf_data |
Optional pre-projected |
gamma_r |
Regional clearance coefficient (default 3.0) |
gamma_l |
Local clearance coefficient (default 1.136) |
p |
Distance scaling exponent (default 1.25) |
alpha_r |
Optional manual override for regional separation (metres).
May be supplied independently of |
alpha_l |
Optional manual override for local expansion (metres).
May be supplied independently of |
refine |
If TRUE, apply a bounded collision-refinement pass after the analytical displacement. Default is FALSE. |
refine_min_gap |
Optional minimum boundary-to-boundary gap in map units.
If NULL and |
refine_max_shift |
Optional maximum correction per feature in map units.
If NULL and |
refine_max_iter |
Maximum refinement iterations. |
refine_step |
Fraction of each gap deficit corrected per iteration. |
refine_within |
Refine pairs within each |
allow_other |
If TRUE, permits units mapped to "Other" |
fix_invalid |
If TRUE, auto-repairs invalid geometries |
centroid_fun |
|
plot |
Print plots on return (default TRUE). Automatically suppressed
when called inside a live Shiny session; use |
export |
NULL (no export), TRUE (auto-named GeoJSON), or a file path |
label |
Title for plots and print output |
quiet |
If |
Two boundary levels are supported via the level argument:
"cousub" (default) — Census county subdivision (COUSUB) units.
Best for the northeastern and midwestern states where municipalities
tile the state completely. Requires a named region_map.
"county" — county-level boundaries.
Works well for all 50 states. region_map is optional: when omitted,
regions are assigned automatically by k-means clustering on county
centroids. Pass n_regions to override the automatic cluster count.
You can bypass the TIGER/Line download entirely by passing a pre-projected
sf object via sf_data. The state_fips argument is then only used for
the default label; it may be omitted if you supply your own label.
An exploded_map S3 object
Fingerprint explodemap geometry and grouping
explodemap_fingerprint( x, id_col = NULL, group_col = NULL, include_geometry = TRUE )explodemap_fingerprint( x, id_col = NULL, group_col = NULL, include_geometry = TRUE )
x |
An |
id_col |
Optional feature ID column. |
group_col |
Optional group column. |
include_geometry |
Include EWKB geometry bytes. |
A stable MD5 fingerprint string.
Converts an sf, exploded_map, or grouped_exploded_map object to
TopoJSON using the external mapshaper command-line tool. The input is
first written as a temporary GeoJSON file, then converted by mapshaper.
export_topojson(x, file, simplify = NULL, overwrite = FALSE)export_topojson(x, file, simplify = NULL, overwrite = FALSE)
x |
An |
file |
Output file path. Should end in |
simplify |
Optional simplification proportion passed to
|
overwrite |
Logical; if |
This is intended as a convenience helper for downstream tools such as Power BI, D3.js, and Observable that prefer or require TopoJSON input.
This function requires the external mapshaper command-line tool to be
installed and available on the system path. It can be installed with:
npm install -g mapshaper
The mapshaper tool is not an R package dependency; it is invoked via
system2(). If mapshaper is not found, the function errors with an
informative message.
Invisibly returns the output file path.
## Not run: # Two-level export result <- explode_sf(my_sf, region_col = "region", plot = FALSE) export_topojson(result, "exploded.topojson") # Three-level grouped export grp <- explode_grouped(my_sf, region_col = "region", plot = FALSE) export_topojson(grp, "grouped.topojson") # With simplification (breaks Proposition 1 guarantee) export_topojson(result, "simplified.topojson", simplify = 0.5) # Raw sf object export_topojson(my_sf, "raw.topojson", overwrite = TRUE) ## End(Not run)## Not run: # Two-level export result <- explode_sf(my_sf, region_col = "region", plot = FALSE) export_topojson(result, "exploded.topojson") # Three-level grouped export grp <- explode_grouped(my_sf, region_col = "region", plot = FALSE) export_topojson(grp, "grouped.topojson") # With simplification (breaks Proposition 1 guarantee) export_topojson(result, "simplified.topojson", simplify = 0.5) # Raw sf object export_topojson(my_sf, "raw.topojson", overwrite = TRUE) ## End(Not run)
Renders spatial features as a smooth, interactive SVG map. Click any polygon to zoom in and lift it from the map with a "toast" effect; right-click or press Escape to reset. Camera transitions use D3's optimal zoom interpolation for fluid 60 fps motion with zero server round-trips.
focus_map( x, label_col = NULL, id_col = NULL, group_col = NULL, group_palette = NULL, context_col = NULL, state = NULL, restore_selection = FALSE, context_values = "context", context_mode = c("fade", "hide", "show"), coordinate_system = c("auto", "longlat", "planar"), context_fill = "#cfd9df", context_opacity = 0.18, context_clickable = FALSE, focus_preset = c("none", "municipal", "drilldown", "municipal_drilldown"), simplify = TRUE, fill = "#2d6ea3", fill_opacity = 0.58, stroke = "#ffffff", lift_scale = 1.16, focus_padding = 40, focus_size = 0.76, min_focus_width = 0, min_focus_height = 0, tiny_feature_threshold = 48, tiny_feature_boost = 1, max_zoom = NULL, origin_context = c("none", "socket", "inset", "both"), origin_context_position = c("bottom-left", "bottom-right", "top-left", "top-right"), focus_context_opacity = 0.3, show_drag_zoom = FALSE, show_group_labels = FALSE, group_labels = NULL, font_size = 14, show_labels = TRUE, show_sidebar = TRUE, performance_mode = NULL, info_cols = NULL, info_labels = NULL, info_title = NULL, info_position = c("top-right", "top-left", "bottom-right", "bottom-left"), info_card_scale = 1, area_min = 5000, width_min = 95, height_min = 28, width = "100%", height = "600px", elementId = NULL ) focusmapOutput(outputId, width = "100%", height = "600px") renderFocusmap(expr, env = parent.frame(), quoted = FALSE)focus_map( x, label_col = NULL, id_col = NULL, group_col = NULL, group_palette = NULL, context_col = NULL, state = NULL, restore_selection = FALSE, context_values = "context", context_mode = c("fade", "hide", "show"), coordinate_system = c("auto", "longlat", "planar"), context_fill = "#cfd9df", context_opacity = 0.18, context_clickable = FALSE, focus_preset = c("none", "municipal", "drilldown", "municipal_drilldown"), simplify = TRUE, fill = "#2d6ea3", fill_opacity = 0.58, stroke = "#ffffff", lift_scale = 1.16, focus_padding = 40, focus_size = 0.76, min_focus_width = 0, min_focus_height = 0, tiny_feature_threshold = 48, tiny_feature_boost = 1, max_zoom = NULL, origin_context = c("none", "socket", "inset", "both"), origin_context_position = c("bottom-left", "bottom-right", "top-left", "top-right"), focus_context_opacity = 0.3, show_drag_zoom = FALSE, show_group_labels = FALSE, group_labels = NULL, font_size = 14, show_labels = TRUE, show_sidebar = TRUE, performance_mode = NULL, info_cols = NULL, info_labels = NULL, info_title = NULL, info_position = c("top-right", "top-left", "bottom-right", "bottom-left"), info_card_scale = 1, area_min = 5000, width_min = 95, height_min = 28, width = "100%", height = "600px", elementId = NULL ) focusmapOutput(outputId, width = "100%", height = "600px") renderFocusmap(expr, env = parent.frame(), quoted = FALSE)
x |
An |
label_col |
Character. Column name for polygon labels.
Auto-detected if |
id_col |
Optional stable feature ID column for Shiny selection events.
Defaults to row order if |
group_col |
Character. Optional column for region/group colouring. Polygons sharing a group value share a hue. |
group_palette |
Optional named character vector of colours for
|
context_col |
Optional column identifying features that should remain as geographic context rather than active focus features. |
state |
Optional |
restore_selection |
When |
context_values |
Character vector of values in |
context_mode |
How context features are drawn: |
coordinate_system |
Coordinate system used by the widget. |
context_fill |
Fill colour for context features when
|
context_opacity |
Fill opacity for faded context features. |
context_clickable |
Should context features remain clickable? Default
|
focus_preset |
Optional named preset for common interactive workflows.
|
simplify |
Controls geometry simplification for rendering
performance. |
fill |
Fill colour (used when |
fill_opacity |
Fill opacity. Default |
stroke |
Stroke colour. Default |
lift_scale |
Initial toast lift scale. Default |
focus_padding |
Extra screen-space padding in pixels around the lifted feature during focus. Increase this if large lifted features feel too close to the map edge. |
focus_size |
Target fraction of the map viewport the lifted feature
may occupy. Increase this to make selected areas appear larger while
preserving |
min_focus_width, min_focus_height
|
Minimum focused feature width and
height in screen pixels. When a selected feature is very small, the widget
may zoom past the usual density-aware default until the lifted feature
reaches these dimensions. Set to |
tiny_feature_threshold |
Screen-pixel size below which a selected
feature receives an adaptive lift-scale boost. Set to |
tiny_feature_boost |
Maximum multiplier applied to |
max_zoom |
Optional maximum camera zoom. If |
origin_context |
How the selected feature's source location should be
shown while focused. The default |
origin_context_position |
Position for the overview inset:
|
focus_context_opacity |
Fill opacity for non-selected features while a feature is focused. Lower values make tiny selected areas easier to read. |
show_drag_zoom |
Show a widget-level drag-zoom toggle. When enabled, users can draw a marquee rectangle to zoom into dense clusters while ordinary feature clicks continue to focus the map. Shift-drag works as a shortcut even when the button is hidden. |
show_group_labels |
Show one passive label per |
group_labels |
Optional named character vector or list for
|
font_size |
Label font size in px. Default |
show_labels |
Show labels on lifted shapes? Default |
show_sidebar |
Deprecated and has no effect. Will be removed in a future version. |
performance_mode |
Logical or |
info_cols |
Optional character vector of columns to show in a non-blocking focus card when a feature is selected. |
info_labels |
Optional named character vector or list for display
labels in the focus card. Names should match |
info_title |
Optional column to use as the focus card title. Defaults
to |
info_position |
Position for the focus card: |
info_card_scale |
Relative size for the focus card. Values above
|
area_min |
Min screen area (px^2) for label visibility. |
width_min |
Min screen width (px) for label visibility. |
height_min |
Min screen height (px) for label visibility. |
width |
Widget width. Default |
height |
Widget height. Default |
elementId |
Optional element ID. |
outputId |
Shiny output ID. |
expr |
Expression that returns a |
env |
Environment in which to evaluate |
quoted |
Logical. Is |
Accepts raw sf objects, exploded_map results from
explode_sf, or grouped_exploded_map results from
explode_grouped. For exploded objects, the displaced
(WGS 84) geometry is used automatically.
An htmlwidgets object.
poly <- function(xmin, ymin, xmax, ymax) { sf::st_polygon(list(rbind( c(xmin, ymin), c(xmax, ymin), c(xmax, ymax), c(xmin, ymax), c(xmin, ymin) ))) } counties <- sf::st_sf( NAME = c("A", "B"), region = c("North", "South"), geometry = sf::st_sfc( poly(-74.2, 40.0, -74.0, 40.2), poly(-73.9, 40.0, -73.7, 40.2), crs = 4326 ) ) focus_map(counties, label_col = "NAME", group_col = "region")poly <- function(xmin, ymin, xmax, ymax) { sf::st_polygon(list(rbind( c(xmin, ymin), c(xmax, ymin), c(xmax, ymax), c(xmin, ymax), c(xmin, ymin) ))) } counties <- sf::st_sf( NAME = c("A", "B"), region = c("North", "South"), geometry = sf::st_sfc( poly(-74.2, 40.0, -74.0, 40.2), poly(-73.9, 40.0, -73.7, 40.2), crs = 4326 ) ) focus_map(counties, label_col = "NAME", group_col = "region")
Returns a named list of focus_map() arguments for common interactive
mapping workflows. Presets are intentionally plain lists so they can be
inspected, modified, or passed through do.call().
focus_map_preset( name = c("municipal", "drilldown", "municipal_drilldown", "none") )focus_map_preset( name = c("municipal", "drilldown", "municipal_drilldown", "none") )
name |
Preset name. |
A named list of focus_map() arguments.
focus_map_preset("municipal")focus_map_preset("municipal")
Focus-map Shiny proxy
focusMapProxy(outputId, session = NULL) update_focus_labels(proxy, show = TRUE) update_focus_palette(proxy, palette) update_focus_data(proxy, data, ...)focusMapProxy(outputId, session = NULL) update_focus_labels(proxy, show = TRUE) update_focus_palette(proxy, palette) update_focus_data(proxy, data, ...)
outputId |
Shiny output ID for an existing |
session |
Shiny session. Defaults to the current reactive domain. |
proxy |
A |
show |
Logical; show focus labels. |
palette |
Named character vector of group colours. |
data |
New |
... |
Passed to |
update_focus_data() swaps the widget's geometry and rebuilds it, which
returns the map to its idle (unfocused) view – a data swap is treated as a
fresh dataset. To keep the user focused on a feature across the swap, pass a
state and restore_selection = TRUE through ...; these flow to
focus_map() and the new feature is re-focused on load:
update_focus_data(proxy, new_sf, id_col = "GEOID",
state = state, restore_selection = TRUE)
A focusmap_proxy object.
Create a stable group palette
group_palette(groups, palette = "Dark 3", existing = NULL)group_palette(groups, palette = "Dark 3", existing = NULL)
groups |
Character vector of group names. |
palette |
Palette name passed to |
existing |
Optional named colour vector. Existing assignments are retained and colours are generated only for new groups. |
A named character vector of colours.
These offsets are a small documented finishing step for the national HHS reference view. They are interpreted in metres for projected layouts.
hhs_display_offsets()hhs_display_offsets()
A data frame with region, dx_m, and dy_m.
Create a focus-map widget for HHS regions
hhs_focus_map( states, apply_offsets = TRUE, show_region_labels = TRUE, show_drag_zoom = TRUE, show_labels = TRUE, ... )hhs_focus_map( states, apply_offsets = TRUE, show_region_labels = TRUE, show_drag_zoom = TRUE, show_labels = TRUE, ... )
states |
An |
apply_offsets |
Logical. Apply |
show_region_labels |
Logical. Show one passive HHS label per region. |
show_drag_zoom |
Logical. Show the drag-to-zoom button. |
show_labels |
Logical. Show labels on lifted states/territories. |
... |
Additional arguments passed to |
An htmlwidgets focus-map widget.
Build an HHS reference layout
hhs_layout( states, apply_offsets = TRUE, offsets = hhs_display_offsets(), source = "user data" )hhs_layout( states, apply_offsets = TRUE, offsets = hhs_display_offsets(), source = "user data" )
states |
An |
apply_offsets |
Logical. Apply the documented gallery display offsets? |
offsets |
Offset data frame, usually from |
source |
Optional source label stored in the returned list. |
A list with states, labels, and source.
HHS region colour palette
hhs_palette()hhs_palette()
A named character vector keyed by region id.
HHS region display names
hhs_region_names(short = FALSE)hhs_region_names(short = FALSE)
short |
Logical. When |
A named character vector keyed by region id.
Returns the lookup table used by the explodemap gallery's national HHS view. It includes the 50 states, District of Columbia, Puerto Rico, U.S. Virgin Islands, Guam, American Samoa, and the Northern Mariana Islands.
hhs_regions()hhs_regions()
A data frame with state name, postal/territory code, region id, and display labels.
Build layout objective weights
layout_objective( overlap = 10, displacement = 2, unused_space = 1, label_overlap = 4 )layout_objective( overlap = 10, displacement = 2, unused_space = 1, label_overlap = 4 )
overlap |
Weight for polygon overlap area. |
displacement |
Weight for mean displacement. |
unused_space |
Weight for unused canvas space. |
label_overlap |
Weight for approximate label overlaps. |
Named numeric vector of objective weights.
Implements the anchor layout procedure from Section 12. Supports three modes: automatic radial placement, automatic with collision resolution, and manual user-specified anchors.
layout_regions( sf_obj, region_col, mode = c("auto", "auto_collision", "manual"), anchors = NULL, initial_layout = NULL, preserve_manual = FALSE, kappa = 1.8, padding = 50000, delta = 15000, lambda = 0.18, eta = 0.18, padding_sep = 20000, max_iter = 60, quantile_p = 0.85, centroid_fun = c("centroid", "point_on_surface"), quiet = FALSE )layout_regions( sf_obj, region_col, mode = c("auto", "auto_collision", "manual"), anchors = NULL, initial_layout = NULL, preserve_manual = FALSE, kappa = 1.8, padding = 50000, delta = 15000, lambda = 0.18, eta = 0.18, padding_sep = 20000, max_iter = 60, quantile_p = 0.85, centroid_fun = c("centroid", "point_on_surface"), quiet = FALSE )
sf_obj |
Projected sf object with region column |
region_col |
Grouping column name |
mode |
"auto" (radial only), "auto_collision" (radial + solver), or "manual" |
anchors |
For mode = "manual": data.frame with columns (region_col, anchor_x, anchor_y) |
initial_layout |
Optional data.frame with columns (region_col,
anchor_x, anchor_y), or a grouped layout object. Used when
|
preserve_manual |
If |
kappa |
Radial expansion factor (default 1.8) |
padding |
Base padding in map units (default 50000) |
delta |
Log-density scaling factor (default 15000) |
lambda |
Spring coefficient for collision solver (default 0.18) |
eta |
Repulsion step size for collision solver (default 0.18) |
padding_sep |
Minimum separation between blocks (default 20000) |
max_iter |
Max iterations for collision solver (default 60) |
quantile_p |
Quantile for block radius estimation (default 0.85) |
centroid_fun |
"centroid" or "point_on_surface" |
quiet |
If |
data.frame with region, anchor_x, anchor_y, block_radius, n_units
Search grouped-layout parameters
optimize_grouped_layout( x, region_col, objective = c("no_overlap", "compact", "balanced", "stable"), weights = layout_objective(), label_col = NULL, label_size = NULL, grid = NULL, kappa = c(1.4, 1.8, 2.2), padding = c(25000, 50000, 75000), delta = c(5000, 15000, 30000), padding_sep = c(10000, 20000, 40000), ... )optimize_grouped_layout( x, region_col, objective = c("no_overlap", "compact", "balanced", "stable"), weights = layout_objective(), label_col = NULL, label_size = NULL, grid = NULL, kappa = c(1.4, 1.8, 2.2), padding = c(25000, 50000, 75000), delta = c(5000, 15000, 30000), padding_sep = c(10000, 20000, 40000), ... )
x |
Projected sf object with region column. |
region_col |
Grouping column name. |
objective |
Objective presets: |
weights |
Named weights from |
label_col, label_size
|
Optional label column and approximate label size.
When |
grid |
Optional data.frame of parameter combinations. |
kappa, padding, delta, padding_sep
|
Candidate values used when |
... |
Passed to |
A grouped_exploded_map with optimization metadata.
Plot an exploded_map object
## S3 method for class 'exploded_map' plot(x, which = c("exploded", "original", "both"), ...)## S3 method for class 'exploded_map' plot(x, which = c("exploded", "original", "both"), ...)
x |
An |
which |
"exploded" (default), "original", or "both" |
... |
Ignored |
Invisibly returns x, the original exploded_map object. The
method is called for its side effect of drawing the stored ggplot2
original and/or exploded map objects.
Plot a grouped_exploded_map object
## S3 method for class 'grouped_exploded_map' plot(x, which = c("grouped", "original", "local", "all"), ...)## S3 method for class 'grouped_exploded_map' plot(x, which = c("grouped", "original", "local", "all"), ...)
x |
A |
which |
"grouped" (default), "original", "local", or "all" |
... |
Ignored |
Invisibly returns x, the original grouped_exploded_map object.
The method is called for its side effect of drawing the stored ggplot2
grouped, original, and/or local map objects.
Renders the region anchors as block circles inside the layout's canvas frame, so unused space is visible as the gap between the blocks and the frame, and draws a red segment between every overlapping region pair. The subtitle summarises overlaps, label overlaps, and canvas utilization.
## S3 method for class 'layout_quality_report' plot(x, ...)## S3 method for class 'layout_quality_report' plot(x, ...)
x |
A |
... |
Unused. |
A ggplot object.
Standardizes common columns (unit_id, unit_name, and region) while
reporting each preparation choice.
prepare_explodemap_input( x, group_col = NULL, id_col = NULL, label_col = NULL, group_method = c("column", "quadrants", "clusters", "individual"), cluster_count = 6L, target_crs = NULL, make_valid = TRUE, target_vertices = NULL, seed = 1L )prepare_explodemap_input( x, group_col = NULL, id_col = NULL, label_col = NULL, group_method = c("column", "quadrants", "clusters", "individual"), cluster_count = 6L, target_crs = NULL, make_valid = TRUE, target_vertices = NULL, seed = 1L )
x |
An |
group_col, id_col, label_col
|
Optional source columns. |
group_method |
Grouping method when |
cluster_count |
Number of clusters for generated cluster groups. |
target_crs |
CRS for layout work. Use |
make_valid |
Repair geometries with |
target_vertices |
Optional simplification budget. |
seed |
Seed for generated clusters. |
An explodemap_prepared_input object with data, report,
mapping, and warnings.
Print an exploded_map object
## S3 method for class 'exploded_map' print(x, ...)## S3 method for class 'exploded_map' print(x, ...)
x |
An |
... |
Ignored |
Invisibly returns x, the original exploded_map object. The
method is called for its side effect of printing a compact diagnostic
overview of units, regions, derived parameters, and optional refinement
information.
Print a grouped_exploded_map object
## S3 method for class 'grouped_exploded_map' print(x, ...)## S3 method for class 'grouped_exploded_map' print(x, ...)
x |
A |
... |
Ignored |
Invisibly returns x, the original grouped_exploded_map object.
The method is called for its side effect of printing a compact diagnostic
overview of units, regions, grouping mode, and grouped-layout parameters.
Reads one or more drag-helper offset files and returns a tidy data frame
ready for apply_region_offsets. The drag helper tool exports
a CSV named {state}_drag_offsets.csv (e.g. nj_drag_offsets.csv)
with three columns: region, dx_m, and dy_m. This
function provides a convenient way to load that file – by explicit path,
by state abbreviation, or a mix of both – and prints a compact summary so
you can verify the offsets before applying them.
read_drag_offsets(x, dir = ".", quiet = FALSE)read_drag_offsets(x, dir = ".", quiet = FALSE)
x |
A character vector of one or more items, each of which is either:
|
dir |
Directory to search when an element of |
quiet |
Logical; when |
Typical workflow after running the drag helper tool:
# 1. Compute the exploded layout
nj <- explode_state("34", crs = 32111, region_map = list(...))
# 2. Read the offsets exported from the drag helper
offsets <- read_drag_offsets("NJ", dir = "outputs/drag_helpers")
# 3. Apply them as a reproducible finishing step
nj_display <- apply_region_offsets(nj, offsets)
You can also pass the CSV path directly to
apply_region_offsets without calling
read_drag_offsets() first – both accept a file path.
read_drag_offsets() is most useful when you want to inspect the
offsets interactively, load multiple state files at once, or resolve files
by abbreviation rather than full path.
A data frame with columns region (character), dx_m
(numeric), and dy_m (numeric). When multiple files are supplied an
additional state column (the lower-case abbreviation or file stem)
is prepended and rows from all files are combined.
Simplify geometry to a vertex budget
simplify_to_vertex_budget( x, target_vertices = 350000, max_tolerance = NULL, preserve_features = TRUE, preserve_topology = TRUE )simplify_to_vertex_budget( x, target_vertices = 350000, max_tolerance = NULL, preserve_features = TRUE, preserve_topology = TRUE )
x |
An |
target_vertices |
Desired maximum vertex count. |
max_tolerance |
Optional maximum simplification tolerance. |
preserve_features |
Require row count, non-empty geometries, and polygon geometry types to be preserved. |
preserve_topology |
Passed to |
An explodemap_simplification object.
Summary of an exploded_map object
## S3 method for class 'exploded_map' summary(object, ...)## S3 method for class 'exploded_map' summary(object, ...)
object |
An |
... |
Ignored |
Invisibly returns object, the original exploded_map object. The
method is called for its side effect of printing a human-readable summary
of dataset size, geometry statistics, displacement parameters, refinement
diagnostics, and implied calibration coefficients.
Summary of a grouped_exploded_map object
## S3 method for class 'grouped_exploded_map' summary(object, ...)## S3 method for class 'grouped_exploded_map' summary(object, ...)
object |
A |
... |
Ignored |
Invisibly returns object, the original grouped_exploded_map
object. The method is called for its side effect of printing dataset size,
grouping diagnostics, anchor parameters, and anchor radii.
Update an exploded grouped layout after manual composition
update_exploded_layout( result, region_offsets, label_offsets = NULL, update_plots = TRUE )update_exploded_layout( result, region_offsets, label_offsets = NULL, update_plots = TRUE )
result |
A |
region_offsets |
Data frame of manual anchors ( |
label_offsets |
Optional label-offset table stored on the result. |
update_plots |
Rebuild stored ggplots. |
Updated grouped_exploded_map.
Validate explodemap input
validate_explodemap_input( x, group_col, id_col = NULL, label_col = NULL, max_features = Inf, max_groups = Inf, max_vertices = Inf, min_groups = 2L )validate_explodemap_input( x, group_col, id_col = NULL, label_col = NULL, max_features = Inf, max_groups = Inf, max_vertices = Inf, min_groups = 2L )
x |
An |
group_col |
Grouping column. |
id_col |
Optional unique feature ID column. |
label_col |
Optional feature label column. |
max_features, max_groups, max_vertices
|
Optional limits. |
min_groups |
Minimum number of groups required. |
An explodemap_validation object.