---
title: "Mapycus"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Mapycus}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
knitr::opts_chunk$set(
  fig.width = 7,
  fig.height = 5,
  fig.align = "center"
)
```
## 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:

- `fisheye_fgc()` — numeric coordinates (matrix) with diagnostics
- `sf_fisheye()` — `sf`/`sfc` objects with CRS handling and normalization

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

## Setup

```{r setup}
library(sf)
library(ggplot2)
library(mapycusmaximus)
theme_set(ggplot2::theme_minimal())
```

The package ships example data:

- `vic`: Victoria LGA polygons (projected)
- `vic_fish`: fisheye-distorted `vic` (for reference examples)
- `conn_fish`: sample transfer lines (already warped in data preparation)

## 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).

```{r quick-start}
# 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:

- As a geometry: `center = melbourne` (centroid of the combined geometry)
- As lon/lat: `center = c(144.9631, -37.8136)`, `center_crs = "EPSG:4326"`
- As map units (working CRS): `center = c(x, y)`
- As normalized coordinates in `[-1, 1]`: `normalized_center = TRUE`

```{r centers}
# 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.

```{r multi-layer}
centroids <- st_centroid(vic)
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.:

```{r scale-radii, eval=FALSE}
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.

```{r diagnostics}
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

- Let `sf_fisheye()` auto-select a working CRS for lon/lat inputs, or set `target_crs` explicitly for project standards.
- Prefer `center` as an `sf`/`sfc` geometry or as lon/lat with `center_crs` for clarity.
- Use `normalized_center = TRUE` and fixed radii for small multiples across regions.

## 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.


