Elisp: Earth Coordinate to Google Map Link
This page shows a command to turn earth coordinate into Google Map link.
Problem
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 becomes a Google Map link, like this:
<a class="ggMap" href="http://maps.google.com/maps?q=40.71277777777778%2C-74.00583333333333">Location</a>
Solution
Here's the emacs lisp command to do it.
Alt+x xah-google-map-linkify
put this in your Emacs Init File:
;; -*- coding: utf-8; lexical-binding: t; -*- (defun xah-latitude-longitude-decimalize (CoordYX) "Convert latitude longitude string CoordYX in minutes second format to decimal. Return a vector. For example, string 37°26′36.42″N 06°15′14.28″W becomes [37.44345 -6.253966666666667] URL `http://xahlee.info/emacs/emacs/elisp_make_google-map_link.html' Version: 2015-02-08 2023-07-23" (let ((xtmpPair (split-string (replace-regexp-in-string "'" "′" (replace-regexp-in-string "\"" "″" (replace-regexp-in-string "''" "″" CoordYX t t) t t) t t) " +")) xlatStr xlatNum xlonStr xlonNum xdeg xmin xsec xsign (xc (/ 1.0 60.0))) (when (not (equal (length xtmpPair) 2)) (user-error "Error: input can contain only one space")) (setq xlatStr (elt xtmpPair 0) xlonStr (elt xtmpPair 1)) (if (string-match "\\`\\([0-9]+\\)°\\([0-9]+\\)′\\([.0-9]+\\)″\\(.?\\)\\'" xlatStr) (progn (setq xdeg (string-to-number (match-string 1 xlatStr))) (setq xmin (string-to-number (match-string 2 xlatStr))) (setq xsec (string-to-number (match-string 3 xlatStr))) (setq xsign (match-string 4 xlatStr)) (setq xlatNum (+ xdeg (* (+ xmin (* xsec xc)) xc))) (cond ((string-equal (downcase xsign) "n") nil) ((string-equal xsign "") nil) ((string-equal (downcase xsign) "s") (setq xlatNum (* -1 xlatNum))) (t (user-error "Input is malformed. Your latitude ends with a char that's not N or S")))) (progn (user-error "Latitude is malformed"))) (if (string-match "\\`\\([0-9]+\\)°\\([0-9]+\\)′\\([.0-9]+\\)″\\(.?\\)\\'" xlonStr) (progn (setq xdeg (string-to-number (match-string 1 xlonStr))) (setq xmin (string-to-number (match-string 2 xlonStr))) (setq xsec (string-to-number (match-string 3 xlonStr))) (setq xsign (match-string 4 xlonStr)) (setq xlonNum (+ xdeg (* (+ xmin (* xsec xc)) xc))) (cond ((string-equal (downcase xsign) "e") nil) ((string-equal xsign "") nil) ((string-equal (downcase xsign) "w") (setq xlonNum (* -1 xlonNum))) (t (user-error "Input is malformed. Your longitude ends with a char that's not E or W")))) (progn (user-error "Longitude is malformed"))) (vector xlatNum xlonNum))) (defun xah-coord-to-google-map-link (CoordYX &optional Title) "Return a HTML link to Google Map. Title is the title attribute for the HTML link. CoordYX is a vector [y x] where y is latitude, x is longitude. Each must be a decimal number. Sample output: <a class=\"ggMap\" href=\"http://maps.google.com/maps?q=40.71277777777778%2C-74.00583333333333\">Location</a> URL `http://xahlee.info/emacs/emacs/elisp_make_google-map_link.html' Version: 2015-05-12 2021-05-02 2022-01-27" (let (xtitle xy xx) (setq xtitle (if Title Title "")) (if CoordYX (setq xy (elt CoordYX 0) xx (elt CoordYX 1)) (setq xy "y▮" xx "x▮")) ;; (insert "<a href=\"http://maps.google.com/maps?q=" (number-to-string xy) "%2C" (number-to-string xx) "\" title=\"" xtitle "\">Google Map</a>\n") (format "<a class=\"ggMap\" href=\"http://maps.google.com/maps?q=%s%s%s\">%s</a>\n" (number-to-string xy) "%2C" (number-to-string xx) xtitle ))) (defun xah-google-map-linkify () "Change coordinate under cursor into a Google Map link. If there's a text selection, use that as input. The current line must be one of the following format: 40°42′46″N 74°00′21″W 40.71277777777778 -74.00583333333333 (New York City coordinate.) Note, by convention, earth coordinates are given in this order: ‹latitude› ‹longitude› (latitude is like y axis, longitude is like x axis) Sample result: <a class=\"ggMap\" href=\"http://maps.google.com/maps?q=40.71277777777778%2C-74.00583333333333\">Location</a> URL `http://xahlee.info/emacs/emacs/elisp_make_google-map_link.html' Version: 2016-07-12 2022-01-27 2023-07-23" (interactive) (let (xp1 xp2 xinput xcoord-x xcoord-y xcoord-y-x) (if (use-region-p) (setq xp1 (region-beginning) xp2 (region-end)) (setq xp1 (line-beginning-position) xp2 (line-end-position))) (setq xinput (buffer-substring-no-properties xp1 xp2)) (if (string-match-p "°" xinput) (progn (setq xcoord-y-x (xah-latitude-longitude-decimalize xinput) xcoord-y (aref xcoord-y-x 0) xcoord-x (aref xcoord-y-x 1))) (progn (let ((xxx (split-string xinput " " "OMIT-NULLS"))) (setq xcoord-y (string-to-number (nth 0 xxx)) xcoord-x (string-to-number (nth 1 xxx)) xcoord-y-x (vector xcoord-y xcoord-x))))) (delete-region xp1 xp2) (insert (xah-coord-to-google-map-link xcoord-y-x "Location"))))