沿线串查找坐标 x 距离
Find coordinates x distance along 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')
在示例 code/image 中,我们有一个线串(灰色节点)和红色起点(在本例中为线串起始坐标)。
所需输出示例:
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
)从起点开始沿线串。这感觉很常见,所以如果我错过了一个明显的解决方案,我深表歉意。
我能看到的唯一方法是使用 sf::st_line_sample
以高分辨率进行采样并提取最接近的值。这似乎效率低下,因为我有数千个线串,每个线串只需要一个距离坐标。理想情况下,所提出的方法将与 sf 兼容。
更新了更真实的数据
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提出的测试方法:
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
我不知道为什么这种方法的准确性似乎与距离成比例,但对于我的任务来说这个误差是可以接受的。
我想提出以下解决方案。如您所见,它有一些
缺点,但我认为它可以解决您的问题(取决于所需的
空间精度)首先,加载一些包
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()
:
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。例如:
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)
这两点不完全相同,但很接近。他们都躺在中途
在线串对象中。
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 package (v2.0.0)
于 2021 年 6 月 16 日创建
我想从线串的一端开始沿线串在已知距离处提取点的坐标。
例如:
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')
在示例 code/image 中,我们有一个线串(灰色节点)和红色起点(在本例中为线串起始坐标)。
所需输出示例:
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
)从起点开始沿线串。这感觉很常见,所以如果我错过了一个明显的解决方案,我深表歉意。
我能看到的唯一方法是使用 sf::st_line_sample
以高分辨率进行采样并提取最接近的值。这似乎效率低下,因为我有数千个线串,每个线串只需要一个距离坐标。理想情况下,所提出的方法将与 sf 兼容。
更新了更真实的数据
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提出的测试方法:
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
我不知道为什么这种方法的准确性似乎与距离成比例,但对于我的任务来说这个误差是可以接受的。
我想提出以下解决方案。如您所见,它有一些 缺点,但我认为它可以解决您的问题(取决于所需的 空间精度)首先,加载一些包
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()
:
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。例如:
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)
这两点不完全相同,但很接近。他们都躺在中途 在线串对象中。
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 package (v2.0.0)
于 2021 年 6 月 16 日创建