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.