Work the Shell - Calculating the Distance between Two Latitude/Longitude Points
To get everything to work well, I actually hacked and slashed at the original script to make it a bit more succinct and, of course, invoke the C “distance” program as shown in Listing 1. [Listing 1 also is available on our FTP site at ftp.linuxjournal.com/pub/lj/listings/issue188/10606.tgz.] Ready? It's surprisingly short:
#!/bin/sh converter="http://api.maps.yahoo.com/ajax/ ↪geocode?appid=onestep&qt=1&id=m&qs=" tmpfile="/tmp/bc.script.$$" # Get lat/long for point 1 addr="$(echo $1 | sed 's/ /+/g')" values="$(curl -s $converter$addr | \ cut -d\" -f13,15 | \ sed 's/[^0-9\.\,\-]//g;s/,$//')" lat1=$(echo $values | cut -d, -f1) long1=$(echo $values | cut -d, -f2) # Get lat/long for point 2 addr="$(echo $2 | sed 's/ /+/g')" values="$(curl -s $converter$addr | \ cut -d\" -f13,15 | \ sed 's/[^0-9\.\,\-]//g;s/,$//')" lat2=$(echo $values | cut -d, -f1) long2=$(echo $values | cut -d, -f2) # Now we have the lat/long for both points, let's # figure out the distance between them... dist=$(./distance $lat1 $long1 $lat2 $long2) echo "$1 to $2 is $dist miles" exit 0
The script would be even shorter if we tweaked the C program to accept x,y location pairs, but I'll leave that one to you. Instead, let's do a few tests:
$ farapart.sh \ "union station, denver, co" \ "union station, chicago, il" union station, denver, co to union station, chicago, il is 917.984 miles
Now, how about something a bit more ambiguous:
$ farapart.sh "long beach, ca" "boston, ma" long beach, ca to boston, ma is 2597.53 miles
Well, darn it, that seems way too short. Let's see what Yahoo Maps reports as the distance between those two cities. Sure enough, it reports that the trip should be 3,015 miles, not 2,597 miles.
Somewhere there's an error that's giving us poor results. My guess is there's some sort of significant rounding error going on in the C program (because we can verify experimentally that the lat/lon information we're getting is valid, simply by plugging it in to a mapping app and seeing where it places us).
I'm all tapped out on this example, however. It turned out to be far more tricky than I anticipated, and I leave it as an exercise to you, dear reader, to see if you can figure out what's broken in the C program and report your fix to us. We'll publish the best of them next month! Meanwhile, next column, I'll get back to something that's more about the shell and less about mathematics. I mean, heck, I didn't like math when I was working on my computer science degree, so why am I playing with it now?
Dave Taylor has been involved with UNIX since he first logged in to the on-line network in 1980. That means that, yes, he's coming up to the 30-year mark now. You can find him just about everywhere on-line, but start here: www.DaveTaylorOnline.com. In addition to all his other projects, Dave is now a film critic. You can read his reviews at www.DaveOnFilm.com.
Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.
Practical books for the most technical people on the planet. Newly available books include:
- Agile Product Development by Ted Schmidt
- Improve Business Processes with an Enterprise Job Scheduler by Mike Diehl
- Finding Your Way: Mapping Your Network to Improve Manageability by Bill Childers
- DIY Commerce Site by Reven Lerner
Plus many more.
- diff -u: What's New in Kernel Development
- Server Hardening
- Giving Silos Their Due
- 22 Years of Linux Journal on One DVD - Now Available
- What's New in 3D Printing, Part III: the Software
- Controversy at the Linux Foundation
- Don't Burn Your Android Yet
- Firefox OS
- February 2016 Issue of Linux Journal