英文:
Unable to get "flat" endcapStyle to work for st_buffer in R
问题
我目前正在使用经度/纬度坐标创建SFC linestrings表,并绘制缓冲区。但是,我无法使endCapStyle = "FLAT"
参数起作用。我希望它能够起作用,因为我需要确保缓冲区不延伸到线的端点之外。我漏掉了什么?
library(sf)
library(mapview)
library(tidyverse)
## 示例中的随机坐标
df_tbl <- tibble::tribble(
~lat, ~lon, ~lat2, ~lon2,
39.977917887303626, -105.28350982984472, 40.026678120413961, -105.20312377997453,
39.934422269952776, -105.25986687400055, 39.902061443935025, -105.28605599432022)
## 创建点
beg_t <- df_tbl %>% select(lon, lat) %>% st_as_sf(coords = c("lon", "lat"), crs = 4326)
end_t <- df_tbl %>% select(lon2, lat2) %>% st_as_sf(coords = c("lon2", "lat2"), crs = 4326)
# 合并起始和结束几何图形
cbind(beg_t, end_t) -> points_ready
# 创建linestrings
line_segments <- points_ready %>%
mutate(
path = st_sfc(purrr::map2(
.x = geometry,
.y = geometry.1,
.f = ~{st_union(c(.x, .y)) %>% st_cast("LINESTRING")}
),
crs = 4326))
## 尝试使用FLAT endCapStyles
line_segments$buffer <- st_buffer(line_segments$path, dist = 2000, endCapStyle = "FLAT")
mapview(line_segments$path) + mapview(line_segments$buffer) ## 缓冲区的末端不是平的
这段代码的问题是,endCapStyle
参数在st_buffer
函数中不是合法的参数。因此,缓冲区的末端不会被平掉。要使缓冲区的末端变平,您需要使用其他方法。
英文:
I am currently creating a table of sfc linestrings using lat/lon coordinates, and drawing a buffer. However, I am unable to get the endcapstyle = "FLAT" argument to work. I would like this to work as I need the buffer to not extend past the end points of the lines. What am I missing?
library(sf)
library(mapview)
library(tidyverse)
## random coordinates for example
df_tbl <- tibble::tribble(
~lat, ~lon, ~lat2, ~lon2,
39.977917887303626, -105.28350982984472, 40.026678120413961, -105.20312377997453,
39.934422269952776, -105.25986687400055, 39.902061443935025, -105.28605599432022)
## create points
beg_t <- df_tbl %>% select(lon, lat) %>% st_as_sf(coords = c("lon", "lat"), crs = 4326)
end_t <- df_tbl %>% select(lon2, lat2) %>% st_as_sf(coords = c("lon2", "lat2"), crs = 4326)
# combine start and end geometries
cbind(beg_t,end_t) -> points_ready
# create linestrings
line_segments <- points_ready %>%
mutate(
path = st_sfc(purrr::map2(
.x = geometry,
.y = geometry.1,
.f = ~{st_union(c(.x, .y)) %>% st_cast("LINESTRING")}
),
crs = 4326))
## try to use the FLAT endCapStyles
line_segments$buffer <- st_buffer(line_segments$path, dist = 2000, endCapStyle = "FLAT")
mapview(line_segments$path) + mapview(line_segments$buffer) ## the buffers are not flat at the ends
答案1
得分: 2
endCapStyle 只在 GEOS 设置中有效,它与{s2}球面操作的不兼容。您可以选择要么完全关闭{s2}处理,要么重新投影到一个平面坐标系。
在以下代码中,我选择了第二种方法,使用 Web Mercator (EPSG 3857)。
此外,我选择将缓冲线创建为一个单独的对象,因为点和线是在 WGS84 坐标系下的,我不太喜欢在一个对象中混合不同的坐标系({sf}的活动/非活动几何特性应该可以处理,但感觉不太对)。
library(sf)
library(mapview)
library(tidyverse)
## 用于示例的随机坐标
df_tbl <- tibble::tribble(
~lat, ~lon, ~lat2, ~lon2,
39.977917887303626, -105.28350982984472, 40.026678120413961, -105.20312377997453,
39.934422269952776, -105.25986687400055, 39.902061443935025, -105.28605599432022)
## 创建点
beg_t <- df_tbl %>% select(lon, lat) %>% st_as_sf(coords = c("lon", "lat"), crs = 4326)
end_t <- df_tbl %>% select(lon2, lat2) %>% st_as_sf(coords = c("lon2", "lat2"), crs = 4326)
# 合并起始和结束几何对象
cbind(beg_t, end_t) -> points_ready
# 创建线串
line_segments <- points_ready %>%
mutate(
path = st_sfc(purrr::map2(
.x = geometry,
.y = geometry.1,
.f = ~{st_union(c(.x, .y)) %>% st_cast("LINESTRING")}
),
crs = 4326))
## 尝试使用 FLAT endCapStyles
buffered_lines <- line_segments$path %>%
st_transform("EPSG:3857") %>% # 强制使用 GEOS 处理
st_buffer(endCapStyle = "FLAT",
dist = 2000)
mapview(line_segments$path) + mapview(buffered_lines)
[1]: https://i.stack.imgur.com/EjapV.png
<details>
<summary>英文:</summary>
The endCapStyle will work only in GEOS settings = it is not compatible with {s2} world of spherical operations. You can either turn off {s2} processing entirely, or re-project to a planar CRS.
In the following code I am using the second approach, going for Web Mercator (EPSG 3857).
Also I am choosing to create the buffered lines as a separate object, since the points and lines are in WGS84, and I don't quite like mixing CRSes in a single object (the active / non active geometry feature of {sf} should handle it, but it does not *feel* right).
```r
library(sf)
library(mapview)
library(tidyverse)
## random coordinates for example
df_tbl <- tibble::tribble(
~lat, ~lon, ~lat2, ~lon2,
39.977917887303626, -105.28350982984472, 40.026678120413961, -105.20312377997453,
39.934422269952776, -105.25986687400055, 39.902061443935025, -105.28605599432022)
## create points
beg_t <- df_tbl %>% select(lon, lat) %>% st_as_sf(coords = c("lon", "lat"), crs = 4326)
end_t <- df_tbl %>% select(lon2, lat2) %>% st_as_sf(coords = c("lon2", "lat2"), crs = 4326)
# combine start and end geometries
cbind(beg_t,end_t) -> points_ready
# create linestrings
line_segments <- points_ready %>%
mutate(
path = st_sfc(purrr::map2(
.x = geometry,
.y = geometry.1,
.f = ~{st_union(c(.x, .y)) %>% st_cast("LINESTRING")}
),
crs = 4326))
## try to use the FLAT endCapStyles
buffered_lines <- line_segments$path %>%
st_transform("EPSG:3857") %>% # to force GEOS processing
st_buffer(endCapStyle = "FLAT",
dist = 2000)
mapview(line_segments$path) + mapview(buffered_lines)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论