Elisp: Command to Change Earth-Coordinate to Google Map Link

By Xah Lee. Date: . Last updated: .

This page shows a emacs command to turn earth coordinate into Google Map link.

Suppose you have a earth coordinate under cursor, like this:

40°42′46″N 74°00′21″W

or

40.71277777777778 -74.00583333333333

Press a button, and it'll be changed into a Google Map link, like this:

<a href="http://maps.google.com/maps?q=40.71277777777778%2C-74.00583333333333" title="�" target="_blank">Google Map</a>

in browser, with CSS, it shows like this:

Google Map

longitude 352012
Longitude.

Code

Here's the emacs lisp command to do it.

(defun xah-google-map-linkify ()
  "Change coordinate under cursor into a Google Map link.

The current line must be one of the following format:
 40°42′46″N 74°00′21″W
 40.71277777777778 -74.00583333333333

The above is ‹latitude› ‹longitude›
 (That's New York City)
 (Note: latitude is y-axis, longitude is x-axis)

If there's a text selection, use that as input.

Sample result:
 <a href=\"http://maps.google.com/maps?q=40.71277777777778%2C-74.00583333333333\" title=\"�\" target=\"_blank\">Google Map</a>

URL `http://ergoemacs.org/emacs/elisp_make_google-map_link.html'
Version 2016-07-12"
  (interactive)
  (let ($p1 $p2 $input
           $coord-x
           $coord-y
           $coord-y-x
           )
    (if (use-region-p)
        (progn
          (setq $p1 (region-beginning))
          (setq $p2 (region-end)))
      (progn
        (setq $p1 (line-beginning-position))
        (setq $p2 (line-end-position))))

    (setq $input (buffer-substring-no-properties $p1 $p2))
    (if (string-match-p "°" $input)
        (progn
          (setq $coord-y-x (xah-latitude-longitude-decimalize $input))
          (setq $coord-y (aref $coord-y-x 0))
          (setq $coord-x (aref $coord-y-x 1)))
      (progn
        (let ( ($xx (split-string $input  " " "OMIT-NULLS")))
          (setq $coord-y (string-to-number (nth 0 $xx)))
          (setq $coord-x (string-to-number (nth 1 $xx)))
          (setq $coord-y-x (vector $coord-y $coord-x)))))
    (delete-region $p1 $p2)
    (xah-insert-google-map-link "�" $coord-y-x)))

Call “xah-google-map-linkify”.

The following two functions are required.

(defun xah-insert-google-map-link (&optional @title @latlon)
  "Insert HTML link to Google Map.

*title is the title attribute for the HTML link.
*latlon is a vector [y x] where y is latitude, x is longitude. Each must be a decimal number. See also: `xah-latitude-longitude-decimalize'

Example of inserted text:
 <a href=\"http://maps.google.com/maps?q=40.71277777777778%2C-74.00583333333333\" title=\"�\" target=\"_blank\">Google Map</a>

URL `http://ergoemacs.org/emacs/elisp_make_google-map_link.html'
Version 2015-05-12"
  (interactive)
  (let ($title $y $x)
    (setq $title (if @title @title ""))
    (if @latlon
        (progn
          (setq $y (elt @latlon 0))
          (setq $x (elt @latlon 1)))
      (progn
        (setq $y "y�")
        (setq $x "x�")))
    (insert "<a href=\"http://maps.google.com/maps?q=" (number-to-string $y) "%2C" (number-to-string $x) "\" title=\"" $title "\" target=\"_blank\">Google Map</a>\n")))
(defun xah-latitude-longitude-decimalize (@latlon)
  "Convert latitude longitude string *latlon in minutes second format to decimal.
Returns a vector.
For example: 「\"37°26′36.42″N 06°15′14.28″W\"」
becomes 「[37.44345 -6.253966666666667]」
(Note: latitude is “horizontal lines”, longitude is “vertical lines”)

URL `http://ergoemacs.org/emacs/elisp_make_google-map_link.html'
Version 2015-02-08"
  (interactive)
  (let (($tmpPair
         (split-string
          (replace-regexp-in-string "'" "′"
                                    (replace-regexp-in-string "\"" "″"
                                                              (replace-regexp-in-string "''" "″" @latlon t t) t t) t t)
          " +"))
        $latStr $latNum $lonStr $lonNum $deg $min $sec $sign ($c (/ 1.0 60.0)))

    (when (not (equal (length $tmpPair) 2)) (user-error "Error: input can contain only one space"))

    (setq $latStr (elt $tmpPair 0))
    (setq $lonStr (elt $tmpPair 1))
    (if (string-match "\\`\\([0-9]+\\)°\\([0-9]+\\)′\\([.0-9]+\\)″\\(.?\\)\\'" $latStr )
        (progn
          (setq $deg  (string-to-number (match-string 1 $latStr)))
          (setq $min  (string-to-number (match-string 2 $latStr)))
          (setq $sec  (string-to-number (match-string 3 $latStr)))
          (setq $sign (match-string 4 $latStr))
          (setq $latNum (+ $deg (* (+ $min (* $sec $c)) $c)))
          (cond
           ((string= (downcase $sign) "n") nil)
           ((string= $sign "") nil)
           ((string= (downcase $sign) "s") (setq $latNum (* -1 $latNum)))
           (t (user-error "Your input is malformed. Your latitude ends with a char that's not N or S"))))
      (progn (user-error "Your latitude is malformed")))

    (if (string-match "\\`\\([0-9]+\\)°\\([0-9]+\\)′\\([.0-9]+\\)″\\(.?\\)\\'" $lonStr )
        (progn
          (setq $deg  (string-to-number (match-string 1 $lonStr)))
          (setq $min  (string-to-number (match-string 2 $lonStr)))
          (setq $sec  (string-to-number (match-string 3 $lonStr)))
          (setq $sign (match-string 4 $lonStr))
          (setq $lonNum (+ $deg (* (+ $min (* $sec $c)) $c)))
          (cond
           ((string= (downcase $sign) "e") nil)
           ((string= $sign "") nil)
           ((string= (downcase $sign) "w") (setq $lonNum (* -1 $lonNum)))
           (t (user-error "Your input is malformed. Your longitude ends with a char that's not E or W"))))
      (progn (user-error "Your longitude is malformed")))
    (vector $latNum $lonNum)))
Liket it? Put $1 at patreon. Or Buy Xah Emacs Tutorial. Thanks.