Skip to content

sf::st_lenght() seems to give incorrect results when using S2 engine #1998

@jlacko

Description

@jlacko

The sf::st_length() seems to give incorrect result when used to calculate length of shared border between two countries.

This issue flows from an earlier SO question about calculating length of the border between Germany and Denmark.

The result obtained by calculating length of intersection of two polygons in WGS84 is off significantly (by a factor of 2). Reprojecting the object to ETRS89 gives a more reasonable length, as does running the calculation in WGS84 but with S2 turned off via sf::sf_use_s2(FALSE).

For a reproducible example consider this piece of code, noting that the "reference" length of the border is 68 kilometers and that doing the calculation on a lower resolution object is expected to give a somewhat lower figure.

library(sf)
library(dplyr)

border_length <- function(shape) {
  
  sf::st_intersection(shape[1], shape[2], model = "closed") %>%
    st_length()
    
}

gisco_wgs <- giscoR::gisco_get_countries(resolution = "20",
                                epsg = 4326,
                                country = c("DE", "DK")) %>% 
  st_geometry() # to avoid warnings about spatially constant variables

gisco_3035 <- st_transform(gisco_wgs, 3035)

border_length(gisco_wgs)
# 105547.6 [m] - this is too much!

border_length(gisco_3035)
# 52953.44 [m] - this feels about right, given the resolution...

sf_use_s2(FALSE)

border_length(gisco_wgs)
# although coordinates are longitude/latitude, st_intersection assumes that they are planar
# 52940.58 [m] - this again feels right, but note the difference compared to results with s2 turned on!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions