| Title: | The Structural Similarity Index Measure for Maps |
| Version: | 0.4.3 |
| Description: | Computes the Structural Similarity Index Measure (SSIM) and its components for raster images and irregular polygon maps. The raster method follows Wang et al. (2004) <doi:10.1109/TIP.2003.819861>. The polygon method uses geographically weighted summary statistics described by Brunsdon et al. (2002) <doi:10.1016/S0198-9715(01)00009-6> with an adaptive nearest-neighbor kernel. Provides bandwidth selection, value transformations, permutation-based inference, Fire Weather Index rasters, and Toronto census-derived example data. |
| Depends: | R (≥ 3.6.0) |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| LazyData: | true |
| Imports: | stats, scales, terra, ggplot2 (≥ 3.4.0), sf, knitr, FNN |
| Suggests: | magick, RColorBrewer, testthat (≥ 3.0.0), rmarkdown, patchwork, tidyterra |
| URL: | https://github.com/Hailyee-Ha/SSIMmap |
| BugReports: | https://github.com/Hailyee-Ha/SSIMmap/issues |
| VignetteBuilder: | knitr |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-11-04 05:52:53 UTC; hailyeeha |
| Author: | Hui Jeong (Hailyee) Ha
|
| Maintainer: | Hui Jeong (Hailyee) Ha <hha24@uwo.ca> |
| Repository: | CRAN |
| Date/Publication: | 2026-11-13 09:10:53 UTC |
Toronto neighborhood deprivation indices and commuting measure (2021)
Description
An sf polygon object containing 279 Aggregate Dissemination Areas
(ADAs) for the Toronto Census Subdivision, Ontario, Canada. It includes two
neighborhood deprivation indices and a derived commuting measure, for use
with ssim_polygon and ssim_bandwidth.
Usage
Toronto_SSIM
Format
An sf data frame with 279 rows and the following columns:
- ADAUID
2021 Aggregate Dissemination Area identifier.
- CIMD
Canadian Index of Multiple Deprivation residential instability score.
- PP
Pampalon material and social deprivation index social dimension.
- Commute
Preserved derived commuting percentage. Its DA numerator is the Census count for commuting to a different CSD and CD within the province or territory of residence (characteristic 2601), divided by total DA Census population (characteristic 1), multiplied by 100, and rounded half-up to two decimals. The ADA value is the unweighted mean of all stored percentages for all intersecting DAs, including boundary-only intersections and stored zero percentages. Zero-population DAs also have stored zero percentages and are included. It is not a household or worker share, a pooled ADA population rate, or a count of all outside-CSD commuting. Some source numerator cells are suppressed in the official release but stored as zero in the preserved data; see the provenance note.
- geometry
sfcpolygon geometry column.
Details
The numeric data are unchanged from version 0.4.0. Earlier documentation incorrectly described these polygons as 2016 Census Tracts. The preserved commuting variable is a derived DA-average measure, not a proportion of households. See ‘extdata/Toronto_SSIM_provenance.txt’ for its calculation and the suppressed-value limitation.
Source
Statistics Canada, 2021 Census of Population; author-prepared neighborhood deprivation and commuting data.
Examples
data("Toronto_SSIM")
plot(Toronto_SSIM["CIMD"], border = NA)
British Columbia Fire Weather Index — 16 August 2023
Description
Daily Canadian Fire Weather Index (FWI) for the province of British Columbia, Canada, on 16 August 2023, at a 2 km spatial resolution. This date represents conditions during the peak summer fire season, when fire danger levels in British Columbia are typically high.
Usage
fwi_0816_bc
Format
A packed terra raster object with one numeric layer
(FWI values).
Details
The object is stored as a packed terra raster (created with
terra::wrap()) so that it can be saved in an R .rda file.
Use terra::unwrap() to convert it back to a regular terra
raster before passing it to ssim_raster or to other
terra functions.
Source
Canadian Forest Fire Weather Index System; FWI values are derived from meteorological inputs (temperature, wind speed, relative humidity, precipitation).
Examples
data("fwi_0816_bc")
fwi_0816_bc <- terra::unwrap(fwi_0816_bc)
terra::plot(fwi_0816_bc, main = "FWI - 16 August 2023")
British Columbia Fire Weather Index — 18 August 2023
Description
Daily Canadian Fire Weather Index (FWI) for the province of British
Columbia, Canada, on 18 August 2023, at a 2 km spatial resolution. This
date also represents conditions during the peak summer fire season and is
typically expected to show high spatial similarity to
fwi_0816_bc.
Usage
fwi_0818_bc
Format
A packed terra raster object with one numeric layer
(FWI values).
Details
The object is stored as a packed terra raster (created with
terra::wrap()). Use terra::unwrap() to convert it back to a
regular terra raster before use.
Source
Canadian Forest Fire Weather Index System.
Examples
data("fwi_0818_bc")
fwi_0818_bc <- terra::unwrap(fwi_0818_bc)
terra::plot(fwi_0818_bc, main = "FWI - 18 August 2023")
British Columbia Fire Weather Index — 1 November 2023
Description
Daily Canadian Fire Weather Index (FWI) for the province of British
Columbia, Canada, on 1 November 2023, at a 2 km spatial resolution. This
date represents late-fall conditions, when fire danger across most of
British Columbia is typically much lower than during the summer season due
to cooler temperatures and increased precipitation. The spatial structure
of this map is therefore expected to differ substantially from the summer
FWI maps (fwi_0816_bc, fwi_0818_bc).
Usage
fwi_1101_bc
Format
A packed terra raster object with one numeric layer
(FWI values).
Details
This legacy November 1 dataset is retained unchanged for compatibility.
The package examples use fwi_1111_bc, which
contains a different observation from November 11, not a renamed copy.
The object is stored as a packed terra raster (created with
terra::wrap()). Use terra::unwrap() to convert it back to a
regular terra raster before use.
Source
Canadian Forest Fire Weather Index System.
Examples
data("fwi_1101_bc")
fwi_1101_bc <- terra::unwrap(fwi_1101_bc)
terra::plot(fwi_1101_bc, main = "FWI - 1 November 2023")
British Columbia Fire Weather Index — 11 November 2023
Description
Daily Canadian Fire Weather Index (FWI) for British Columbia, Canada,
on 11 November 2023, at a 2 km spatial resolution. This is the late-fall
observation used in the package summer-fall comparison.
It is distinct from the unchanged legacy fwi_1101_bc data.
Usage
fwi_1111_bc
Format
A packed terra raster object with one numeric FWI layer,
895 rows and 510 columns, at 2,000 m resolution in EPSG:3978.
Details
The original FWI raster was cropped and masked to the 2021 British Columbia
provincial boundary, with no resampling or value transformation. Its grid
matches fwi_0816_bc and fwi_0818_bc.
The data are stored using terra::wrap(); use terra::unwrap()
before calculation. Use transform = "none" in
ssim_raster to reproduce the manuscript's original-unit
FWI analysis; "none" is also the function default from version 0.4.2.
See the installed ‘extdata/fwi_1111_bc_provenance.txt’ for source
and preparation checksums.
Source
Natural Resources Canada, Canadian Forest Service, Canadian Wildland Fire Information System (CWFIS), https://cwfis.cfs.nrcan.gc.ca/. Historical FWI coverage for 2023-11-11, independently retrieved on 2026-10-27 and verified cell-for-cell against the original source raster ‘fwi20231111.tif’. Contains information licensed under the Open Government Licence – Canada. Crop boundary: Statistics Canada, 2021 provincial boundary.
Examples
data("fwi_1111_bc")
fwi_1111 <- terra::unwrap(fwi_1111_bc)
terra::plot(fwi_1111, main = "FWI - 11 November 2023")
Bandwidth selection for polygon maps
Description
Computes bias–variance trade-off curves for two polygon maps using an adaptive Gaussian kernel. The two input variables can be optionally transformed (e.g. normal scores or min–max normalization) before smoothing. A suggested bandwidth range is obtained by balancing standardized bias and variance for each variable, and a single bandwidth is chosen from this range.
Usage
ssim_bandwidth(
shape,
map1,
map2,
max_bandwidth,
transform = c("none", "normal_score", "percentile", "minmax"),
option = "midpoint"
)
Arguments
shape |
An |
map1 |
Character string; column name in |
map2 |
Character string; column name in |
max_bandwidth |
Integer (at least 12). Upper bound of the bandwidth
|
transform |
One of |
option |
Character string specifying how to choose a single bandwidth
from the bias–variance trade-off range: one of
|
Details
This function does *not* compute SSIM; it is intended to be used in
combination with ssim_polygon(), which can then be called with the
selected bandwidth.
The kernel is Gaussian with adaptive bandwidth:
w_{ij} = \exp\left\{-\tfrac12 (d_{ij} / h_i)^2 \right\},
where d_{ij} is the distance between polygon centroids and
h_i is the distance from polygon i to its k-th nearest
neighbor. Bandwidth selection is based purely on bias–variance trade-off
and does not involve any SSIM computation or permutation testing.
Value
A list with components:
plot |
A |
bandwidth |
The chosen bandwidth |
tradeoff |
A list with elements
|
Structural similarity index (SSIM) for polygon maps
Description
Computes local and global SSIM (and its components SIM, SIV, SIP) for two polygon maps using an adaptive k-nearest-neighbor (k-NN) Gaussian kernel. Input variables can be optionally transformed (e.g. rank-based inverse normal scores or min–max normalization). Optionally performs permutation tests for global and local significance with BH-FDR correction. Under the null hypothesis for the permutation test, both variables are randomly permuted at each iteration, breaking spatial structure and association between them. Local p-values can be optionally adjusted using the Benjamini–Hochberg FDR procedure.
Usage
ssim_polygon(
shape,
map1,
map2,
global = TRUE,
bandwidth = NULL,
transform = c("none", "normal_score", "percentile", "minmax"),
k1 = NULL,
k2 = NULL,
do_test = FALSE,
R = 1000,
fdr = TRUE,
alpha = 0.05,
seed = NULL
)
Arguments
shape |
An |
map1 |
Character string; column name in |
map2 |
Character string; column name in |
global |
Logical. If |
bandwidth |
Integer; adaptive k-NN size (number of neighbors). The
default is |
transform |
One of |
k1, k2 |
SSIM constants. If |
do_test |
Logical; if |
R |
Integer; number of permutations for the significance tests
(default |
fdr |
Logical; if |
alpha |
Numeric; significance threshold for local results (default
|
seed |
Optional integer; random seed for reproducibility of the permutation tests. |
Value
If global = TRUE and do_test = FALSE, the function prints a
knitr table summarizing the global mean, minimum, maximum, and standard
deviation of SSIM, SIM, SIV, and SIP, and returns this data.frame
(invisibly).
If global = TRUE and do_test = TRUE, the function prints the
same summary table plus a table of global permutation p-values (two-sided)
for SSIM, SIM, SIV, and SIP, and returns (invisibly) a list with
components:
-
summary:data.framewith global SSIM/SIM/SIV/SIP summary statistics; -
p_global:data.framewith global means and permutation p-values for SSIM, SIM, SIV, SIP.
If global = FALSE, the function returns an sf object equal to
shape with additional columns:
-
SSIM,SIM,SIV,SIP: local similarity metrics for each polygon; With
do_test = TRUE, each statistic has columns with suffixes_p,_q, and_sig, for exampleSIM_p,SIM_q, andSIM_sig. These contain its local permutation p-value, BH-adjusted q-value, and logical significance flag(q <= alpha). Whenfdr = FALSE, the_qcolumns equal the unadjusted p-values.-
p_value,q_value,sigremain aliases forSSIM_p,SSIM_q,SSIM_sig, respectively, for compatibility with earlier versions.
SSIM index for raster images
Description
This function calculates the Structural Similarity Index Measure (SSIM) between two raster images. It can return either global SSIM summaries or local SSIM raster layers. Optional permutation-based statistical inference can also be performed for global or local SSIM values.
Usage
ssim_raster(
map1,
map2,
global = TRUE,
w = 1,
transform = c("none", "normal_score", "percentile", "minmax"),
k1 = NULL,
k2 = NULL,
do_test = FALSE,
local_test = FALSE,
R = 1000,
fdr = TRUE,
alpha = 0.05,
seed = NULL
)
Arguments
map1 |
A single-layer |
map2 |
A single-layer |
global |
Logical. If |
w |
Integer. Radius of the local moving window used to calculate local
SSIM components. For example, |
transform |
Character. Transformation applied to both raster maps before
SSIM calculation. Options are |
k1 |
Numeric. Constant used to stabilize the luminance component of SSIM.
If |
k2 |
Numeric. Constant used to stabilize the contrast and structure
components of SSIM. If |
do_test |
Logical. If |
local_test |
Logical. If |
R |
Integer. Number of permutations used for statistical inference.
Default is |
fdr |
Logical. If |
alpha |
Numeric. Significance level used to determine significant SSIM
values. Default is |
seed |
Optional integer. Random seed used for permutation testing.
Default is |
Details
The SSIM index is calculated as the product of three components:
similarity in mean intensity, similarity in variance, and similarity in
spatial pattern. These components are returned as SIM, SIV, and
SIP, respectively.
The local SSIM calculation uses a square moving window with size
(2 * w + 1) x (2 * w + 1).
When do_test = TRUE, permutation testing is performed by randomly
permuting the values of map2 over the overlapping non-NA cells
and recalculating SSIM values while holding map1 fixed. Both global
and local tests are two-sided, centered on the corresponding permutation
mean: p = (1 + sum(abs(null - mean(null)) >=
abs(observed - mean(null)))) / (R + 1). This tests departures in either
direction from the value-randomization distribution, not similarity to zero.
Local tests estimate a separate permutation mean for each cell and component.
They replay the same permutations in a second pass to avoid storing all
local null layers; the final random-number state is the same as after one pass.
With fdr = TRUE, BH adjustment is applied across the four global
components or across valid cells separately for each local component.
Value
If global = TRUE and do_test = FALSE, a list containing a summary
table of global SSIM, SIM, SIV, and SIP values is returned.
If global = TRUE and do_test = TRUE, a list containing the
summary table, permutation null distributions, p-values, and optionally
q-values is returned.
If global = FALSE and do_test = FALSE, a
terra::SpatRaster object with four layers is returned:
SSIM, SIM, SIV, and SIP.
If global = FALSE, do_test = TRUE, and
local_test = TRUE, a terra::SpatRaster object is returned with
local SSIM component layers, p-value layers, optionally q-value layers, and
significance layers.
Examples
## Not run:
library(terra)
# Global SSIM summary
g1 <- ssim_raster(
map1,
map2,
global = TRUE,
w = 1
)
# Local SSIM raster layers
l1 <- ssim_raster(
map1,
map2,
global = FALSE,
w = 1
)
# Local SSIM with permutation test
l2 <- ssim_raster(
map1,
map2,
global = FALSE,
w = 1,
do_test = TRUE,
local_test = TRUE,
R = 999
)
## End(Not run)