Skip to content
Prev 29504 / 29559 Next

The sf::st_perimeter() function doesn't seem to work properly when trying to determine the perimeter of an sf object on the ellipsoid

After another check, I see you are correct: the st_perimeter() function returns a different value **when S2 is turned off**

sf::st_is_valid(plt)
[1] TRUE

plt <- st_transform(plt, 4326)
sf::sf_use_s2(FALSE)
Spherical geometry (s2) switched off
plt |>  sf::st_perimeter()
129.0982 [m]
# Calculating ellipsoidal perimeter with st_boundary()
plt |>
  sf::st_boundary() |>
  sf::st_length()
129.2854 [m]
# Calculating ellipsoidal perimeter with st_cast() 
plt |>
  sf::st_cast("MULTILINESTRING") |>
  sf::st_length()
129.2854 [m]

I don't know for sure, but I would guess that st_boundary() and st_cast() break the polygon into individual line strings, and then calculate length of each edge, whereas st_perimeter takes the polygon area and calculates perimeter, without using S2 so assuming a cartesian CRS, (which would be distorted).

In the help for distance functions it says:
"if sf_use_s2() is FALSE, ellipsoidal distances are computed using st_geod_distance which uses function geod_inverse from GeographicLib (part of PROJ); see Karney, Charles FF, 2013, Algorithms for geodesics, Journal of Geodesy 87(1), 43?55"

I take that to mean that *length* calculations use the st_geod_distance(). But perimeter must work differently.

Best, Micha



--
Micha Silver
cell: +972-523-665918
On Saturday, 17 May 2025 at 01:29, Josiah Parry <josiah.parry at gmail.com> wrote:

            
Message-ID: <ul0k5LRmT5YBqoLt_h3t50kIYi0AqiV4S6dLNn8M-pPW0GWiEYg13j1nWKA46_wYDat_D0O6y9plLLCYJO9XN4myiyrkMqk5opAEATra7Og=@proton.me>
In-Reply-To: <CAL3ufULXjHuJQQn_PxmAiwJnBOQ5AB_DQk5Zro8EiPXMCN2gUw@mail.gmail.com>