因此,我需要使用sf
包创建一个R为的多边形,我所拥有的只是一个相对简单的 Dataframe ,在其中我可以看到组成直线、圆弧(多边形边缘的某些部分是圆弧,而不是直线)和圆(这些位于多边形内部,是表面上的洞)的点。
多边形的边是直线或圆弧,它们应该相互连接,这样我就不必使用st_convex_hull
或类似的东西。完整的圆在多边形内部,在多边形的末端是洞。
我是使用sf
的新手,但我已经知道如何处理直线和圆,尽管可能有更好的方法。
我已经创建了3个元素的虚拟数据,每个元素一个,以及我如何构建不同的几何图形。我实际上坚持与弧部分。我很有信心这应该是很容易的,也许使用circularstring
类型,但不确定这是否是最好的方式。显然不会有一个最终的多边形与这些虚拟数据,但希望它得到的想法。
这是虚拟数据和我的代码。
library(tidyverse)
#> Warning: package 'tidyverse' was built under R version 4.0.3
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
(sample <- data.frame(number = 1,
name = c("Arc", "Circle", "Line"),
area = c(0.46, 330, NA),
start_angle = c(134, NA, NA),
angle_total = c(17, NA, NA),
center_x = c(974, 377, NA),
center_y = c(7299, 7250, NA),
center_z = c(0, 0, NA),
length = c(4.27, NA, 15),
radius = c(14, 10.2, NA),
angle = c(NA, NA, 270),
delta_x = c(NA, NA, 0),
delta_y = c(NA, NA, -15),
delta_z = c(NA, NA, 0),
start_x = c(NA, NA, 18.2),
start_y = c(NA, NA, 7000),
start_z = c(NA, NA, 0),
end_x = c(NA, NA, 18.2),
end_y = c(NA, NA, 146),
end_z = c(NA, NA, 0)) %>%
as_tibble())
#> # A tibble: 3 x 20
#> number name area start_angle angle_total center_x center_y center_z length
#> <dbl> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 Arc 0.46 134 17 974 7299 0 4.27
#> 2 1 Circ~ 330 NA NA 377 7250 0 NA
#> 3 1 Line NA NA NA NA NA NA 15
#> # ... with 11 more variables: radius <dbl>, angle <dbl>, delta_x <dbl>,
#> # delta_y <dbl>, delta_z <dbl>, start_x <dbl>, start_y <dbl>, start_z <dbl>,
#> # end_x <dbl>, end_y <dbl>, end_z <dbl>
line_start <- sample %>%
filter(name == "Line") %>%
select(start_x, start_y) %>%
rename(X = start_x, Y = start_y) %>%
mutate(ID = 1:nrow(.))
line_end <- sample %>%
filter(name == "Line") %>%
select(end_x, end_y) %>%
rename(X = end_x, Y = end_y) %>%
mutate(ID = 1:nrow(.))
(lines <- line_start %>%
bind_rows(line_end) %>%
st_as_sf(coords = c("X", "Y")) %>%
group_by(ID) %>%
summarise(do_union = FALSE) %>%
st_cast("LINESTRING"))
#> `summarise()` ungrouping output (override with `.groups` argument)
#> Simple feature collection with 1 feature and 1 field
#> geometry type: LINESTRING
#> dimension: XY
#> bbox: xmin: 18.2 ymin: 146 xmax: 18.2 ymax: 7000
#> CRS: NA
#> # A tibble: 1 x 2
#> ID geometry
#> <int> <LINESTRING>
#> 1 1 (18.2 7000, 18.2 146)
# ggplot() +
# geom_sf(data = lines) +
# coord_sf(xlim = c(10, 20))
circle_centers <- sample %>%
filter(name == "Circle") %>%
select(center_x, center_y) %>%
rename(X = center_x, Y = center_y) %>%
mutate(ID = 1:nrow(.))
circle_radii <- sample %>%
filter(name == "Circle") %>%
select(radius) %>%
rename(R = radius) %>%
mutate(ID = 1:nrow(.))
(circle <- circle_centers %>%
st_as_sf(coords = c("X", "Y")) %>%
st_buffer(circle_radii$R))
#> Simple feature collection with 1 feature and 1 field
#> geometry type: POLYGON
#> dimension: XY
#> bbox: xmin: 366.8 ymin: 7239.8 xmax: 387.2 ymax: 7260.2
#> CRS: NA
#> # A tibble: 1 x 2
#> ID geometry
#> * <int> <POLYGON>
#> 1 1 ((387.2 7250, 387.186 7249.466, 387.1441 7248.934, 387.0744 7248.404, 3~
# ggplot() +
# geom_sf(data = circle)
# ggplot() +
# geom_sf(data = rbind(lines, circle)) +
# coord_sf(xlim = c(-500, 1000))
由reprex package(v0.3.0)于2020年12月3日创建
唯一缺少的步骤是将所有这些几何体组合起来,得到最终的内部有洞的多边形,但一旦我有了所有分离的几何体,这应该很容易。
还有可能有更好的方法来处理线和圆的部分。同样,我刚刚开始与sf
,所以请随时教我更有效的方法,如果你知道一个。
提前感谢你的帮助!
1条答案
按热度按时间irtuqstp1#
所以,让我们从头开始,以及如何使
circularstring
从样本数据我有(这是autoCAD导出数据顺便说一句)。这是通过弧的中心(黄色)、端点(绿色和红色)和弧的中点(蓝色)来完成大部分的重物搬运:
从这里开始构建您的
circularstring
是非常有策略的:密谋检查一切是否良好:
现在,棘手的部分是结束一个多边形,因为通常情况下,一个弧的末端,例如,应该与一条线,这两个点(端点)应该在完全相同的坐标上,但实际上不是。因此形状不闭合,
st_polygon
不能做任何事情。因为多边形是由弧和线组成的(圆是该形状内的孔),你可以用st_segmentize()
来沿着直线添加点,然后用concaveman::concaveman(concavity = 0.1)
,其中concavity
是一个猜测,你必须自己找到它。我记不住所有的细节,但是concaveman()
只考虑点来构造多边形,而不考虑线或弧,因此需要在调用它之前添加点。希望这是sheshing一些光,可以对某人有用。