R/GIS:找到位置和最近线之间的正交距离

use*_*432 11 gis r

我试图找到一组位置坐标和一组线(道路或河流)之间的正交距离.点集以纬度/经度对的形式出现,并且行在shapefile(.shp)中.他们绘制的地图上是没有问题的,无论是使用maptools还是PBSmapping.但我的基本问题是找到从一个地方到达道路或河流的最小距离.在R中有没有办法做到这一点?

mds*_*ner 21

如果我理解正确,你可以gDistancergeos包装中做到这一点.

读入行SpatialLines/DataFrame和作为点SpatialPoints/DataFrame,然后循环每个点计算距离每次:

require(rgeos)
## untested code
shortest.dists <- numeric(nrow(sp.pts))
for (i in seq_len(nrow(sp.pts)) {
    shortest.dists[i] <- gDistance(sp.pts[i,], sp.lns)
}
Run Code Online (Sandbox Code Playgroud)

sp.pts是空间点对象,sp.lns是空间线对象.

您必须循环以便仅将单个坐标sp.pts与所有线几何中的全部进行比较sp.lns,否则您将获得跨所有点的聚合值的距离.

由于您的数据是纬度/经度,因此您应该将线和点转换为合适的投影,因为该gDistance函数采用笛卡尔距离.

更多讨论和示例(编辑)

获取线上最近的点而不仅仅是距离是很简洁的,但是这会打开另一个选项,即您是否需要沿着一条线的最近坐标,或者是一个实际的交点,其线段比任何一条线都更近现有的顶点.如果您的顶点足够密集以至于差异无关紧要,那么请spDistsN1sp包中使用.你必须从集合中的每一行中提取所有坐标(不是很难,但有点难看),然后遍历每个感兴趣点计算到行顶点的距离 - 然后你可以找到哪个是最短的并选择从顶点集合坐标,这样您就可以轻松获得距离和坐标.由于函数可以使用带longlat = TRUE参数的椭圆距离,因此无需投影.

library(maptools)

## simple global data set, which we coerce to Lines
data(wrld_simpl)

wrld_lines <- as(wrld_simpl, "SpatialLinesDataFrame")

## get every coordinate as a simple matrix (scary but quick)
wrld_coords <- do.call("rbind", lapply(wrld_lines@lines, function(x1) do.call("rbind", lapply(x1@Lines, function(x2) x2@coords[-nrow(x2@coords), ]))))
Run Code Online (Sandbox Code Playgroud)

以交互方式进行检查,您必须对其进行修改以节省坐标或最小距离.这将绘制线条并等待您单击绘图中的任何位置,然后它将从您的单击绘制一条线到一条线上最近的顶点.

## no out of bounds clicking . . .
par(mar = c(0, 0, 0, 0), xaxs = "i", yaxs = "i") 

plot(wrld_lines, asp = "")

n <- 5

for (i in seq_len(n)) {
xy <- matrix(unlist(locator(1)), ncol = 2)
    all.dists <- spDistsN1(wrld_coords, xy, longlat = TRUE)
    min.index <- which.min(all.dists)
    points(xy, pch = "X")
lines(rbind(xy, wrld_coords[min.index, , drop = FALSE]), col = "green", lwd = 2)
}
Run Code Online (Sandbox Code Playgroud)