Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove maptools and deprecate fortify() for sp objects #5327

Closed
1 change: 0 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ Suggests:
knitr,
mapproj,
maps,
maptools,
multcomp,
munsell,
nlme,
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@
* `stat_contour()` and `stat_contour_filled()` now warn about and remove
duplicated coordinates (@teunbrand, #5215).
* Improve performance of layers without positional scales (@zeehio, #4990)
* `fortify()` for sp objects (e.g., `SpatialPolygonsDataFrame`) is now deprecated
and will be removed soon in support of [the upcoming retirement of rproj, rgeos,
and maptools](https://r-spatial.org/r/2023/05/15/evolution4.html). In advance
of the whole removal, `fortify(<SpatialPolygonsDataFrame>, region = ...)`
no longer works as of this version (@yutannihilation, #5244).

# ggplot2 3.4.2
This is a hotfix release anticipating changes in r-devel, but folds in upkeep
Expand Down
62 changes: 47 additions & 15 deletions R/fortify-spatial.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,31 @@
#' @param ... not used by this method
#' @keywords internal
#' @name fortify.sp
#' @examples
#' if (require("maptools")) {
#' sids <- system.file("shapes/sids.shp", package="maptools")
#' nc1 <- readShapePoly(sids,
#' proj4string = CRS("+proj=longlat +datum=NAD27"))
#' nc1_df <- fortify(nc1)
#' }
NULL

#' @rdname fortify.sp
#' @export
#' @method fortify SpatialPolygonsDataFrame
fortify.SpatialPolygonsDataFrame <- function(model, data, region = NULL, ...) {
deprecate_warn0("3.4.3",
I("`fortify(<SpatialPolygonsDataFrame>)`"),
details = "Please migrate to sf."
)

attr <- as.data.frame(model)
# If not specified, split into regions based on polygons
if (is.null(region)) {
coords <- lapply(model@polygons,fortify)
# Suppress duplicated warnings
withr::with_options(list(lifecycle_verbosity = "quiet"), {
coords <- lapply(model@polygons,fortify)
})
coords <- vec_rbind0(!!!coords)
cli::cli_inform("Regions defined for each Polygons")
} else {
cp <- sp::polygons(model)

# Union together all polygons that make up a region
unioned <- maptools::unionSpatialPolygons(cp, attr[, region])
coords <- fortify(unioned)
coords$order <- 1:nrow(coords)
lifecycle::deprecate_stop("3.4.3",
I("`fortify(<SpatialPolygonsDataFrame>, region = ...)` is defunct'"),
details = "Please migrate to sf."
)
}
coords
}
Expand All @@ -43,14 +42,27 @@ fortify.SpatialPolygonsDataFrame <- function(model, data, region = NULL, ...) {
#' @export
#' @method fortify SpatialPolygons
fortify.SpatialPolygons <- function(model, data, ...) {
polys <- lapply(model@polygons, fortify)
deprecate_warn0("3.4.3",
I("`fortify(<SpatialPolygons>)`"),
details = "Please migrate to sf."
)

# Suppress duplicated warnings
withr::with_options(list(lifecycle_verbosity = "quiet"), {
polys <- lapply(model@polygons, fortify)
})
vec_rbind0(!!!polys)
}

#' @rdname fortify.sp
#' @export
#' @method fortify Polygons
fortify.Polygons <- function(model, data, ...) {
deprecate_warn0("3.4.3",
I("`fortify(<Polygons>)`"),
details = "Please migrate to sf."
)

subpolys <- model@Polygons
pieces <- lapply(seq_along(subpolys), function(i) {
df <- fortify(subpolys[[model@plotOrder[i]]])
Expand All @@ -70,6 +82,11 @@ fortify.Polygons <- function(model, data, ...) {
#' @export
#' @method fortify Polygon
fortify.Polygon <- function(model, data, ...) {
deprecate_warn0("3.4.3",
I("`fortify(<Polygon>)`"),
details = "Please migrate to sf."
)

df <- as.data.frame(model@coords)
names(df) <- c("long", "lat")
df$order <- 1:nrow(df)
Expand All @@ -81,6 +98,11 @@ fortify.Polygon <- function(model, data, ...) {
#' @export
#' @method fortify SpatialLinesDataFrame
fortify.SpatialLinesDataFrame <- function(model, data, ...) {
deprecate_warn0("3.4.3",
I("`fortify(<SpatialLinesDataFrame>)`"),
details = "Please migrate to sf."
)

lines <- lapply(model@lines, fortify)
vec_rbind0(!!!lines)
}
Expand All @@ -89,6 +111,11 @@ fortify.SpatialLinesDataFrame <- function(model, data, ...) {
#' @export
#' @method fortify Lines
fortify.Lines <- function(model, data, ...) {
deprecate_warn0("3.4.3",
I("`fortify(<Lines>)`"),
details = "Please migrate to sf."
)

lines <- model@Lines
pieces <- lapply(seq_along(lines), function(i) {
df <- fortify(lines[[i]])
Expand All @@ -108,6 +135,11 @@ fortify.Lines <- function(model, data, ...) {
#' @export
#' @method fortify Line
fortify.Line <- function(model, data, ...) {
deprecate_warn0("3.4.3",
I("`fortify(<Line>)`"),
details = "Please migrate to sf."
)

df <- as.data.frame(model@coords)
names(df) <- c("long", "lat")
df$order <- 1:nrow(df)
Expand Down
8 changes: 0 additions & 8 deletions man/fortify.sp.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions tests/testthat/test-fortify.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,26 @@ test_that("spatial polygons have correct ordering", {
polys2 <- rev(polys)
polys2_sp <- sp::SpatialPolygons(polys2)
fake_sp2 <- sp::SpatialPolygonsDataFrame(polys2_sp, fake_data)
expected <- fortify(fake_sp2)
lifecycle::expect_deprecated(
expected <- fortify(fake_sp2)
)
expected <- expected[order(expected$id, expected$order), ]

actual <- fortify(fake_sp)
lifecycle::expect_deprecated(
actual <- fortify(fake_sp)
)

# the levels are different, so these columns need to be converted to character to compare
expected$group <- as.character(expected$group)
actual$group <- as.character(actual$group)

# Use expect_equal(ignore_attr = TRUE) to ignore rownames
expect_equal(actual, expected, ignore_attr = TRUE)

lifecycle::expect_deprecated(
# fortify() with region is defunct due to maptools' retirement
lifecycle::expect_defunct(fortify(fake_sp, region = "foo"))
)
})

test_that("fortify.default proves a helpful error with class uneval", {
Expand Down
Loading