# Decimalizing Latitude and Longitude

Xah Lee has reintroduced a challenge from last year. Given a string of latitude/longitude is degrees, minutes, seconds, write a function that returns them as signed decimal numbers. That is,

```"37°26′36.42″N 06°15′14.28″W" → (37.44345 -6.253966666666667)
```

I remember looking at this challenge last year and thinking it wasn't very interesting but when I started thinking about it this time, I realized that there are a couple of twists that do make it interesting.

Here's my solution in Elisp:

```(require 'cl)

(defun decimalize-lat-lon (lat-lon)
"Decimalize latitude longitude
\"37°26′36.42″N 06°15′14.28″W\" --> (37.44345 -6.253966666666667)"
(let (result)
(dolist (ll (split-string lat-lon " +"))
(destructuring-bind (deg min sec dir)
(split-string ll "[°′″]")
(if (string= "" dir) (error "malformed lat-lon %s" ll))
(let ((factor (if (member dir '("S" "W")) -1 1)))
(push (* factor (+ (string-to-number deg)
(/ (string-to-number min) 60.0)
(/ (string-to-number sec) 3600.0))) result))))
(reverse result)))
```

Elisp purists might complain about my using `dolist`, `destructuring-bind`, and `push` from the Common Lisp package but they're convenient and don't do anything that can't be done a bit more verbosely in pure Emacs Lisp. The real workhorse in this function is the Elisp `split-string` function. It gets used twice: once to split the original string into latitude and longitude and once to break the latitude and longitude into their constituent parts.

The check on whether `dir` is the empty string really checks for any missing constituents and is just a sanity check. I didn't bother rounding the numbers to any particular number of decimal places or making the function a command. Either of those are easily done if the user needs them.

Update: Mickey over at Mastering Emacs and Aaron Hawley in the comments give nice solutions using Emacs `calc`. Mickey's post shows off some of the great features of `calc` so be sure to take a look.

This entry was posted in Programming and tagged , . Bookmark the permalink.