# Geodesy: how to calculate the straight line distance between two locations, which is represented by longitude and latitude?

**URL:** <https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984>\
**Category:** Geo\
**Tags:** diffeq, gmt, geodesy\
**Created:** [January 23, 2019, 2:03pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984 "2019-01-23T14:03:11Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![bsnyh](https://avatars.discourse-cdn.com/v4/letter/b/ce7236/32.png) [@bsnyh](https://discourse.julialang.org/u/bsnyh)\
**Post date:** [January 23, 2019, 2:03pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/1 "2019-01-23T14:03:11Z")

</div>

Is the following the correct way to calculate the straight line distance between two points / locations by longitude and latitude?

```julia
julia> using Geodesy
INFO: Precompiling module Geodesy.

julia> x_lla = LLA(-27.468937, 153.023628, 0.0)
LLA(lat=-27.468937°, lon=153.023628°, alt=0.0)

julia> y_lla = LLA(-27.465933, 153.025900, 0.0)
LLA(lat=-27.465933°, lon=153.0259°, alt=0.0)

julia> distance(x_lla, y_lla)
401.5431022017651

```

Is there a simple / easy way to transfer the longitude and latitude into the x value and y value (cartesian coordinate system) of a point in a planar map?

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [January 23, 2019, 2:09pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/2 "2019-01-23T14:09:19Z")

</div>

A map in what projection?

If you want great circle distance, and are happy to think of the earth as a sphere, then it should just be `arccos(dot(v,w))` where v,w are 3-vectors like `v=[sin(lat), cos(lat)*sin(long), cos(lat)*cos(long)]`… up to units. But perhaps a package called Geodesy will already have this somewhere?

---

<div class="post-metadata">

**Author:** ![bsnyh](https://avatars.discourse-cdn.com/v4/letter/b/ce7236/32.png) [@bsnyh](https://discourse.julialang.org/u/bsnyh)\
**Post date:** [January 23, 2019, 2:43pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/3 "2019-01-23T14:43:40Z")

</div>

@improbable22, I read the package description of Geodesy and the above example if directly from their git link. But I’m not sure I totally understand it.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [January 23, 2019, 2:53pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/4 "2019-01-23T14:53:09Z")

</div>

Sorry perhaps a reading failure on my part.

Now that I look at the readme, it sounds like “distance” is probably a straight-line distance in 3D. Is this what you want?

They say "Future work may focus on geodesics and related calculations " which is what I was aiming for. But the package is more sophisticated than assuming the world is a sphere, and thus working out the accurate great-circle distance (i.e. geodesic length) accurately would be harder work.

---

<div class="post-metadata">

**Author:** ![stephancb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephancb/32/14243_2.png) [@stephancb](https://discourse.julialang.org/u/stephancb)\
**Post date:** [January 23, 2019, 3:28pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/5 "2019-01-23T15:28:49Z")

</div>

To get the cartesian (2d-) distance on a map, have a look at [Proj4.jl](https://github.com/JuliaGeo/Proj4.jl) which is a Julia wrapper around a relatively widely used C library. As @improbable22 already wrote, this depends on the map projection.

---

<div class="post-metadata">

**Author:** ![alejandromerchan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alejandromerchan/32/10500_2.png) [@alejandromerchan](https://discourse.julialang.org/u/alejandromerchan)\
**Post date:** [January 23, 2019, 5:33pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/6 "2019-01-23T17:33:49Z")

</div>

Doesn’t harversine distance in the Distances package work?

```julia
using Distances
julia> l1 = (-27.468937, 153.023628)
julia> l2 = (-27.465933, 153.025900)
julia> haversine(l1, l2, 6372.8)
0.39054922275889736

```

I used it to calculate distances in an agricultural plot.

---

<div class="post-metadata">

**Author:** ![bsnyh](https://avatars.discourse-cdn.com/v4/letter/b/ce7236/32.png) [@bsnyh](https://discourse.julialang.org/u/bsnyh)\
**Post date:** [January 23, 2019, 6:14pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/7 "2019-01-23T18:14:27Z")

</div>

@alejandromerchan, yes. It’s correct. See [Calculate distance and bearing between two Latitude/Longitude points using haversine formula in JavaScript](https://www.movable-type.co.uk/scripts/latlong.html)

---

<div class="post-metadata">

**Author:** ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)\
**Post date:** [March 1, 2020, 5:27pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/8 "2020-03-01T17:27:09Z")

</div>

Just a few words to tell you that you need to be aware that straight line is not the shortest path.

No one here mentioned the difference between [loxodromic route](https://en.wikipedia.org/wiki/Loxodromic_navigation) ie constant bearing and [orthodromic navigation](https://en.wikipedia.org/wiki/Great-circle_navigation) aka great-circle navigation.

I wonder if there is a Julia package which calculate bearing between 2 points (using either loxodromic navigation or orthodromic navigation).

---

<div class="post-metadata">

**Author:** ![anowacki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anowacki/32/17375_2.png) [@anowacki](https://discourse.julialang.org/u/anowacki)\
**Post date:** [March 2, 2020, 4:18pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/9 "2020-03-02T16:18:10Z")

</div>

@scelles, there are several options for calculating _great circle_ paths between points in Julia, including bearings:

- Straightforward Haversine calculations, as explained above—works for spheres only, but easy to implement oneself;
- Vincenty’s algorithm—works for moderately elliptical ellipsoids but has problems with near-antipodal points. A versions is available in [Geodesics.jl](https://github.com/anowacki/Geodesics.jl/) (code mostly originally from [GreatCircle.jl](https://github.com/acrosby/GreatCircle.jl)).
- Charles Karney’s algorithms—work for even very eccentric bodies and all combinations of points, with no slowdown compared to (2). Implemented in [`GeographicLib.inverse`](https://anowacki.github.io/GeographicLib.jl/stable/julia_funcs/#GeographicLib.inverse), or [`Proj4.geod_inverse`](https://github.com/JuliaGeo/Proj4.jl/blob/f9a9bf5ab20cb1f1be719c62784cd966d17e937a/src/proj_functions.jl#L212) (via the Proj4 external library).

I plan to get around to [moving the GeographicLib algorithms into Geodesy.jl](https://github.com/JuliaGeo/Geodesy.jl/pull/53), when time permits.

(I don’t know of any _constant-bearing_ methods implemented in Julia currently.)

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [March 2, 2020, 6:57pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/10 "2020-03-02T18:57:28Z")

</div>

For constant bearing it should only be a question of converting to Mercator (or other conformal projection) and compute the conjugate of the of the straight line angle.

---

<div class="post-metadata">

**Author:** ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)\
**Post date:** [March 3, 2020, 1:55pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/11 "2020-03-03T13:55:02Z")

</div>

> compute the conjugate of the of the straight line angle

@joa-quim I’m not sure to understand what you mean about “conjugate”

In Mercator projection, bearing should simply be angle between segment North-Point1 and Point1-Point2.

Is there some Julia packages to **show** earth (for example) and see how trajectory between two points can be displayed on it and using different map projections?

PS : something like [Orthodromie et loxodromie](http://ressources.univ-lemans.fr/AccesLibre/UM/Pedago/physique/02/divers/ortholoxo.html) but with Julia

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [March 3, 2020, 8:45pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/12 "2020-03-03T20:45:33Z")

</div>

Well, the angle between 2 points in a cartesian axis (theta) is the angle counterclockwise from the x-axis, but bearing (azimuth) is the angle clockwise from North. So _azimuth = 90 - theta_

You can do all sorts of mapping with [GMT.jl](https://github.com/GenericMappingTools/GMT.jl) See for example [this example](https://docs.generic-mapping-tools.org/latest/gallery/ex23.html#example-23) and the corresponding [julia script](https://www.generic-mapping-tools.org/GMT.jl/latest/gallery/historic/ex23/).

And as a simpler example, let’s plot an orthodrome between two points

```julia
ortho = project(start_pt=[-50.0 10], end_pt=[50 60], step=10, km=true);
coast(region=[-180 180 -90 90], proj=:equidistCylindrical, frame=:g, res=:crude, land=:navy, B=:a)
plot!(ortho, lw=3, lc=:green, name="ortho_line.png", show=true)

```

(to plot an loxodrome one could interpolate linearly between two points in a Mercator, convert back to gepgraphic (using _mapproject_) and add that line to the plot below)

 ![ortho_line](https://global.discourse-cdn.com/julialang/original/3X/8/f/8fcbaad616bd57680bd4b6d0f68b67fb133ce5ca.png)

---

<div class="post-metadata">

**Author:** ![anowacki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/anowacki/32/17375_2.png) [@anowacki](https://discourse.julialang.org/u/anowacki)\
**Post date:** [March 3, 2020, 9:40pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/13 "2020-03-03T21:40:29Z")

</div>

If you are only interested in the visualisation, this can be shortened to

```julia
coast(region=[-180 180 -90 90], proj=:equidistCylindrical, frame=:g, res=:crude, land=:navy, B=:a)
plot!([-50 10; 50 60], lw=3, lc=:green, name="ortho_line.png", show=true)

```

since GMT plots great circles between points by default.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [March 3, 2020, 11:08pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/14 "2020-03-03T23:08:00Z")

</div>

😊 Off course. I tried to see if there was an option to generate loxodromes that I forgot the obvious.

---

<div class="post-metadata">

**Author:** ![scelles](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scelles/32/220408_2.png) [@scelles](https://discourse.julialang.org/u/scelles)\
**Post date:** [March 5, 2020, 5:06pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/15 "2020-03-05T17:06:52Z")

</div>

Thanks for your examples with GMT.jl  
Being able to also plot loxodrome will be great!  
I hope it will be possible to have such plots with [GeoMakie.jl](https://github.com/JuliaPlots/GeoMakie.jl/issues/35) also. Pinging @asinghvi17

---

<div class="post-metadata">

**Author:** ![asinghvi17](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/asinghvi17/32/8272_2.png) [@asinghvi17](https://discourse.julialang.org/u/asinghvi17)\
**Post date:** [March 6, 2020, 2:13am UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/16 "2020-03-06T02:13:53Z")

</div>

It should be - if you have the geodesic line, all you need to do is get the coordinates in Mercator space and construct a LinRange for lat and lon - then, you can reproject into any coordinate system.

I haven’t been able to create an example yet, but probably will be able to in the next couple of days.

---

<div class="post-metadata">

**Author:** ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)\
**Post date:** [March 6, 2020, 12:09pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/17 "2020-03-06T12:09:10Z")

</div>

Turns out that GMT can compute loxodromes directly with the module _sample1d_ (sorry the syntax for this case was not yet expanded to the more comprehensible keywords)

```julia
loxo = sample1d([-50 10; 50 60], resamp="R+l", equi_space="10k");
ortho = project(start_pt=[-50.0 10], end_pt=[50 60], step=10, km=true);
coast(region=:global, land=:navy, res=:crude)
plot!(ortho, lw=2, lc=:green)
plot!(loxo, lw=2, lc=:red, name="loxo_ortho.png", show=true)

```

 ![loxo_ortho](https://global.discourse-cdn.com/julialang/original/3X/b/3/b3ff5e601ff18ce83cb062bb164d216c8a783415.png)

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [February 28, 2021, 4:07pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/18 "2021-02-28T16:07:54Z")

</div>

Hey, do you know how to get the geodesic line data (x,y,z)[lon,lat,alt] between two points coordinates?, I would like to have the data and then plot it with whatever library I wish, as you mentioned before.

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [February 28, 2021, 9:01pm UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/19 "2021-02-28T21:01:59Z")

</div>

Here is a translation to Julia of a Matlab code I wrote years ago. It is approximate in that it assumes a spherical earth model, but I found it completely adequate for plotting purposes.

```nohighlight
using LinearAlgebra: ⋅, norm, ×

"""
    gcinterp(p1, p2, dθ)

Compute list of points on a great circle interpolation assuming a spherical earth model.

### Input Arguments

- `p1`, `p2`: Iterables of length 2 containing the longitude λ and lattitude L 
               in degrees of the initial and terminal points of the desired arc.

- `dθ`: The desired angular increment in degrees for point spacing along 
        the interpolated great circle arc.

### Return Value
A vector of ordered pairs `(λᵢ, Lᵢ)` (longitudes and lattitudes in degrees) of
points on the great circle path joining `p1` and `p2`. The arc length spacing of the
points will be equal to or slightly less than `dθ`.
"""
function gcinterp(p1, p2, dθ)
    λ₁, L₁ = float.(p1[1:2])
    λ₂, L₂ = float.(p2[1:2])
    rg1 = ll2rect(λ₁, L₁)
    rg2 = ll2rect(λ₂, L₂)
    ct0 = rg1 ⋅ rg2
    st0 = norm(rg1 × rg2)
    rg1 /= st0
    rg2 /= st0
    θ0 = atand(st0,ct0) # great circle arc length
    n = 1+ceil(Int, θ0/dθ)
    points = [(λ₁,L₁) for _ in 1:n]
    for (i,θ) in enumerate(range(0, θ0, length=n))
        rvec = rg1 * sind(θ0-θ) + rg2 * sind(θ)
        points[i] = rect2ll(rvec)
    end
    points[1] = p1[1], p1[2] # Eliminate rounding errors
    points[n] = p2[1], p2[2]
    points
end

"""
    ll2rect(λ, L)

Convert longitude `λ` and lattitude `L` (both in degreees) to a 3-vector of rectangular coordinates.
"""
function ll2rect(λ, L)
    sinλ, cosλ = sincosd(λ)
    sinL, cosL = sincosd(L)
    [cosL * cosλ, cosL * sinλ, sinL]
end

"""
    rect2ll(rvec)

Convert rectangular coordinates (a 3-vector of unit length) to a (longitude,lattitude) tuple.
Angular units on output are degrees.
"""
function rect2ll(rvec)
    λ = atand(rvec[2], rvec[1])
    L = asind(rvec[3])
    (λ, L)
end

```

Hope this helps.

---

<div class="post-metadata">

**Author:** ![lazarusA](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lazarusa/32/6571_2.png) [@lazarusA](https://discourse.julialang.org/u/lazarusA)\
**Post date:** [March 1, 2021, 7:42am UTC](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984/20 "2021-03-01T07:42:21Z")

</div>

Thanks, this works just fine for plotting. (Assuming we live in an spherical earth 😃 )

[Next page](https://discourse.julialang.org/t/geodesy-how-to-calculate-the-straight-line-distance-between-two-locations-which-is-represented-by-longitude-and-latitude/19984.md?page=2)
