Calculating Distance in R using geosphere - r

library(geosphere)
distm(c(lon1, lat1), c(lon2, lat2), fun = distHaversine)
Just wondering that the code above will be calculated based on the shortest distance between these two points instead of the actual distance.
If possible is there any way to actually calculate the distance accurately let's say in the scenario of bike rides from point A to Point B which never the case of a straight line.
Thanks in advance

Related

Calculate distance of one point in DF with all other points in R

I have a dataframe with around 10,000 points. I want to find to take the first point and check its distance from the second point onwards and if the distance is less than "d" (variable), I remove these two points from df and perform this activity with the first point of the new df.
This is done till there are only 2 points left in the dataframe.
It takes a lot of time. Is there a time-efficient way to do this?
If your points exist in 2D space (e.g. Euclidean), then you can use the Cluster package:
library(cluster)
data(agriculture)
## Dissimilarities using Euclidean metric
d.agr <- daisy(agriculture, metric = "euclidean")
as.matrix(d.agr)
The final matrix will give you the "distance" between each point, according to the metric you set (Euclidean in the above example).

Fastest cartesian distance (R) from each point in SpatialPointsDataFrame to closest points/lines in 2nd shapefile

I want to know the fastest algorithms for obtaining the cartesian distances between each point in a SpatialPointsDataFrame (X) and either (a) the closest point in a second SpatialPointsDataFrame (Y), or (b) the closest line segment in a SpatialLinesDataFrame (Y). So this is basically 2 questions, with perhaps the same answer.
For the lines, I know I can use dist2Line(X,Y, distfun=distGeo) but this is insanely slow. I also tried using nncross, after converting both X and Y to ppp objects, as below. This is did NOT work; heat mapping the new distance measure showed that it does not radiate from Y.
X_ppp <- as(X, "ppp")
Y_psp <- as(Y, "psp")
distR <- nncross(X_ppp,Y_ppp,what="dist",k=1)
X$dist2road <- distR
For lines, I also tried using gDistance(X,Y) but was met with the error, for i=1,2: Spatial object i is not projected; GEOS expects planar coordinates. I think this is because I'm using lat-lon, and it needs a true projection. But all the files i'm working with are lat-lon, and I'm not sure how to choose and specify a projection (for tanzania) w/out coping it from another file.
For points, again using the nncross approach resulted in definitely wrong distances. (In each the point and line case, is this because the output vector is not ordered in the same way that the points within X are? If so, I see now way of outputting an ID for the point within X.)
Also for points, this knn code below did work. But it's clearly not in cartesian distance, and so I'd like to convert it or find some other algorithm that provides cartesian distance.
knn.results = knn(data=coordinates(market.shp),
query=coordinates(tzprice.shp), k=1)
knn.results <- data.frame(knn.results)
tzprice.shp$dist2market <- knn.results[,2]
Basically, my hope is to find the fastest algorithm for each purpose (distance to nearest point, distance to nearest line), with output either in cartesian distance or convertible to cartesian distance. Thanks!
Somebody pointed me towards one possible answer for finding the cartesian distance between each point in a SpatialPointsDataFrame (X) and the closest point in a second SpatialPointsDataFrame (let's call it Y). So that's the first half of my question... perhaps there's a faster method out there, but this way is quite fast, and it DOES return answers in Km, at least if proj=longlat.
tree <- createTree(coordinates(Y))
inds <- knnLookup(tree, newdat=coordinates(X), k=1)
distkm <- sapply(seq_len(nrow(inds)), function(i) spDists(X[i, ], Y[inds[i, ],]))
Still looking for an algorithm that (quickly) finds meters/km from each point in X to the nearest line in a SpatialLinesDataFrame.

r - Calculate shortest distance between 2 points in a delaunay triangulation

Currently I'm working with spatial data and applied a Delaunay triangulation on my data points. I additionally calculated the geodesic distances on the WGS84 ellipsoid for every edge (connection between 2 points) in the triangulation. Now I'm going to search the shortest path between every 2 points in the generated graph and calculate the path distance. The shortest distance should thus be calculated as the sum over all edge distances.
Below is a minimal working example:
library(deldir)
set.seed(31)
x <- runif(100)
y <- runif(100)
d <- deldir(x, y) #preforms tesselation & Delaunay triangulation
#Calculate edge distances (for reasons of simplicity I calculate here Euclidean distances)
geodists <- NULL
for (i in 1:nrow(d$delsgs)) {
geodists[i] <- sqrt((x[d$delsgs[i,5]] - x[d$delsgs[i,6]])^2 + (y[d$delsgs[i,5]] - y[d$delsgs[i,6]])^2)
}
#Plot data
plot(d, wlines="triang")
However, I have no idea how I can perform the shortest path search on the deldir object I created. Thus, I'd be very happy if you could provide some solutions for my problem:
How can I identify which edges are involved in the shortest path between point A and B?
How can I then efficiently calculate the path distance matrix?
Thanks a lot in advance for your help!
There are some path finding algorithms. One of them is A* (Wikipedia Link)
Maybe this helps you.
You can replace the regularly ordered points in an Euclidean Metric by the delaunay points of your collection of points.
Then always go to the next neighbor, which is closest to the finish point.

R spatstat: Units of distances retrieved by nndist

I’m ashamed bothering you with a stupid (but very necessary to me) question. I’ve a bunch of lat/lon points distributed almost randomly within a rectangle of ca. two x three degrees (latitude x longitude).
I need to calculate the maximum distance to the second nearest neighbor as well as the maximum distance to the farthest neighbor. I calculated these using package spatstat,
d2 <- max(nndist(data[,2:3], k = 2)
dn <- max(nndist(data[,2:3], k=(nrow(data))-1))
, respectively, and the distances obtained were 0.3 to 4.2.
I need these distances in kilometers.
So, I supposed that distances provided by nndist where expressed in radians.
So, if θ = a /r, where θ is the subtended angle in radians, a is arc length, and r is Earth radius), then, to calculate a the equations becomes: a = θr.
However, the distances transformed in such a way ranged from:
a = 6371 * 0.3 = 1911.3, and
a= 6371 * 4.2 = 2650.2
This is evidently wrong; since the maximum distance measured using – for example – Qgis between the farthest points is just 480 km…
Can anybody indicate me where am I mistaken?
Thanks a lot in advance!!!
nndist is simply calculating the euclidean distance. It does no unit conversion. As such you have given it values in "degrees", and thus it will return a value whose units are degrees. (not radians).
Thus
6371*0.3*pi/180 = 33.36
will give an approximation of the distance between these points.
A better approach would be to use great circle distances (eg in geosphere or gstat packages or to project the lat/long coordinates onto an appropriate map projection. (rgdal::spTransform will do this) and then nndist will calculate your distances in metres.

GIS: Tunnel to geographical distance approximation

This question is more about math than programming. I am programming a function which takes a square of geographical distance between 2 points with known latitude and longitude as an argument. There's a straightforward way to compute it: calculate dot-product, then take arccos, and multiply by Earth radius. Then square the result and you get the square of geographical distance assuming Earth is a sphere (which is acceptable approximation in my case).
However I would like, if possible, to avoid an expensive arccos() call, especially given that I can easily obtain the square of the tunnel distance (by either Pythagorean theorem or the dot product).
I also read here http://en.wikipedia.org/wiki/Geographical_distance#Tunnel_distance about underestimation formula which I can use to get tunnel distance from geographical distance. In my case however, I need the opposite (tunnel to geographical), and for the square. I played with Taylor series and got a rough approximation:
G square = T2 / (1 - (T2/R2)/12.0) // here G2 is square of geographical distance, T2-square of tunnel, R2-square of Earth radius. I also was able to get a more accurate formula:
G square = T2 / (1 - (T2/R2)/12.0 - ((T2/R2)^2)/240.0).
This last formula gives error of only 3.8mm for G=1000 km, and less than 50cm for G=2000 km.
However, I still cannot mathematically prove this formula, at least when using Taylor series. Wonder if it's possible to get the mathematical proof and also expansion of this formula for larger values of G/T. Thanks!
Why tunnel distance from geo distance?. There is no geo distance. There are many possibilities to calculate a distance between two points on earth.
Just take the two lat/lon cooridnates, and then calculate the distance between them using a simmple cyclindrical projection.
This needs only a cos(centerLatitude), and a multiplication with a factor. (meters_per_degree)
See also Cyclindrical equi distant projection. Up to some kilomters (abou 10 to 100) this gives sufficient accuracy.

Resources