我正在测量不规则形状的多边形内的点之间的距离。使用 dist 函数,距离是在一条直线上测量的,有时会穿过多边形的线(边界)。
有没有一种方法可以在不使用 R 接触点的情况下找到短路“路径”? 我正在添加一个图像作为例子,我目前正在测量点之间的距离(蓝线)但它横跨多边形。如何计算黄线?
谢谢!
编辑: 这是一些创建多边形和两点的代码:
library(sf) #
mypolygon = data.frame(x = c(-5,-5, 5, 5,3,-3,4, -5),
y = c(-5,5,5,-5,0,0,-4, -5))
p1 = st_as_sf(mypolygon, coords = c("x", "y")); # create a polygon object
p3 = summarise(p1, do_union = FALSE); # combines the points into one vector
p4 = st_cast(p3, "LINESTRING"); # makes a line of the points
plot(p4)
point<-data.frame(x = c(2,4.8), ## added a return point
y = c(-4,-4))
points(point,pch=19,cex=2)
使用您的多边形数据,通过添加“ID”并使用
library(sfheaders)
来简化从 data.frame 创建 sf
对象,因为我没有正确地计算出 summarise(
,我暂时在想以下可能是适合您情况的工作流程(仍在翻阅 sfnetworks
文档,因此将进一步编辑):
library(sf)
library(sfheaders)
library(sfnetworks)
mypolygon_df = data.frame(x = c(-5,-5, 5, 5,3,-3,4, -5),
y = c(-5,5,5,-5,0,0,-4, -5), L1 = c(1,1,1,1,1,1,1,1))
mypolygon_sf = sfheaders::sf_polygon(
obj = mypolygon_df,
x = 'x',
y = 'y',
polygon_id = 'L1')
诀窍是让
mypolygon_sf
内的网格足够小,足以填充空间,同时排除“不是路径/不要在这里游泳”区域。实验导致 n = c(150, 150)
,它可能更大,比如 c(125,125),但是 n = c(100, 100)
产生的多边形太大而无法填充到螃蟹的狭窄爪中,因此 point
在多边形内。太大的多边形也会在入口处形成一个“陆桥”,这会导致与欧几里得距离等价。
n150 = c(150,150)
mypoly_hex_150 = st_make_grid(
mypolygon_sf,
cellsize = c(diff(st_bbox(mypolygon_sf)[c(1,3)]), diff(st_bbox(mypolygon_sf)[c(2,4)]))/n150,
offset = st_bbox(mypolygon_sf)[c('xmin', 'ymin')],
n150,
what = 'polygons',
square = FALSE
)
接下来,我们至少要证明我们可以排除“禁止游泳”区域,尽管通过进一步审查
sfnetworks
文档,这可能会演化为对那些被排除在外的人应用“权重”而不是排除他们,所以他们是'考虑进行最短路径分析。
contains_polysf_hex150 = st_contains_properly(mypolygon_sf, mypoly_hex_150)
plot(st_geometry(mypolygon_sf))
plot(mypoly_hex_150[unlist(contains_polysf_hex150)], col = '#ff000088', add = TRUE)
points(point, pch = 19, col = c('blue', 'red'))
绘图需要很长时间。走到外面,种下 30-40 个球茎,喝点东西,回来查看是否完成。总体而言,想法是用 mypoly_hex_150[unlist(contains_polysf_hex150)] 代替 mypolygon_sf,然后执行图/网络分析。所以,还有更多。