【问题标题】:Generate uniform distributed geo points around a geo point (Lat,Long) in a radius在半径内的地理点(纬度,经度)周围生成均匀分布的地理点
【发布时间】:2021-01-01 06:34:51
【问题描述】:

在给定距离的情况下,是否有更好的方法可以在起点周围生成 N 个纬度/经度坐标?这是我的方法,但它不会创建均匀分布。

generate_gps_coordinates_in_circle<-function(start_lat,start_lon,max_distance_in_m,min_distance_in_m){
  
  lat <- (start_lat * pi / 180) #center of the circle
  lon <- (start_lon * pi / 180) #center of the circle
  earth_radius <- 6371000
  distance <- sqrt(runif(1, 0, 1) * (max_distance_in_m ** 2 - min_distance_in_m ** 2) + min_distance_in_m ** 2) #max and min distance from the center
  delta_lat = cos(runif(1) *  pi) * distance / earth_radius
  sign = runif(1, 0, 2) * 2 - 1
  delta_lon = sign * acos(((cos(distance/earth_radius) - cos(delta_lat)) / (cos(lat) * cos(delta_lat + lat))) + 1)
  result <- c(lon = (lon + delta_lon) * 180 / pi, lat =(lat + delta_lat) * 180 / pi)
  return(result)
}

【问题讨论】:

  • 在正方形上创建均匀分布并排除距离起点大于r 的点会更容易吗?
  • 我认为这确实是一个概率问题而不是编程问题。困难在于球体上的圆圈与平面上的圆圈不同,例如如果距离是地球周长的一半,则边界的长度为零;它只是球体另一侧的点。
  • 艾伦这也行!你能举个例子吗?
  • user2554330 嗯可能是。我用这个解决方案得到了一些“拉伸”的图片.. 即点不是以“圆形”分布的
  • 查看这些帖子:CrossValidated 1, 2

标签: r gis r-raster


【解决方案1】:

您可以使用geosphere 包中的函数destPoint 来获取给定点的坐标,该点是给定方位角和距地球表面原点的距离。通过runif(1) * 360 获得随机方位很简单。但是,如果您希望点周围的密度均匀,则需要将均匀随机变量的平方根作为距离。

因此,我们可以使用destPoint 重写您的函数,还可以利用矢量化,以便我们可以返回n 点的数据帧:

generate_gps_coordinates_in_circle <- function(
  start_lat, start_lon, max_distance_in_m, min_distance_in_m, n = 1)
{
  d <- geosphere::destPoint(c(start_lon, start_lat), 360 * runif(n), 
    min_distance_in_m + (max_distance_in_m - min_distance_in_m) * sqrt(runif(n)))
  setNames(as.data.frame(d), c("lon", "lat"))
}

这让我们可以这样做:

df <- generate_gps_coordinates_in_circle(54, 0, 200, 0, n = 1000)

head(df)
#>             lon      lat
#> 1 -0.0010012322 53.99864
#> 2  0.0028912625 53.99959
#> 3  0.0021632655 54.00045
#> 4 -0.0006538438 53.99894
#> 5  0.0014026358 54.00087
#> 6  0.0005882192 54.00172

而且我们可以看到效果令人满意,在小距离处产生了一个圆圈:

plot(df$lon, df$lat)

但是在较大距离处适当扭曲的圆:

df <- generate_gps_coordinates_in_circle(54, 0, 2000e3, 0, n = 1000)
plot(df$lon, df$lat)

【讨论】:

  • 这适用于max_distance_in_m &lt; 4e6,但之后地球的球形度非常明显。对于更大的值,我会使用geosphere::randomCoordinates(10*n),并拒绝任何geosphere::distGeo() 大于目标距离的点。
  • 非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
  • 1970-01-01
  • 1970-01-01
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多