The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.

Mapycus

Overview

mapycusmaximus implements a projection-aware, vector-geometry fisheye based on the Focus-Glue-Context (FGC) model. The transform magnifies a chosen focus (inner radius r_in), transitions smoothly through a glue ring (r_out), and preserves the outer context. It is provided at two levels:

This vignette shows how to apply the fisheye to common sf layers, tune parameters, and align multiple layers for a single figure.

Setup

library(sf)
#> Linking to GEOS 3.13.0, GDAL 3.10.1, PROJ 9.5.1; sf_use_s2() is TRUE
library(ggplot2)
library(mapycusmaximus)
theme_set(ggplot2::theme_minimal())

The package ships example data:

Quick start: warp a polygon layer

sf_fisheye() chooses a sensible projected working CRS and normalizes coordinates around a center. With preserve_aspect = TRUE (default), radii are interpreted in unit-like space (approx fraction of the layer’s half-span).

# Focus near a supplied geometry: use the centroid of the combined Melbourne polygon
melbourne <- vic[vic$LGA_NAME == "MELBOURNE", ]

vic_fisheye_demo <- sf_fisheye(
  vic,
  center = melbourne,      # accept sf/sfc; centroid is used in working CRS
  r_in = 0.34, r_out = 0.60,
  zoom_factor = 15,
  squeeze_factor = 0.35,
  method = "expand",
  revolution = 0
)

ggplot() +
  geom_sf(data = vic_fisheye_demo, fill = "grey92", color = "white", linewidth = 0.2) +
  geom_sf(data = melbourne, fill = NA, color = "tomato", linewidth = 0.5) +
  ggtitle("FGC fisheye: Melbourne focus within Victoria")

Choosing a center

You may supply the focus center in several ways:

# Example: WGS84 center (Melbourne CBD), auto-project to a working CRS
vic_cbd <- sf_fisheye(
  vic,
  center = c(144.9631, -37.8136),
  center_crs = "EPSG:4326",
  r_in = 0.30, r_out = 0.55,
  zoom_factor = 15, squeeze_factor = 0.30
)

ggplot(vic_cbd) +
  geom_sf(fill = "grey92", color = "white", linewidth = 0.2) +
  ggtitle("Center supplied as lon/lat (WGS84)")

Aligning multiple layers

To keep overlays aligned, apply the exact same fisheye parameters to each layer and ensure they share the same working CRS and normalization. A robust pattern is to bind layers together, transform once, then split for plotting; this guarantees a common bounding box for normalization.

centroids <- st_centroid(vic)
#> Warning: st_centroid assumes attributes are constant over geometries
vic$layer <- "polygon"
centroids$layer <- "centroid"
both <- rbind(vic[, c("LGA_NAME", "geometry", "layer")],
              centroids[, c("LGA_NAME", "geometry", "layer")])

both_fish <- sf_fisheye(both, center = melbourne,
                        r_in = 0.34, r_out = 0.60,
                        zoom_factor = 15, squeeze_factor = 0.35)

ggplot() +
  geom_sf(data = both_fish[both_fish$layer == "polygon", ],
          fill = "grey92", color = "white", linewidth = 0.2) +
  geom_sf(data = both_fish[both_fish$layer == "centroid", ],
          color = "#2b6cb0", size = 0.6, alpha = 0.8) +
  ggtitle("Aligned overlays: transform layers together, plot separately")

If layers must be transformed separately, current per-layer normalization can lead to slight radius mismatches. A practical workaround is to compute a scale factor from a reference layer’s bbox and multiply r_in/r_out accordingly, e.g.:

all_points <- sf_fisheye(all_points, center = melbourne,
                         zoom_factor = 1.8, squeeze_factor = 0.30)
scale_radii <- 1 - (((st_bbox(vic)["xmax"] - st_bbox(vic)["xmin"])  -
                     (st_bbox(all_points)["xmax"] - st_bbox(all_points)["xmin"])) /
                    (st_bbox(vic)["xmax"] - st_bbox(vic)["xmin"]))
vic_fisheye <- sf_fisheye(vic, center = melbourne,
                          r_in = 0.35 * scale_radii,
                          r_out = 0.50 * scale_radii,
                          zoom_factor = 1.8, squeeze_factor = 0.30)

Future versions will expose a parameter object or match_to argument so multiple layers can share normalization and radii without manual scaling.

Diagnostics with numeric coordinates

Use create_test_grid() and plot_fisheye_fgc() to understand the mapping in isolation from GIS workflows.

grid <- create_test_grid(range = c(-1, 1), spacing = 0.1)
warp <- fisheye_fgc(grid, r_in = 0.34, r_out = 0.5,
                    zoom_factor = 1.3, squeeze_factor = 0.5)
plot_fisheye_fgc(grid, warp, r_in = 0.34, r_out = 0.5)

CRS and reproducibility tips

Caveats

The fisheye intentionally distorts distances and areas within the focus and glue zones. Use it for visual exploration and communication; run quantitative spatial analysis on the original geometry. For publication figures, set revolution = 0 and describe the distortion in the caption.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.