Point at distance and bearing¶
Function destPoint returns the location of point given a point of origin, and a distance and bearing. Its perhaps obvious use in georeferencing locations of distant sitings. It can also be used to make circular polygons (with a fixed radius, but in longitude/latitude coordinates)
library(geosphere) LA <- c(-118.40, 33.95) NY <- c(-73.78, 40.63) destPoint(LA, b=65, d=100000) ## lon lat ## [1,] -117.4152 34.32706 circle=destPoint(c(0,80), b=1:365, d=1000000) circle2=destPoint(c(0,80), b=1:365, d=500000) circle3=destPoint(c(0,80), b=1:365, d=100000) plot(circle, type='l') polygon(circle, col='blue', border='black', lwd=4) polygon(circle2, col='red', lwd=4, border='orange') polygon(circle3, col='white', lwd=4, border='black')
Below is triangulation example. We have three locations (NY, LA, MS) and three directions (281, 60, 195) towards a target. Because we are on a sphere, there are two (antipodal) results. We only show one here (by only using int[,1:2]). We compute the centroid from the polygon defined with the three points. To accurately draw a spherical polygon, we can use makePoly. This function inserts intermediate points along the paths between the vertices provided (default is one point every 10 km).
MS <- c(-93.26, 44.98) gc1 <- greatCircleBearing(NY, 281) gc2 <- greatCircleBearing(MS, 195) gc3 <- greatCircleBearing(LA, 55) data(wrld) plot(wrld, type='l', xlim=c(-125, -70), ylim=c(20, 60)) lines(gc1, col='green') lines(gc2, col='blue') lines(gc3, col='red') int <- gcIntersectBearing(rbind(NY, NY, MS), c(281, 281, 195), rbind(MS, LA, LA), c(195, 55, 55)) int ## lon lat lon lat ## [1,] -94.40975 41.77229 85.59025 -41.77229 ## [2,] -102.91692 41.15816 77.08308 -41.15816 ## [3,] -93.63298 43.97765 86.36702 -43.97765 distm(rbind(int[,1:2], int[,3:4])) ## [,1] [,2] [,3] [,4] [,5] [,6] ## [1,] 0.0 713665.0 253077.7 20003931.5 19308947.3 19751854.8 ## [2,] 713665.0 0.0 823532.8 19308947.3 20003931.5 19195862.0 ## [3,] 253077.7 823532.8 0.0 19751854.8 19195862.0 20003931.5 ## [4,] 20003931.5 19308947.3 19751854.8 0.0 713665.0 253077.7 ## [5,] 19308947.3 20003931.5 19195862.0 713665.0 0.0 823532.8 ## [6,] 19751854.8 19195862.0 20003931.5 253077.7 823532.8 0.0 int <- int[,1:2] points(int) poly <- rbind(int, int[1,]) centr <- centroid(poly) poly2 <- makePoly(int) polygon(poly2, col='yellow') points(centr, pch='*', col='dark red', cex=2)
Below we first compute the distance and bearing from Los Angeles (LA) to New York (NY). These are then used to compute the point from LA at that distance in that (initial) bearing (direction). Bearing changes continuously when traveling along a Great Circle. The final bearing, when approaching NY, is also given.
d <- distCosine(LA, NY) d ##  3977614 b <- bearing(LA, NY) b ##  65.93893 destPoint(LA, b, d) ## lon lat ## [1,] -73.83063 40.63262 NY ##  -73.78 40.63 finalBearing(LA, NY) ##  93.90995
What if we went off-course and were flying over Minneapolis (MS)? The closest point on the planned route (p) can be computed with the alongTrackDistance and destPoint functions. The distance from ‘p’ to MS can be computed with the dist2gc (distance to great circle, or cross-track distance) function. The light green line represents the along-track distance, and the dark green line represents the cross-track distance.
atd <- alongTrackDistance(LA, NY, MS) p <- destPoint(LA, b, atd) plot(wrld, type='l', xlim=c(-130,-60), ylim=c(22,52)) gci <- gcIntermediate(LA, NY) lines(gci, col='blue', lwd=2) points(rbind(LA, NY), col='red', pch=20, cex=2) points(MS, MS, pch=20, col='blue', cex=2) lines(gcIntermediate(LA, p), col='green', lwd=3) lines(gcIntermediate(MS, p), col='dark green', lwd=3) points(p, pch=20, col='red', cex=2)
dist2gc(LA, NY, MS) ##  549733.7 distCosine(p, MS) ##  548738.9
Rhumb (from the Spanish word for course, ‘rumbo’) lines are straight lines on a Mercator projection map (and at most latitudes pretty straight on an equirectangular projection (=unprojected lon/lat) map). They were used in navigation because it is easier to follow a constant compass bearing than to continually adjust direction as is needed to follow a great circle, even though rhumb lines are normally longer than great-circle (orthodrome) routes. Most rhumb lines will gradually spiral towards one of the poles.
NP <- c(0, 85) SF <- c(-122.44, 37.74) bearing(SF, NP) ##  5.15824 b <- bearingRhumb(SF, NP) b ##  41.45714 dc <- distCosine(SF, NP) dr <- distRhumb(SF, NP) dc / dr ##  0.8730767 pr <- destPointRhumb(SF, b, d=round(dr/100) * 1:100) pc <- rbind(SF, gcIntermediate(SF, NP), NP) par(mfrow=c(1,2)) plot(wrld, type='l', xlim=c(-140,10), ylim=c(15,90), main='Equirectangular') lines(pr, col='blue') lines(pc, col='red') data(merc) plot(merc, type='l', xlim=c(-15584729, 1113195), ylim=c(2500000, 22500000), main='Mercator') lines(mercator(pr), col='blue') lines(mercator(pc), col='red')