Bash Snippet: Calculating the Distance Between 2 Coordinates

I have a tendency to do things in bash that I’d probably be better off doing in perl or python. Although bash may have super powers, math is not one of them, and so like my last post this script also requires bc. I’ll try and keep these code snippet posts short and sweet, and yes this is my feeble attempt to pad my year-end post numbers.

Calculate the distance between two longitude and latitude points in bash:

deg2rad () {
        bc -l <<< "$1 * 0.0174532925"
}

rad2deg () {
        bc -l <<< "$1 * 57.2957795"
}

acos () {
        pi="3.141592653589793"
        bc -l <<<"$pi / 2 – a($1 / sqrt(1 – $1 * $1))"
}

distance () {
        lat_1="$1"
        lon_1="$2"
        lat_2="$3"
        lon_2="$4"
        delta_lat=`bc <<<"$lat_2$lat_1"`
        delta_lon=`bc <<<"$lon_2$lon_1"`
        lat_1="`deg2rad $lat_1`"
        lon_1="`deg2rad $lon_1`"
        lat_2="`deg2rad $lat_2`"
        lon_2="`deg2rad $lon_2`"
        delta_lat="`deg2rad $delta_lat`"
        delta_lon="`deg2rad $delta_lon`"

        distance=`bc -l <<< "s($lat_1) * s($lat_2) + c($lat_1) * c($lat_2) * c($delta_lon)"`
        distance=`acos $distance`
        distance="`rad2deg $distance`"
        distance=`bc -l <<< "$distance * 60 * 1.15078"`
        distance=`bc <<<"scale=4; $distance / 1"`
        echo $distance
}

# Keywest, FL to Cuba
distance 23.137160859692981.68746948242188 24.54079389806876781.76849365234375

Edit: Top Google result for “calculate the distance between two coordinates in bash” isn’t even done in bash, but rather compiled C code called from a bash script. Seriously Dave Taylor, you have a series of articles at Linux Journal called “Work the Shell”, and this is what you came up with? At least I tried.

Comments

4 responses to “Bash Snippet: Calculating the Distance Between 2 Coordinates”

  1. rkkki Avatar
    rkkki

    Hi, excellent tutorial.
    But, what is the unit parameter? Metric or Imperial?
    How may I convert to meters?
    Thanks

    I’ll bookmark to see the answer, please help me.

  2. Julien Lamarche Avatar
    Julien Lamarche

    Pretty sure I copied this verbatim and got 79 kms isntead of the correct 51 kms.

    Here’s the xtrace of the function:

    ++ distance 45.401244 -75.74193 45.28713 -75.10282
    ++ earth_radius=3960.00
    ++ lat_1=45.401244
    ++ lon_1=-75.74193
    ++ lat_2=45.28713
    ++ lon_2=-75.10282
    +++ bc
    ++ delta_lat=-.114114
    +++ bc
    ++ delta_lon=.63911
    +++ deg2rad 45.401244
    +++ bc -l
    ++ lat_1=.7924011913
    +++ deg2rad -75.74193
    +++ bc -l
    ++ lon_1=-1.3219460588
    +++ deg2rad 45.28713
    +++ bc -l
    ++ lat_2=.7904095263
    +++ deg2rad -75.10282
    +++ bc -l
    ++ lon_2=-1.3107914850
    +++ deg2rad -.114114
    +++ bc -l
    ++ delta_lat=-.0019916650
    +++ deg2rad .63911
    +++ bc -l
    ++ delta_lon=.0111545737
    +++ bc -l
    ++ distance=.9998
    +++ acos .9998
    +++ pi=3.141592653589793
    +++ bc -l
    ++ distance=.0200
    +++ rad2deg .0200
    +++ bc -l
    ++ distance=1.1459155
    +++ bc -l
    ++ distance=79.1713018
    +++ bc
    ++ distance=79.1713
  3. Claude Avatar
    Claude

    Nice, thanks for the script!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.