简体   繁体   中英

Calculating distances from latitude and longitude coordinates in R

I am trying to calculate distance between one location and all other locations from their latitudes and longitudes.

I have been using distanceTrack from the argosfilter package to calculate the distance between consectuive locations which works very simply as this is a the code I need to make it work:

    lat<-lizard$Latitude
    lon<-lizard$Longitude
    distanceTrack(lat, lon)

But now I am wanting to calculate the distance between the first location and the second location, and then the distance between the first and third location, etc. for all locations.

I have been looking for a way to do this quickly as the only way I have been able to do it is manually copying and pasting the desired coordinates into a different csv file and then uploading it to R and running the above code, which is arduous. I am thinking an apply function or something similar might work. So would an apply function be the right way forward? And I don't know how to write the code to specify the rows to calculate the distance between, so any help with that would be great.

 earthDist <- function (lon1, lat1, lon2, lat2){
    rad <- pi/180
    a1 <- lat1 * rad
    a2 <- lon1 * rad
    b1 <- lat2 * rad
    b2 <- lon2 * rad
    dlon <- b2 - a2
    dlat <- b1 - a1
    a <- (sin(dlat/2))^2 + cos(a1) * cos(b1) * (sin(dlon/2))^2
    c <- 2 * atan2(sqrt(a), sqrt(1 - a))
    R <- 6378.145
    d <- R * c
    return(d)
}

earthDist(lon[1], lat[1], lon, lat)

Sample input data I'll use:

p <- data.frame(lat=runif(6,-90,90), lon=runif(6,-180,180) );
p;
##         lat        lon
## 1 -27.85808  160.23800
## 2  31.14363  -45.22589
## 3 -50.01119   48.84754
## 4  68.11402   71.46464
## 5  45.58087 -104.46365
## 6  87.49930  -88.12699

If you only want the distances between the first point and all subsequent points, you can do this:

d <- sapply(2:nrow(p), function(x) distance(p$lat[x],p$lat[1],p$lon[x],p$lon[1]) );
d;
## [1] 17517.58  9037.04 12806.45 12557.67 13196.02

If you want all combinations of points, it's more complicated. In the below, I've switched from a simple vector to a data.frame for the result, so the two point indexes can be stored alongside each distance value:

d <- setNames(do.call(rbind.data.frame,combn(1:nrow(p),2,simplify=F)),c('p1','p2'));
d$dist <- sapply(1:nrow(d), function(r) distance(p$lat[d$p1[r]],p$lat[d$p2[r]],p$lon[d$p1[r]],p$lon[d$p2[r]]) );
d;
##    p1 p2      dist
## 1   1  2 17517.583
## 2   1  3  9037.040
## 3   1  4 12806.448
## 4   1  5 12557.672
## 5   1  6 13196.020
## 6   2  3 12868.340
## 7   2  4  7815.027
## 8   2  5  5276.540
## 9   2  6  6338.329
## 10  3  4 13259.829
## 11  3  5 17961.347
## 12  3  6 15757.656
## 13  4  5  7363.244
## 14  4  6  2694.062
## 15  5  6  4669.714

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM