Skip to content

Instantly share code, notes, and snippets.

@mdsumner
Last active April 2, 2024 22:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mdsumner/5c52e770d822bc4ac183e7460cb2b4fc to your computer and use it in GitHub Desktop.
Save mdsumner/5c52e770d822bc4ac183e7460cb2b4fc to your computer and use it in GitHub Desktop.
    library(terra)
#> terra 1.7.71
set.seed(2)
query <- buffer(project(vect(geosphere::randomCoordinates(1), crs = "EPSG:4326"),   "EPSG:3857"), 
                c(1e6, 4e6), capstyle = "square")

maps::map()
plot(project(query, "EPSG:4326"), add = TRUE, border= "firebrick", lwd = 4)

expanse(query) ## correct, crs-aware
#> [1] 2.407833e+12
sf::st_area(sf::st_as_sf(query))  ## Mercator
#> 4e+12 [m^2]

set.crs(query, NA)  ## beware doing this or to a copy, it's "in-place"

expanse(query)  ## also wrong
#> Warning: [expanse] unknown CRS. Results can be wrong
#> [1] 4e+12
set.crs(query, "EPSG:3857")  ## restore

sf::st_area(sf::st_as_sf(project(query, "EPSG:4326")))  ## correct, s2
#> 2.406033e+12 [m^2]
sf::sf_use_s2(FALSE)
#> Spherical geometry (s2) switched off
sf::st_area(sf::st_as_sf(project(query, "EPSG:4326")))  ## correct, but different - underlying ellipsoid engine

#> 2.407833e+12 [m^2]

## now compare non-crs-aware, but a good projection for this isomorphic case (Merc -> longlat -> cea)
query.cyl <- project(query, "+proj=cea")
set.crs(query.cyl, NA)

expanse(query.cyl)
#> Warning: [expanse] unknown CRS. Results can be wrong
#> [1] 2.411209e+12

sf::st_area(sf::st_as_sf(query.cyl))   ## also close enough
#> [1] 2.411209e+12


## compare to local laea (or aea or many lcc or many others)
laea_local <- function(x) {
    centre <- terra::geom(terra::project(terra::centroids(x), "EPSG:4326"))[1, c("x", "y")]
    prj <- sprintf("+proj=laea +lon_0=%f +lat_0=%f", centre[1], centre[2])
    terra::project(x, prj)
}

expanse(laea_local(query)) ## correctish but might not be segmentized enough
#> [1] 2.407833e+12
expanse(laea_local(densify(query, 5000)))
#> [1] 2.411209e+12

## compare
plot(laea_local(densify(query, 5000)))

plot(laea_local(query))

Created on 2024-04-02 with reprex v2.0.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment