How to calculate distance between several fixes(GPS points) to a single (specific point) and return to a dataframe for IDs, Lat/Long and column for the distance

Hi, could anyone please help me how to calculate the distance between a specific geographic (GPS) point and multiple points for different IDs. I have pasted the primary output of all the points for IDs and Lat/Long: I would like to calculate the distance from these point to this specific point (Latitude: 22.41235, Longitude: 92.38767).Then I would like to create a matrix of ID, the original Lat and Long and the output " distance from this specific GPS point" in a new column.

structure(list(ID = c("ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
"ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
"ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
"ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
"ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
"ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID2",
"ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
"ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
"ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
"ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
"ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
"ID2", "ID2", "ID2", "ID2"), Latitude = c(22.15733, 22.1508,
22.152249, 22.15686, 22.1508, 22.15184, 22.1521, 22.15516, 22.15137,
22.15838, 22.15078, 22.15932, 22.15942, 22.15937, 22.15732, 22.15527,
22.15733, 22.15148, 22.15244, 22.15702, 22.15511, 22.15876, 22.15866,
22.1557, 22.15813, 22.16191, 22.16227, 22.16226, 22.16121, 22.16535,
22.16563, 22.16495, 22.16256, 22.1625, 22.16497, 22.16335, 22.16464,
22.16512, 22.16542, 22.16342, 22.16568, 22.1635, 22.16104, 22.16323,
22.162557, 22.16102, 22.16245, 22.16227, 22.162321, 22.1614,
22.22376, 22.24522, 22.24535, 22.24435, 22.22383, 22.22381, 22.22362,
22.22351, 22.22343, 22.2234, 22.22359, 22.22376, 22.22391, 22.22401,
22.22384, 22.22348, 22.22711, 22.22711, 22.22681, 22.22649, 22.22692,
22.22708, 22.22656, 22.2266, 22.22708, 22.22718, 22.22744, 22.22727,
22.22391, 22.22448, 22.22446, 22.22624, 22.22674, 22.22651, 22.22611,
22.22617, 22.22599, 22.22418, 22.22637, 22.22424, 22.22392, 22.24445,
22.24411, 22.24395, 22.2442, 22.24396, 22.24539, 22.24363, 22.24279,
22.24419), Longtitude = c(92.3299, 92.32269, 92.32289, 92.33346,
92.32235, 92.3223, 92.3223, 92.32631, 92.32234, 92.3337, 92.324697,
92.33263, 92.33263, 92.33263, 92.32956, 92.33215, 92.3299, 92.32248,
92.3249, 92.33222, 92.33203, 92.3337, 92.33392, 92.33013, 92.33112,
92.34243, 92.34205, 92.34244, 92.34371, 92.34028, 92.3406, 92.34003,
92.34324, 92.34367, 92.33984, 92.34328, 92.34059, 92.37019, 92.34018,
92.34394, 92.34015, 92.34155, 92.34337, 92.34173, 92.34326, 92.3428,
92.34368, 92.34305, 92.34261, 92.34261, 92.27397, 92.28837, 92.28838,
92.28864, 92.27408, 92.27402, 92.27392, 92.27376, 92.27366, 92.27357,
92.27393, 92.27399, 92.27391, 92.27393, 92.27383, 92.27374, 92.27608,
92.27593, 92.27559, 92.27577, 92.27545, 92.27533, 92.27532, 92.27539,
92.27557, 92.27568, 92.27562, 92.27553, 92.18207, 92.18164, 92.18217,
92.18157, 92.18096, 92.18117, 92.18168, 92.18162, 92.18154, 92.1817,
92.18175, 92.1821, 92.18213, 92.28967, 92.2891, 92.28899, 92.28915,
92.2884, 92.28833, 92.28823, 92.288989, 92.28898)), class = "data.frame", row.names = c(NA,
-100L))
ID Latitude Longtitude
1 ID1 22.15733 92.32990
2 ID1 22.15080 92.32269
3 ID1 22.15225 92.32289
4 ID1 22.15686 92.33346
5 ID1 22.15080 92.32235
6 ID1 22.15184 92.32230

I suggest you consider the sf::st_distance() function; you will probably want to set by_element argument to TRUE so that a vector of distances is returned.

Hi Jindra, thank you for your response. I have run a code and produced the only difference for the long/lat in the dataset. But how can I calculate distances from the specific point (Latitude: 22.41235, Longitude: 92.38767) to all points in the dataset. Then I would like to return the dataframe with IDs, all gps points and additional column of the distance output.

so far i have done this:

distance<-read.csv("distance.csv")
distance<-distance[,1:3]
distance.sp<-distance[c("ID","Latitude","Longitude")]
distance<-st_as_sf(distance,coords=c("Longitude","Latitude"),crs=4326)

distance %>%

  • st_set_crs(4326) %>%
  • mutate(
  • distance_to_next = sf::st_distance(geometry), 
    
  • by_element = TRUE)
    

First 10 features:
ID geometry distance_to_next by_element
1 ID1 POINT (92.3299 22.15733) 0.00000 [m] TRUE
2 ID1 POINT (92.32269 22.1508) 1037.28365 [m] TRUE
3 ID1 POINT (92.32289 22.15225) 916.18653 [m] TRUE
4 ID1 POINT (92.33346 22.15686) 370.87677 [m] TRUE
5 ID1 POINT (92.32235 22.1508) 1062.71021 [m] TRUE
6 ID1 POINT (92.3223 22.15184) 992.03216 [m] TRUE
7 ID1 POINT (92.3223 22.1521) 974.65430 [m] TRUE
8 ID1 POINT (92.32631 22.15516) 441.43373 [m] TRUE
9 ID1 POINT (92.32234 22.15137) 1021.59869 [m] TRUE
10 ID1 POINT (92.3337 22.15838) 408.84160 [m] TRUE

Well, consider this code:

What it does it:

  • creates start and end objects in {sf} package data format
  • prepares a {leaflet} overview as a sanity check - do both data points look about right?
  • creates distance column in your end object; it contains all the information you provided + distance from the common origin
library(sf)
library(dplyr)
library(leaflet)

start <- data.frame(lat = c(22.41235),
                    lon = c(92.38767)) %>% 
  st_as_sf(coords = c("lon", "lat"), crs = 4326)


end <- structure(list(ID = c("ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
                      "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
                      "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
                      "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
                      "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
                      "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID1", "ID2",
                      "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
                      "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
                      "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
                      "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
                      "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2",
                      "ID2", "ID2", "ID2", "ID2"), Latitude = c(22.15733, 22.1508,
                                                                22.152249, 22.15686, 22.1508, 22.15184, 22.1521, 22.15516, 22.15137,
                                                                22.15838, 22.15078, 22.15932, 22.15942, 22.15937, 22.15732, 22.15527,
                                                                22.15733, 22.15148, 22.15244, 22.15702, 22.15511, 22.15876, 22.15866,
                                                                22.1557, 22.15813, 22.16191, 22.16227, 22.16226, 22.16121, 22.16535,
                                                                22.16563, 22.16495, 22.16256, 22.1625, 22.16497, 22.16335, 22.16464,
                                                                22.16512, 22.16542, 22.16342, 22.16568, 22.1635, 22.16104, 22.16323,
                                                                22.162557, 22.16102, 22.16245, 22.16227, 22.162321, 22.1614,
                                                                22.22376, 22.24522, 22.24535, 22.24435, 22.22383, 22.22381, 22.22362,
                                                                22.22351, 22.22343, 22.2234, 22.22359, 22.22376, 22.22391, 22.22401,
                                                                22.22384, 22.22348, 22.22711, 22.22711, 22.22681, 22.22649, 22.22692,
                                                                22.22708, 22.22656, 22.2266, 22.22708, 22.22718, 22.22744, 22.22727,
                                                                22.22391, 22.22448, 22.22446, 22.22624, 22.22674, 22.22651, 22.22611,
                                                                22.22617, 22.22599, 22.22418, 22.22637, 22.22424, 22.22392, 22.24445,
                                                                22.24411, 22.24395, 22.2442, 22.24396, 22.24539, 22.24363, 22.24279,
                                                                22.24419), Longtitude = c(92.3299, 92.32269, 92.32289, 92.33346,
                                                                                          92.32235, 92.3223, 92.3223, 92.32631, 92.32234, 92.3337, 92.324697,
                                                                                          92.33263, 92.33263, 92.33263, 92.32956, 92.33215, 92.3299, 92.32248,
                                                                                          92.3249, 92.33222, 92.33203, 92.3337, 92.33392, 92.33013, 92.33112,
                                                                                          92.34243, 92.34205, 92.34244, 92.34371, 92.34028, 92.3406, 92.34003,
                                                                                          92.34324, 92.34367, 92.33984, 92.34328, 92.34059, 92.37019, 92.34018,
                                                                                          92.34394, 92.34015, 92.34155, 92.34337, 92.34173, 92.34326, 92.3428,
                                                                                          92.34368, 92.34305, 92.34261, 92.34261, 92.27397, 92.28837, 92.28838,
                                                                                          92.28864, 92.27408, 92.27402, 92.27392, 92.27376, 92.27366, 92.27357,
                                                                                          92.27393, 92.27399, 92.27391, 92.27393, 92.27383, 92.27374, 92.27608,
                                                                                          92.27593, 92.27559, 92.27577, 92.27545, 92.27533, 92.27532, 92.27539,
                                                                                          92.27557, 92.27568, 92.27562, 92.27553, 92.18207, 92.18164, 92.18217,
                                                                                          92.18157, 92.18096, 92.18117, 92.18168, 92.18162, 92.18154, 92.1817,
                                                                                          92.18175, 92.1821, 92.18213, 92.28967, 92.2891, 92.28899, 92.28915,
                                                                                          92.2884, 92.28833, 92.28823, 92.288989, 92.28898)), class = "data.frame", row.names = c(NA,
                                                                                                                                                                                  -100L)) %>% 
  st_as_sf(coords = c("Longtitude", "Latitude"), crs = 4326)

# sanity check - do the points look all right?
leaflet() %>% 
  addProviderTiles("CartoDB.Positron") %>% 
  addCircleMarkers(data = start,
                   fillColor = "red",
                   stroke = F) %>% 
  addCircleMarkers(data = end,
                   fillColor = "blue",
                   stroke = F)

# calculate the distance
end$distance <- st_distance(start, end, by_element = T)


# check result
head(end)
Simple feature collection with 6 features and 2 fields
geometry type:  POINT
dimension:      XY
bbox:           xmin: 92.3223 ymin: 22.1508 xmax: 92.33346 ymax: 22.15733
geographic CRS: WGS 84
   ID                  geometry     distance
1 ID1  POINT (92.3299 22.15733) 28860.15 [m]
2 ID1  POINT (92.32269 22.1508) 29726.61 [m]
3 ID1 POINT (92.32289 22.15225) 29565.64 [m]
4 ID1 POINT (92.33346 22.15686) 28837.77 [m]
5 ID1  POINT (92.32235 22.1508) 29734.53 [m]
6 ID1  POINT (92.3223 22.15184) 29623.53 [m]
1 Like

Hi Jindra, Thank you very much for that, it works good.
I wonder how to get the distance [km] which is now [m].

The result of sf::st_distance() is a {units} object, so there are two options for you to consider:

  • drop the units and divide by a 1000 via as.numeric(end$distance)/1000
  • transform the units via units::set_units(end$distance, km)

Both approaches should give you roughly equivalent outcome (the second will still be a units object, the first a plain number, but othervise the same figure).

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.