【问题标题】:Points within a distance from a point点距离内的点
【发布时间】:2020-04-07 00:18:45
【问题描述】:

我一直试图把这个正确,实际上它正在工作,但距离是错误的:

  • 1- 我有一个积分集合
  • 2- 我有一个点,我需要在其中找到所有符合条件的点 200m远
  • 3- 通常,它应该返回 6 个点,但它只返回 4 个
library(sf)
library(geosphere)

​
#My points
x<-c(2.3009132,2.2999853,2.2995872,2.2985374,2.2991502,2.2984043,2.3054471,2.3009132,2.3048155,2.3014964)
y<-c(48.8511847,48.8505062,48.8502346,48.8495305,48.8499405,48.8494376,48.8542721,48.8511847,48.853842,48.8515819)​
y<-c(48.8511847,48.8505062,48.8502346,48.8495305,48.8499405,48.8494376,48.8542721,48.8511847,48.853842,48.8515819)
df<-data.frame(x=x,y=y)
#Transforming to SF object 
sdf<-st_transform(st_as_sf(df, coords = c("x", "y"), 
                           crs = 4326, agr = "constant"),3857)
#My point to which I need to calculte
pnt<- st_transform( 
    st_sfc(st_point(x = c(2.3009132, 48.8511847)), crs = 4326), 3857)
#A buffer of 200m arround my point
buffer <- st_buffer(pnt,200)
#getting points within the buffer
intr <- st_intersects(sdf, buffer, sparse=F)
#transforming back to lon/lat
sdf <- st_transform(sdf,4326)

#getting the selected points
sdf<-sdf[which(unlist(intr)),]

#Only 4 points were found
> sdf
Simple feature collection with 4 features and 0 fields
geometry type:  POINT
dimension:      XY
bbox:           xmin: 256033.2 ymin: 6249533 xmax: 256201.4 ymax: 6249715
epsg (SRID):    3857
proj4string:    +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs
                  geometry
1 POINT (256136.5 6249648)
2 POINT (256033.2 6249533)
3 POINT (256136.5 6249648)
4 POINT (256201.4 6249715)

#To verify I have calculated the distance to my point
t_sdf<-df%>% mutate(d = by(df, 1:nrow(df), function(row) {
+     distHaversine(c(row$x, row$y), c(2.3009132, 48.8511847), r = 6378137)
+ }))
#6 points are less than 200m to my point
> t_sdf %>% arrange(d)
          x        y         d
1  2.300913 48.85118   0.00000
2  2.300913 48.85118   0.00000
3  2.301496 48.85158  61.48172
4  2.299985 48.85051 101.61024
5  2.299587 48.85023 143.59844
6  2.299150 48.84994 189.36954
.....

【问题讨论】:

    标签: r sf geosphere


    【解决方案1】:

    我不知道你是如何计算到你的点的距离的。但是,当您使用您提供的数据进行计算时,只有 4 个点落入圆圈中。也许您可以使用 QGIS 或 ArcGIS 来验证这一点。但这是你的 4 个点在圆圈内的样子:

    【讨论】:

    • distHaversine 计算两点之间的最短距离(即“大圆距离”或“乌鸦飞”),我还测试了 distGeo 和其他它们都给出了相同的结果。
    • FWIW,我已经获取了这些数据并计算了直线距离,并使用了单独的半正弦距离实现,并得到了与问题中的 OP 相同的结果。顺便说一句,我在查看数据时也得到了与此答案相同的结果。
    • 很奇怪。不过要注意的一件事是,当我绘制数据时。尽管一切都以米为单位(单位=m),但 x 和 y 轴的单位是纬度。我已经编辑了我上面的图片。
    • 也许尝试使用不同的投影
    【解决方案2】:

    一组点之间的直线(欧几里得)距离因投影而异。

    正如here 所讨论的,3857 不是距离计算的好选择。如果我们使用为法国北部构建的投影,即点所在的位置(可能是EPSG:27561 - NTF (Paris) / Lambert Nord France),我们会得到预期的结果。

    sdf <- st_as_sf(df, coords = c("x", "y"), 
                    crs = 4326, agr = "constant")
    sdf_proj <- st_transform(sdf, 3857)
    sdf_France_proj <- st_transform(sdf, 27561)
    

    大圆距离

    > st_distance(pnt, sdf, by_element = T) %>% sort()
    Units: [m]
     [1]   0.00000   0.00000  61.50611 101.64007 143.64481 189.43485 253.46142 267.67954 411.50933 478.11306
    

    墨卡托 (3857) 欧几里得距离

    > st_distance(pnt_proj, sdf_proj, by_element = T) %>% sort()
    Units: [m]
     [1]   0.00000   0.00000  93.43522 154.41781 218.22699 287.78463 385.04306 406.64205 625.14635 726.33083
    

    法国投影 (27561) 欧几里得距离

    > st_distance(pnt_France_proj, sdf_France_proj, by_element = T) %>% sort()
    Units: [m]
     [1]   0.00000   0.00000  61.50289 101.63477 143.63731 189.42497 253.44822 267.66559 411.48772 478.08794
    

    这里是带有缓冲区的图:

    library(gridExtra)
    
    buffer_proj <- st_buffer(pnt_proj, 200)
    buffer_France_proj <- st_buffer(pnt_France_proj, 200)
    
    proj <- ggplot() + g
    eom_sf(data = buffer_proj, fill = "blue", alpha = 0.5) + 
      geom_sf(data = sdf_proj, color = "red") + 
      ggtitle("Mercator (3857)")
    
    France_proj <- ggplot() + 
      geom_sf(data = buffer_France_proj, fill = "blue", alpha = 0.5) + 
      geom_sf(data = sdf_proj, color = "red") + 
      ggtitle("France proj (27561)")
    
    grid.arrange(proj, France_proj, ncol = 1)
    

    【讨论】:

    • 谢谢,这正是造成这个问题的原因
    • 请,对于我得到的点,如果我想添加一个列,即每个点到框中第一个点的距离(因为它是一条街道,它应该是第一个点街道)
    • 我们实际上在您之前的帖子中讨论过这个问题。在此处查看我的答案的底部-查看 mutate():stackoverflow.com/questions/59250592/…
    • 是的,你是对的,但是,有数千个点,我每次都订购这些点,然后我计算到第一个点的距离。我是地理学的新手,我知道我可以使用 st_bbox 访问 xmin, ymin 第一个点(在给定的街道中)是否总是 c(xmin,ymin) (所以我将不再计算)?
    • 这可能是一个解决方案,但如果没有更仔细地查看您的数据,很难说。我认为您应该创建一个包含更多实际数据的新帖子。这似乎太复杂了,无法在 cmets 中讨论,而且会吸引更多的观众。
    猜你喜欢
    • 2013-02-03
    • 1970-01-01
    • 2017-04-30
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    相关资源
    最近更新 更多