R 经纬度点集之间的最大距离
我有一套lng/lat坐标。计算集合中任意两点之间最大距离的有效方法是什么(如果愿意,“最大直径”) 一种简单的方法是计算每两个点之间的距离并获得最大值,但这显然不能很好地扩展R 经纬度点集之间的最大距离,r,algorithm,geospatial,latitude-longitude,cran,R,Algorithm,Geospatial,Latitude Longitude,Cran,我有一套lng/lat坐标。计算集合中任意两点之间最大距离的有效方法是什么(如果愿意,“最大直径”) 一种简单的方法是计算每两个点之间的距离并获得最大值,但这显然不能很好地扩展 编辑:这些点位于一个足够小的区域上,用于测量携带移动设备的人在一天内活动的区域。我认为以下可能是一个有用的近似值,它与点的数量成线性比例,而不是二次比例,并且非常容易实现: 计算各点的质心M 找到距离M最大的点P0 找到距离P0最大的点P1 用P0和P1之间的距离近似最大直径 这可以通过重复步骤3 N次来概括, 取PN-
编辑:这些点位于一个足够小的区域上,用于测量携带移动设备的人在一天内活动的区域。我认为以下可能是一个有用的近似值,它与点的数量成线性比例,而不是二次比例,并且非常容易实现:
- x(P)=(λ(P)-λ(M)+C)cos(φ(P))
- y(P)=φ(P)-φ(M)[这只是为了清楚起见,它也可以是y(P)=φ(P)]
- 最大值((x(PN)-x(PN-1))2+(y(PN)-y(PN-1))2)
- x(P)=sin(φ(P))
- y(P)=cos(φ(P))sin(λ(P))
- z(P)=cos(φ(P))cos(λ(P))
- 最大值((x(PN)-x(PN-1))2+(y(PN)-y(PN-1))2+(z(PN)-z(PN-1))2)
# input: lng, lat (vectors)
rad = pi / 180;
x = (lng - mean(lng)) * cos(lat * rad)
y = (lat - mean(lat))
i = which.max((x - mean(x))^2 + (y )^2)
j = which.max((x - x[i] )^2 + (y - y[i])^2)
# output: i, j (indices)
在我的电脑上,查找1000000个点的索引i
和j
只需不到一秒钟。以下3D版本稍慢,但适用于任何点分布(当λ=±180°线交叉时,无需修改): 根据数据和要求,
k
的计算可以省略(即,结果可以由i
和j
给出)。另一方面,我的实验表明,计算进一步的指数是无用的
应记住,在任何情况下,结果点之间的距离都是一个估计值,是集合“直径”的下限,尽管它通常是直径本身(频率取决于数据)
编辑3:
不幸的是,在极端情况下,平面近似的相对误差可能高达1-1/√3.≅ 42.3%,这可能是不可接受的,即使非常罕见。该算法可以修改,以便有一个大约20%的上限,这是我用指南针和直尺推导出来的(解析解很麻烦)。修改后的算法找到一对具有局部最大距离的点,然后重复相同的步骤,但这次从第一对点的中点开始,可能会找到另一对点:
# input: lng, lat
rad = pi / 180
x = (lng - mean(lng)) * cos(lat * rad)
y = (lat - mean(lat))
i.n_1 = 1 # n_1: n-1
x.n_1 = mean(x)
y.n_1 = 0 # = mean(y)
s.n_1 = 0 # s: square of distance
repeat {
s = (x - x.n_1)^2 + (y - y.n_1)^2
i.n = which.max(s)
x.n = x[i.n]
y.n = y[i.n]
s.n = s[i.n]
if (s.n <= s.n_1) break
i.n_1 = i.n
x.n_1 = x.n
y.n_1 = y.n
s.n_1 = s.n
}
i.m_1 = 1
x.m_1 = (x.n + x.n_1) / 2
y.m_1 = (y.n + y.n_1) / 2
s.m_1 = 0
m_ok = TRUE
repeat {
s = (x - x.m_1)^2 + (y - y.m_1)^2
i.m = which.max(s)
if (i.m == i.n || i.m == i.n_1) { m_ok = FALSE; break }
x.m = x[i.m]
y.m = y[i.m]
s.m = s[i.m]
if (s.m <= s.m_1) break
i.m_1 = i.m
x.m_1 = x.m
y.m_1 = y.m
s.m_1 = s.m
}
if (m_ok && s.m > s.n) {
i = i.m
j = i.m_1
} else {
i = i.n
j = i.n_1
}
# output: i, j
#输入:液化天然气,纬度
rad=pi/180
x=(液化天然气-平均值(液化天然气))*cos(纬度*rad)
y=(横向-平均横向)
i、 n_1=1#n_1:n-1
x、 n_1=平均值(x)
y、 n_1=0#=平均值(y)
s、 n_1=0#s:距离的平方
重复{
s=(x-x.n_1)^2+(y-y.n_1)^2
i、 n=哪个最大值
x、 n=x[i.n]
y、 n=y[i.n]
s、 n=s[i.n]
如果(s.n这里有一个简单的例子,它不能很好地扩展(如您所说),但可能有助于在R中构建解决方案
## lonlat points
n <- 100
d <- cbind(runif(n, -180, 180), runif(n, -90, 90))
library(sp)
## distances on WGS84 ellipsoid
x <- spDists(d, longlat = TRUE)
## row, then column index of furthest points
ind <- c(row(x)[which.max(x)], col(x)[which.max(x)])
## maps
library(maptools)
data(wrld_simpl)
plot(as(wrld_simpl, "SpatialLines"), col = "grey")
points(d, pch = 16, cex = 0.5)
## draw the points and a line between on the page
points(d[ind, ], pch = 16)
lines(d[ind, ], lwd = 2)
## for extra credit, draw the great circle on which the furthest points lie
library(geosphere)
lines(greatCircle(d[ind[1], ], d[ind[2], ]), col = "firebrick")
##lonlat points
n定理#1:沿地球表面任意两个大圆距离的顺序与穿过地球的点之间直线距离的顺序相同
因此,把你的车床长
## lonlat points
n <- 100
d <- cbind(runif(n, -180, 180), runif(n, -90, 90))
library(sp)
## distances on WGS84 ellipsoid
x <- spDists(d, longlat = TRUE)
## row, then column index of furthest points
ind <- c(row(x)[which.max(x)], col(x)[which.max(x)])
## maps
library(maptools)
data(wrld_simpl)
plot(as(wrld_simpl, "SpatialLines"), col = "grey")
points(d, pch = 16, cex = 0.5)
## draw the points and a line between on the page
points(d[ind, ], pch = 16)
lines(d[ind, ], lwd = 2)
## for extra credit, draw the great circle on which the furthest points lie
library(geosphere)
lines(greatCircle(d[ind[1], ], d[ind[2], ]), col = "firebrick")