Точки на расстоянии от точки

Я пытался сделать это правильно, на самом деле он работает, но расстояние неправильное:

  • 1- У меня есть набор очков
  • 2- У меня есть точка, в которой мне нужно найти все точки на расстоянии 200 метров
  • 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
.....

person roger    schedule 13.12.2019    source источник


Ответы (2)


Расстояния по прямой (евклидово) между определенным набором точек в разных проекциях различаются.

Как обсуждалось здесь, 3857 - это не лучший выбор для расчета расстояния. Если мы используем проекцию, построенную для Северной Франции, где расположены точки (возможно, EPSG: 27561 - NTF (Paris) / Lambert Nord Франция), мы получаем ожидаемые результаты.

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)

введите описание изображения здесь

person Eugene Chong    schedule 13.12.2019
comment
Спасибо, именно из-за этого возникла проблема - person roger; 13.12.2019
comment
Пожалуйста, для набранных мной очков, если я хочу добавить столбец с расстоянием от каждой точки до первой точки в поле (потому что это улица, это должна быть первая точка на улице) - person roger; 13.12.2019
comment
На самом деле мы обсуждали это в предыдущем вашем посте. См. Нижнюю часть моего ответа здесь - посмотрите на mutate (): stackoverflow.com/questions/59250592/ - person Eugene Chong; 13.12.2019
comment
Да, вы правы, но там тысячи точек, я каждый раз заказываю точки, затем рассчитываю расстояние до первой. Я новичок в геоматике, я знаю, что могу получить доступ к xmin, ymin с помощью st_bbox. Всегда ли первая точка (на данной улице) c (xmin, ymin) (так что я больше не буду приказывать вычислять)? - person roger; 13.12.2019
comment
Думаю, вам не нужно сначала заказывать очки. Все, что вам нужно сделать, это найти первую на каждой улице, найти ее расстояние до всех остальных точек, а затем отсортировать по расстоянию. Но, возможно, я неправильно понимаю вашу проблему. Если это правда, я рекомендую вам создать новый пост и объяснить более подробно. - person Eugene Chong; 13.12.2019
comment
На самом деле у меня несколько улиц, есть ли автоматический способ получить первую точку? Фактически во всех sf-объектах ограничивающие рамки доступны через: st_bbox (df) - person roger; 13.12.2019
comment
возможно, это решение, но, не глядя на ваши данные более внимательно, трудно сказать. Я думаю, вам следует создать новый пост, в котором будет больше ваших фактических данных. Это кажется слишком сложным, чтобы обсуждать его в комментариях, и он получит большую аудиторию. - person Eugene Chong; 13.12.2019

Я не знаю, как вы рассчитываете расстояние до своей точки. Но когда вы проводите вычисления с предоставленными вами данными, в круг попадают только 4 точки. Возможно, вы можете использовать QGIS или ArcGIS, чтобы проверить это. Но вот как ваши 4 точки выглядят внутри круга:

введите описание изображения здесь

person Aliyan Haq    schedule 13.12.2019
comment
distHaversine Вычисляет кратчайшее расстояние между двумя точками (т.е. «расстояние по дуге» или «по прямой»). Я также тестировал distGeo и другие, все они дают одинаковый результат. - person roger; 13.12.2019
comment
FWIW, я взял эти данные и рассчитал расстояние по прямой, используя отдельную реализацию гаверсинусного расстояния, и получил тот же результат, что и OP в вопросе. Кстати, я получаю тот же результат, что и этот ответ, при просмотре данных. - person ander2ed; 13.12.2019
comment
Очень странно. Однако следует отметить, что когда я построил данные. Несмотря на то, что все было в метрах (единицы = м), оси x и y были в широте. Я отредактировал свою фотографию выше. - person Aliyan Haq; 13.12.2019
comment
Может быть, попробуй использовать другую проекцию - person Aliyan Haq; 13.12.2019