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

strange buffer using terra #1330

Closed
zhangzhixin1102 opened this issue Oct 30, 2023 · 3 comments
Closed

strange buffer using terra #1330

zhangzhixin1102 opened this issue Oct 30, 2023 · 3 comments

Comments

@zhangzhixin1102
Copy link

zhangzhixin1102 commented Oct 30, 2023

I want to generate a buffer around minimum convex polygon. However, the results are quite strange.
Could you please confirm the issue?
Below is my scripts and data.

library(terra)
locs <- read.csv("opportunistic-occ2.csv", row.names = 1)
locs <- vect(locs, crs="+proj=longlat")
mcp <- convHull(locs)

# generate buffer around MCP
d <- 1000*1000 ## 1000 km 
b <- terra::buffer(mcp, width = d)

maps::map('world', col = 'grey85', fill = T, border = 'grey85')
points(locs, pch = 20, col = "red")
lines(mcp)
lines(b)

opportunistic-occ2.csv

image

@kadyb
Copy link
Contributor

kadyb commented Oct 30, 2023

I think you should reproject your longitude and latitude data to a planar coordinate system (e.g. EPSG:4087). If you want to use coordinates in degrees, you should use the {sf} package, which supports calculations on the sphere. See this article: https://r-spatial.github.io/sf/articles/sf7.html

@zhangzhixin1102
Copy link
Author

zhangzhixin1102 commented Oct 31, 2023

Thanks for the editing by @rhijmans and the suggestion from @kadyb.
I solved the issue by using two methods (terra + sf and sf only). Below are the results.
I am still wandering: can terra alone solve this issue?

library(sf)
library(terra)
locs <- read.csv("opportunistic-occ2.csv", row.names = 1)
locs <- vect(locs, crs="+proj=longlat")
mcp <- convHull(locs)

# generate buffer using terra + sf
d <- 1000*1000 ## 1000 km

## change crs first then buffer
b <- terra::buffer(project(mcp, "+init=EPSG:4087"), width = d)
b <- st_wrap_dateline(st_transform(x = st_as_sf(b), crs = 4326), options = c("WRAPDATELINE=YES", "DATELINEOFFSET=180"), quiet = TRUE)

## plot check
maps::map('world', col = 'grey85', fill = T, border = 'grey85')
points(locs, pch = 20, col = "red")
lines(mcp)
plot(b$geometry, add = T, border = 'blue', lwd = 2)

## generate bufer using sf only
sf::sf_use_s2(TRUE)
mcp.sf <- st_as_sf(mcp, crs = 4326)
b2 <- st_wrap_dateline(st_transform(x = st_buffer(x = st_transform(x = mcp.sf, crs = 4087), dist = d), crs = 4326), options = c("WRAPDATELINE=YES", "DATELINEOFFSET=180"), quiet = TRUE)
plot(b2$geometry, add = T, border = "green", lwd = 2, lty = 2)

image

@rhijmans
Copy link
Member

Thank you for reporting this. This case now works (but there are a few other extreme cases that need to be addressed).

library(terra)
xy <- read.csv("opportunistic-occ2.csv", row.names = 1)
locs <- vect(xy, crs="+proj=longlat")
mcp <- convHull(locs)
b <- terra::buffer(mcp, width = 1000*1000)

maps::map('world', col = 'grey85', fill = T, border = 'grey85')
points(locs, pch = 20, col = "red")
lines(mcp)
lines(b, col="blue", lwd=2)

points

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants