无法使R中的st_buffer函数的”flat” endcapStyle参数生效。

huangapple go评论65阅读模式
英文:

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 &lt;- 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 &lt;- df_tbl %&gt;% select(lon, lat) %&gt;% st_as_sf(coords = c(&quot;lon&quot;, &quot;lat&quot;), crs = 4326)  
end_t &lt;- df_tbl %&gt;% select(lon2, lat2) %&gt;% st_as_sf(coords = c(&quot;lon2&quot;, &quot;lat2&quot;), crs = 4326)  

# combine start and end geometries
cbind(beg_t,end_t) -&gt; points_ready 

# create linestrings

line_segments &lt;- points_ready %&gt;% 
  mutate(
    path = st_sfc(purrr::map2(
      .x = geometry, 
      .y = geometry.1, 
      .f = ~{st_union(c(.x, .y)) %&gt;% st_cast(&quot;LINESTRING&quot;)}
    ),
    crs = 4326)) 

## try to use the FLAT endCapStyles
line_segments$buffer &lt;- st_buffer(line_segments$path, dist = 2000, endCapStyle = &quot;FLAT&quot;)
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)

无法使R中的st_buffer函数的”flat” endcapStyle参数生效。


[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&#39;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 &lt;- 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 &lt;- df_tbl %&gt;% select(lon, lat) %&gt;% st_as_sf(coords = c(&quot;lon&quot;, &quot;lat&quot;), crs = 4326)  
end_t &lt;- df_tbl %&gt;% select(lon2, lat2) %&gt;% st_as_sf(coords = c(&quot;lon2&quot;, &quot;lat2&quot;), crs = 4326)  

# combine start and end geometries
cbind(beg_t,end_t) -&gt; points_ready 

# create linestrings

line_segments &lt;- points_ready %&gt;% 
  mutate(
    path = st_sfc(purrr::map2(
      .x = geometry, 
      .y = geometry.1, 
      .f = ~{st_union(c(.x, .y)) %&gt;% st_cast(&quot;LINESTRING&quot;)}
    ),
    crs = 4326)) 

## try to use the FLAT endCapStyles
buffered_lines &lt;- line_segments$path %&gt;% 
  st_transform(&quot;EPSG:3857&quot;) %&gt;% # to force GEOS processing
  st_buffer(endCapStyle = &quot;FLAT&quot;,
            dist = 2000)

mapview(line_segments$path) + mapview(buffered_lines)  

无法使R中的st_buffer函数的”flat” endcapStyle参数生效。

huangapple
  • 本文由 发表于 2023年4月7日 02:57:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75952876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定