[英]Create equidistant points along (Poly)line in R
If I have a Spatial Lines object like this: 如果我有像这样的空间线对象:
require(sp)
x <- c(18.25721, 18.25763,18.25808,18.25846,18.25864,18.25886,18.25892,18.25913,18.25940,18.25962,
18.25976,18.25997,18.26021,18.26048,18.26061,18.26086,18.26107,18.26128,18.26154,18.26219,
18.26276,18.26350,18.26445,18.26510,18.26584,18.26668,18.26704,18.26807,18.26850,18.26944,
18.27020,18.27080,18.27111,18.27134,18.27168,18.27191,18.27217,18.27254,18.27309,18.27345,
18.27368,18.27389,18.27398,18.27400,18.27392,18.27383,18.27370)
y <- c(44.69540,44.69539,44.69544,44.69552,44.69563,44.69586,44.69608,44.69644,44.69672,44.69687
,44.69701,44.69718,44.69737,44.69763,44.69771,44.69778,44.69781,44.69781,44.69782,44.69776
,44.69772,44.69778,44.69794,44.69805,44.69814,44.69822,44.69824,44.69826,44.69821,44.69805
,44.69775,44.69737,44.69728,44.69717,44.69701,44.69687,44.69671,44.69649,44.69616,44.69598
,44.69578,44.69560,44.69539,44.69513,44.69490,44.69476,44.69453)
river<-SpatialLines(list(Lines(Line(cbind(x,y)), ID="a")))
proj4string(river) <- CRS("+init=epsg:4326")
How is it possible to create points along this line every 3m for example. 例如,如何沿着这条线每3米创建一次点。 The result would look something like this: 结果看起来像这样:
I cant figure it out or find a package that just does that. 我无法弄明白或找到一个只是这样做的包。
what about the spsample() function from sp package ? sp包中的spsample()函数怎么样? You will just sample n points, where 你只需要在n点采样,在哪里
numOfPoints <- gLength(river) / 3
spsample(river, n = numOfPoints, type = "regular")
(gLength is function from rgeos package ) (gLength是rgeos包的功能)
Attribute n does not have to be an integer, so you should get pretty close estimation. 属性n不必是整数,因此您应该得到非常接近的估计。
Don't know of any library but you can achieve the result this way: 不知道任何库,但你可以这样实现结果:
norm_vec <- function(x) sqrt(sum(x^2))
new_point <- function(p0, p1, di) { # Finds point in distance di from point p0 in direction of point p1
v = p1 - p0
u = v / norm_vec(v)
return (p0 + u * di)
}
find <- function(river, M) {
result = river[1,,drop=FALSE]
# for all subsequent points p1, p2 in this data.frame norm_vec(p2 - p1) = M at all times
equidistantPoints = river[1,,drop=FALSE]
river = tail(river, n = -1)
accDist = 0
while (length(river) > 0) {
point = river[1,]
lastPoint = result[1,]
dist = norm_vec(point - lastPoint)
if ( accDist + dist > M ) {
np = new_point(lastPoint, point, M - accDist)
equidistantPoints = rbind(np, equidistantPoints) # add np to equidistantPoints
result = rbind(np, result) # add np to result
accDist = 0 # reset accDist
} else {
#move point from river to result
river = tail(river, n = -1)
result = rbind(point, result)
#update accDist
accDist = accDist + dist
}
}
allPoints = result[NROW(result):1,] # reverse result
return(list(newPoints = equidistantPoints, allPoints = allPoints))
}
See it plotted: 看它画了:
r = cbind(x,y)
result = f(r, 0.003)
plot(result$allPoints, type="l", col="red", asp = 1)
points(result$allPoints, col="red")
points(result$newPoints, col="cyan")
The basic idea is that we keep moving along the river and calculate distance from last "checkpoint" when we realise that the accDist + dist > M
then it means that between lastPoint
and point
a new point np
must be created such that accDist + dist_to_new_point = M
. 基本的想法是,当我们意识到accDist + dist > M
然后它意味着在lastPoint
和point
之间必须创建一个新点np
使得accDist + dist_to_new_point = M
时,我们继续沿着河流移动并计算距离上一个“检查点”的距离accDist + dist_to_new_point = M
We add this point to result and moving along the river. 我们将这一点添加到结果并沿着河流移动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.