沿线串查找坐标 x 距离 [英] Find coordinates x distance along linestring

查看:58
本文介绍了沿线串查找坐标 x 距离的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提取沿线串已知距离处的点的坐标,从线串的一端开始.

I would like to extract the coordinates of a point at a known distance along the linestring, starting from one end of the linestring.

例如:

library(sf)

path <- st_as_sfc('LINESTRING(10 20, 11 21, 12 21, 13 22)')
start_point <- st_as_sfc('POINT(10 20)')
nodes <- st_as_sfc('MULTIPOINT(10 20, 11 21, 12 21, 13 22)')

plot(st_geometry(path))
plot(st_geometry(nodes), add = T, pch = 16, col = 'grey')
plot(st_geometry(start_point), add = T, pch = 16, col = 'red')

在示例代码/图像中,我们有一个线串(灰色的节点)和红色的起点(在本例中是线串的起始坐标).

In the example code/image we have a linestring (nodes in grey) and the starting point (in this example the linestring starting coordinates) in red.

所需输出的示例:

distance_line <- st_as_sfc('LINESTRING(10 20, 11 21, 11.5 21)')
point_wanted <- st_as_sfc('POINT(11.5 21)')  

plot(st_geometry(distance_line), col = 'green', lwd = 4, add = T)
plot(st_geometry(point_wanted), add = T, pch = 16, col = 'blue')

最终,我想从起点沿线串提取距离 X 处的点的坐标(例如,使用 st_coordinates).这感觉就像一个很普遍的愿望,所以如果我错过了一个明显的解决方案,我深表歉意.

Ultimately, I'm wanting to extract the coordinates (e.g. using st_coordinates) of the point at distance X along the linestring from the starting point. This feels like a common enough desire, so apologies if I have missed an obvious solution.

我能看到的唯一方法是使用 sf::st_line_sample 以高分辨率进行采样并提取最接近的值.这似乎效率低下,因为我有数千个线串,每个线串只需要一个距离坐标.理想情况下,所提出的方法将与 sf 兼容.

The only method I can see is to sample, using sf::st_line_sample, at a high resolution and extract the nearest value. This seems inefficient as I have many thousand linestrings with each only needing one distance coordinates. Ideally, the proposed method would be sf compatible.

更新了更真实的数据

path <- st_as_sf(data.frame(X = c(444618, 444640, 444661), Y = c(216561, 216556, 216550), L1 = 1), coords = c('X', 'Y'), crs = 27700) %>% 
      group_by(L1) %>%
      summarise(do_union = F) %>% 
      st_cast('LINESTRING')

nodes <- st_as_sf(data.frame(X = c(444618, 444640, 444661), Y = c(216561, 216556, 216550), L1 = 1), coords = c('X', 'Y'), crs = 27700) 

@agila 提出的测试方法:

Testing method proposed by @agila:

    st_distance(nodes)[1,]
    Units: [m]
    [1]  0.00000 22.56103 44.38468

Testing with point 2 and 3.
pt1 <- path %>% st_startpoint()

desired_distance <- units::set_units(22.56103, "m")
ratio <- desired_distance / st_length(path)
pt2 <- st_linesubstring(path, from = 0, to = ratio) %>% st_endpoint()

desired_distance <- units::set_units(44.38468, "m")
ratio <- desired_distance / st_length(path)
pt3 <- st_linesubstring(path, from = 0, to = ratio) %>% st_endpoint()

    (st_distance(pt1, pt2))
    Units: [m]
         [,1]
[1,] 22.56103
    (st_distance(pt1, pt3))
Units: [m]
         [,1]
[1,] 44.36801

我不知道为什么这种方法的准确性似乎与距离成比例,但这个误差对于我的任务来说是可以接受的.

I don't know why the accuracy of this method appears to scale with the distance but this error is acceptable for my task.

推荐答案

我想提出以下解决方案.正如你所看到的,它有一些缺点,但我认为它可以解决您的问题(取决于所需的空间精度)首先加载一些包

I want to propose the following solution. As you can see, it has some drawbacks, but I think it may fix your problem (depending on the required spatial accuracy) First, load some packages

library(sf)
#> Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
library(lwgeom)
#> Linking to liblwgeom 3.0.0beta1 r16016, GEOS 3.9.0, PROJ 7.2.1

然后,创建线串对象

path <- st_as_sfc('LINESTRING(10 20, 11 21, 12 21, 13 22)', crs = 4326)

计算其长度

st_length(path)
#> 407726.3 [m]

如果我们想估计距离起始点 200000 [m] 处的点线串的点,那么我们可以使用st_linesubstring():

If we want to estimate the point at distance 200000 [m] from the starting point of the linestring, then we can use st_linesubstring():

desired_distance <- units::set_units(200000, "m")
ratio <- desired_distance / st_length(path)
(pt <- st_linesubstring(path, from = 0, to = ratio) %>% st_endpoint())
#> Warning in st_linesubstring.sfc(path, from = 0, to = ratio): st_linesubstring
#> does not follow a geodesic; you may want to use st_geod_segmentize first
#> Geometry set for 1 feature 
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: 11.46373 ymin: 21 xmax: 11.46373 ymax: 21
#> Geodetic CRS:  WGS 84
#> POINT (11.46373 21)

我不是 100% 确定该警告消息(您可能想等待其他答案或更好的解释),但我们可以通过转换输入来修复它反对预计的 CRS.例如:

I’m not 100% sure about that warning message (and you may want to wait for other answers or better explanations), but we can fix it by converting the input object to a projected CRS. For example:

path2 <- st_transform(path, 32632)
(pt2 <- st_linesubstring(path2, from = 0, to = ratio) %>% st_endpoint() %>% st_transform(4326))
#> Geometry set for 1 feature 
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: 11.46165 ymin: 21.00073 xmax: 11.46165 ymax: 21.00073
#> Geodetic CRS:  WGS 84
#> POINT (11.46165 21.00073)

这两个点不完全相同但非常接近.他们都躺在中间在线串对象中.

The two points are not identical but quite close. They both lay around midway in the linestring object.

st_distance(pt, pt2)
#> Units: [m]
#>          [,1]
#> [1,] 230.2247

剧情

par(mar = rep(0, 4))
plot(path, reset = FALSE)
plot(pt, add = TRUE, pch = 16, col = "darkgreen", cex = 3)
plot(pt2, add = TRUE, pch = 16, col = "darkred", cex = 2)

reprex 包 (v2.0.0) 于 2021 年 6 月 16 日创建

Created on 2021-06-16 by the reprex package (v2.0.0)

这篇关于沿线串查找坐标 x 距离的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆