Search code examples
rcoordinateslatitude-longitudegeosphere

Calculate minimum distance between GPS points using geosphere gives inaccuate values


I am trying to calculate the mean distance between nearest neighbor of a series of GPS points in R. I found two codes to get the values. But it doesn't appear to give the correct distance in meters. When I check against Google Maps, its' way off.

I found this answer: R - Finding closest neighboring point and number of neighbors within a given radius, coordinates lat-long

library(geosphere)
sp.groups <- groups
coordinates(sp.groups) <- ~Long+Lat
class(sp.groups)
d<- distm(sp.groups)
min.d<- apply(d, 1, function(x) order(x, decreasing=F)[2])
min.d
mean(min.d)
groupdist<- cbind(groups, groups[min.d,], apply(d, 1, function(x) order(x, decreasing=F)[2]))
colnames(groupdist)<- c(colnames(groups), 'neighbor', 'n.lat', 'n.long','dist')

And here using the package rgeos, but it gives the same results: Calculate the distance between two points of two datasets (nearest neighbor)

library(rgeos)
sp.groups <- groups
coordinates(sp.groups) <- ~Long+Lat
proj4string(sp.groups) <-CRS("+proj=utm +datum=WGS84")
class(sp.groups)
d<- gDistance(sp.groups, byid=TRUE)
min.d<- apply(d, 1, function(x) order(x, decreasing=F)[2])
min.d
mean(min.d)
groupdist<- cbind(groups, groups[min.d,], apply(d, 1, function(x) order(x, decreasing=F)[2]))
colnames(groupdist)<- c(colnames(groups), 'neighbor', 'n.lat', 'n.long','dist')

When I go and check on Google Earth the distances can be way off. And it even gives different values for nearest neighbors by 160-200m. Also some of the nearest neighbors don't have the same distance values, see K11 and K3 then K3 and K11. Here's the results I get, and I added expected values from Google Maps:

Group Lat        Long      neighbor  n.lat      n.long    dist  GMaps
K1    -26.96538  21.80965  K34       -26.96503  21.80940  27    44
K10   -26.96575  21.81132  K1        -26.96538  21.80965  1     172
K11   -26.96249  21.81120  K3        -26.96387  21.81053  22    166
K24   -26.96033  21.81090  K11       -26.96249  21.81120  3     240
K3    -26.96387  21.81053  K11       -26.96249  21.81120  3     166
K34   -26.96503  21.80940  K1        -26.96538  21.80965  1     44

What is wrong?

My data

groups<-data.frame(Group = c('K1', 'K10', 'K11', 'K24', 'K3', 'K34'), 
Lat = c(-26.96538, -26.96575, -26.96249, -26.96033, -26.96387, -25.96503), 
Longitude = c(21.80965, 21.81132, 21.81120, 21.80190, 21.81053, 21.80940))

Solution

  • I am not sure what you tried to calculate here but the column distance just refers to the position/number of the point with the minimum distance. I added a number with the actual minimum distances which look like the result you expected.

    library(geodist, include.only = NULL)
    library(sp, include.only = NULL)
    
    groups <- data.frame(Group = c('K1', 'K10', 'K11', 'K24', 'K3', 'K34'), 
                         Lat   = c(-26.96538, -26.96575, -26.96249, -26.96033, -26.96387, -25.96503), 
                         Long  = c(21.80965, 21.81132, 21.81120, 21.80190, 21.81053, 21.80940))
    
    sp.groups <- groups
    sp::coordinates(sp.groups) <- ~Long+Lat
    
    # mindistance Matrix
    d <- geodist::geodist(groups, measure = "cheap")
    
    
    # position of minimum distance
    diag(d) <- Inf
    min.d <- max.col(-d)
    min.d
    #> [1] 2 1 5 5 3 4
    
    
    groupdist <- cbind(groups, groups[min.d,], min.d)
    colnames(groupdist) <- c(colnames(groups), 'neighbor', 'n.lat', 'n.long','closest_to')
    
    # get minimum distance for each pair of coordinates
    groupdist$distance <- d[cbind(seq_along(min.d), min.d)]
    groupdist
    #>     Group       Lat     Long neighbor     n.lat   n.long closest_to    distance
    #> 2      K1 -26.96538 21.80965      K10 -26.96575 21.81132          2    171.1554
    #> 1     K10 -26.96575 21.81132       K1 -26.96538 21.80965          1    171.1554
    #> 5     K11 -26.96249 21.81120       K3 -26.96387 21.81053          5    167.2225
    #> 5.1   K24 -26.96033 21.80190       K3 -26.96387 21.81053          5    944.4119
    #> 3      K3 -26.96387 21.81053      K11 -26.96249 21.81120          3    167.2225
    #> 4     K34 -25.96503 21.80940      K24 -26.96033 21.80190          4 110613.1362
    

    Created on 2021-08-22 by the reprex package (v2.0.1)