Issues with circles
Closed this issue · 3 comments
Hi,
I suggested a solution (#164) for a problem I haven't described yet (but had discussed it with @mhesselbarth). But here, we go:
Consider the following code:
library(landscapemetrics)
# T-shaped patch with 7 cells horizontal and 6 cells vertical, patch size: 12 cells
mat1 <- matrix(data = c(NA,5,NA,NA,NA,NA,NA,
NA,5,NA,NA,NA,NA,NA,
NA,5,NA,NA,NA,NA,NA,
NA,5, 5, 5, 5, 5, 5,
NA,5,NA,NA,NA,NA,NA,
NA,5,NA,NA,NA,NA,NA,
NA,5,NA,NA,NA,NA,NA), nrow = 7, ncol = 7)
r <- raster::raster(mat1)
raster::extent(r) <- c(0, 7, 0, 7)
landscapetools::show_landscape(r)
lsm_p_area(r)$value * 10000
#> [1] 12
get_circumscribingcircle(r)
#> # A tibble: 1 x 3
#> layer id dist
#> <int> <dbl> <dbl>
#> 1 1 5 7.21
Created on 2020-02-08 by the reprex package (v0.3.0)
The issue is that the diameter of the smallest circumscribing circle is not 7.21, but rather just a bit more than 8 (blue line):
The current algorithm simply looks for the two points that are furthest apart and takes the distance as the diameter of the circle (green line). This, however, is not necessarily the smallest circumscribing circle of the patch - as shown in the example.
@mhesselbarth compared the results of our current algorithm to FRAGSTATS, and they seem to do the same calculation:
library(landscapemetrics)
library(raster)
#> Loading required package: sp
library(tidyverse)
mat <- matrix(data = NA, nrow = 13, ncol = 13)
mat[4:9, 7] <- 1
mat[4, 4:10] <- 1
ras <- raster::raster(mat, xmn = 0, xmx = 13, ymn = 0, ymx = 13)
radius <- (7.211103 / 2) # 7.211103
plot(ras)
plot(rasterToPolygons(ras), add = TRUE)
points(matrix(data = c(6.5, 7.5), ncol = 2, byrow = TRUE),
col = "red")
lines(x = c(6.5, 6.5), y = c(7.5 - radius, 7.5 + radius), col = "green")
lines(x = c(6.5 - radius, 6.5 + radius), y = c(7.5, 7.5), col = "green")
circ <- construct_buffer(coords = matrix(c(6.5, 7.5), 1, 2),
shape = "circle", size = radius)
plot(circ, add = TRUE)
pull(lsm_p_circle(ras), value)
#> [1] 0.7061755
# FRAGSTATS
# 0.7062
Created on 2020-02-08 by the reprex package (v0.3.0)
The other issue I'd like to address is that for patches that consist of only one cell lsm_p_circle
returns zero:
library(landscapemetrics)
# A 1-cell patch
mat1 <- matrix(data = c(NA,NA,NA,
NA, 5,NA,
NA,NA,NA), nrow = 3, ncol = 3)
r <- raster::raster(mat1)
raster::extent(r) <- c(0, 3, 0, 3)
landscapetools::show_landscape(r)
lsm_p_area(r)$value * 10000
#> [1] 1
lsm_p_circle(r)
#> # A tibble: 1 x 6
#> layer level class id metric value
#> <int> <chr> <int> <int> <chr> <dbl>
#> 1 1 patch 5 1 circle 0
Created on 2020-02-08 by the reprex package (v0.3.0)
This just doesn't make sense to me. A single-cell patch has a clear size and also a circle can be drawn around it.
Great work @bitbacchus and @mhesselbarth. I would suggest adding some explanation of the changes (including some of the figures showed above) to https://r-spatialecology.github.io/landscapemetrics/articles/articles/comparing_tools.html,
I already started doing so :)
Done. Pls re-open if needed.