472,782 Members | 1,148 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,782 software developers and data experts.

Elisp Tutorial: Make Google Earth

Elisp Tutorial: Make Google Earth

Xah Lee, 2006-12

This page shows a example of writing a emacs lisp function that creates
a Google Earth file, and creates a link to the file, as well a link to
Google Map. If you don't know elisp, first take a gander at Elisp
Basics.

I often write travelogs on my website. If i traveled to Las Vegas, then
my Las Vegas travelog page will have a link to Google Map location of
Las Vegas. Like this:

<p>
<a
href="http://maps.google.com/maps?z=15&amp;q=36.1027,-115.1730&amp;t=k"
title="Las Vegas">Google Map↗</a>
</p>

The above would display in browser like this:
Google Map↗

It is tedious to type all these characters to create a link, if i need
to do it for many different cities. It would be nice, if all i have to
do is to press a button and have the entire link inserted for me, then
all i have to do is to edit the latitude and longitude part, and the
title part. This is easily done in emacs!

The following elisp function will insert the Google Map link:

(defun insert-google-map-link ()
"Inserts html link markup for Google Map location."
(interactive)
(insert "<p>
<a href=\"http://maps.google.com/maps?z=11&q=ttt&t=k\" title=\"ttt\">
Google Map↗</a>
</p>")
(re-search-backward "ttt" nil t)
)

Now, on my web site i also want to have a Google Earth file of the
location. For example, in the HTML file i would have the following
code:

<p>
<img src="http://xahlee.org/Icons_dir/google_earth.png" alt="">
<a href="las_vegas.kml" title="Las Vegas">Google Earth file</a>
</p>

The above would display in browser like this:
Google Earth file

Then, i create the file las_vegas.kml, having this content:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Placemark>
<name>Las Vegas</name>
<description>Good for a visit!</description>
<Point>
<coordinates>-115.1730,36.1027,1000</coordinates>
</Point>
</Placemark>
</kml>

It easy to write a elisp function “insert-google-earth-link” that
will insert the link for me.

It is also easy to write a function “insert-kml-template” that
inserts the Google Earth KML template.

So, now the procedure to create a Google Map and Google Earth of Las
Vegas is:

1. Use “insert-google-map-link”, then go edit the coordinates
and title.
2. Use “insert-google-earth-link”, then go edit the coordinates,
title, and file name.
3. Create a file.
4. Use “insert-kml-template” to insert the XML template.
5. Edit the coordinate and the title in the template.
6. Save the file.

As you can see, this is becoming tedious. If you are writing a travelog
on your website and needs to place many Google Maps and Google Earth
for various locations, going through the above process is no fun.

As we can see, coordinates and names are manually entered repeatedly.
It would be nice, if we can type out the city's name, the coordinates,
and file name, and press a button, and have emacs create the Google Map
link, Google Earth link, as well as the Google Earth KML file. For
example, for the city Las Vegas, will have this block of text:

Las Vegas
36.1027,-115.1730
Las_Vegas.kml

Then, move the cursor somewhere in that block. Execute the function
google-earth, and emacs will insert the Google Map link, Google Earth
link, and create the Google Earth file as well.

We proceed to write this function.

First, we write a documentation for the function so that we know
precisely what we want.

(defun google-earth ()
"Create a Google Earth file and link.\n
The cursor must be on 3 lines separated by empty lines.
The lines are:

Name
Coordinate
file path (relative to the current file)

For Example:

Las Vegas
36.1027,-115.1730
Las_Vegas.kml

google-earth will create the KML file and with proper html link
to it in the current file."
(interactive)
)

The first step in implementing this function, is to have a code that
grab the 3 lines and store them as values in variables.

After coding this for a while, i realized that its probably better to
write a stand-along function to do this, since turning lines into
values stored in variables can be useful for other programs. Here's our
code:

(defun grab-lines (n)
"Delete the next n lines and return a list
where each element is a line."
(interactive)
(move-beginning-of-line 1)
(let (t1 t2 cl (lns '()))
(dotimes (x n)
(progn
(setq t1 (point))
(move-end-of-line nil)
(setq t2 (point))
(setq cl (buffer-substring-no-properties t1 t2))
(delete-region t1 t2)
(delete-char 1)
(push cl lns)
)
)
(setq lns (reverse lns))
; (prin1 lns (current-buffer)) ; print result for testing purposes
))

In the above code, variables t1 and t2 are temp vars used to store
positions for the beginning of line and ending of line. cl is a temp
variable that stores the current line. “lns” is a temp var that
stores the final list. The whole code is a simple loop and is easy to
understand.

For example, you can test this code on the following lines

(grab-lines 4)
line1
line2
line3

Now, we write the insert-google-earth-link.

(defun insert-google-earth-link
(&optional title file-path)
"Inserts HTML markup for Google Earth."
(interactive)
(if title
(progn (setq title2 title) (setq file-path2 file-path))
(progn (setq title2 "ttt") (setq file-path2 "ttt"))
)
(insert "<div style=\"display:table;background-color:cornsilk\">
<img src=\"../../Icons_dir/google_earth.png\" alt=\"\">
<a href=\"" file-path2 "\" title=\"" title2 "\">Google Earth file</a>
</div>")
)

Note the optional argument “title” and “file-path”. So that, if
called by a program and these are given, then a complete link with
title and file path will be inserted. If called interactively, dummy
text “ttt” is used for places the user need to fill in.

(We could write it so that it prompts user for input, but i find such
interactive program less convenient to use.)

Now, we write a function to insert the Google Earth KML template. Like
before, we use several optional parameters.

(defun insert-kml (&optional title latti longi)
"Inserts a dummy Google Earth KML markup."
(interactive)
(let (title2 latti2 longi2)
(if title ; if optional args not given, set them to dummy text
(progn
(setq title2 title)
(setq latti2 latti)
(setq longi2 longi)
)
(progn
(setq title2 "ttt")
(setq latti2 "ttt")
(setq longi2 "ttt")
)
)
(insert "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<kml xmlns=\"http://earth.google.com/kml/2.1\">
<Placemark>
<name>" title2 "</name>
<description>Good for a visit.</description>
<Point>
<coordinates>" longi2 "," latti2 "</coordinates>
</Point>
</Placemark>
</kml>")
)
)

Finally, we have all our auxiliary components we need, we can go head
and define our google-earth.

(defun google-earth ()
"Create a Google Earth file and link.\n
The cursor must be on 3 lines separated by empty lines.
The lines are:

Name
Coordinate
file path (relative to the current file)

For Example:

Altamount Pass Wind Farm
37.7497,-121.6832
livermore/Altamount_Pass_Wind_Farm.kml

google-earth will create the kml file and with proper html link
to it in the current file."
(interactive)
(search-backward "\n\n")
(search-forward "\n\n")
(let (title latlon file-path sl vl latti longi)

(setq sl '(title latlon file-path))
(setq vl (grab-lines 3))
(while sl (set (pop sl) (pop vl) ) )

(setq sl '(latti longi))
(setq vl (split-string latlon ","))
(while sl (set (pop sl) (pop vl) ) )

(insert-google-map-link title latlon)
(insert-google-earth-link title file-path)
(find-file file-path)
(insert-kml title latti longi)
(html-mode)
(save-buffer)
)
)

In this code, first we call “(search-backward "\n\n") (search-forward
"\n\n")”. What these do is to move the cursor to the beginning of a
text block, which is right after two blank lines.

Then, we define our temp vars. Here's what they mean:

“title” is the title of the Google Map/Earth. e.g. Las Vegas.

“latlon” is the lattitude and longitude string, string. e.g.
37.7497,-121.6832.

“file-path” is the file path to the Google Earth KML file.

“sl” and “vl” are temp vars. “sl” stands for symbols list,
and “vl” stands for value list. They are used to assign a list of
values to variables.

“latti” and “longi” and lattitudes and longitudes.

Now, in this block of code:

(setq sl '(title latlon file-path))
(setq vl (grab-lines 3))
(while sl (set (pop sl) (pop vl) ) )

We set sl to be a list of variable symbols. Then, we use grab-lines to
get a list of values. The while function assigns the variables.

Then, we do the same by splitting the latitude and longitude string
into separate variables and store them in latti and longi.

The rest of the code is trivial. We call insert-google-map-link to
insert the Google Map link with proper fillers. We call
insert-google-earth-link too. These will insert the Google Map link and
the Google Earth link. We then call find-file to generate a new file,
insert-kml to insert the KML template with proper fillers, then we make
the buffer html-mode and save it.

If we want, we can close the buffer. But we want to leave it open so
that the user might want to add descriptions for the KML file.

So now, we have a elisp function, that we can assign to a keystroke.
Upon a press of button, it saves us a few hundreds of tedious
error-prone keystrokes and file managing process.

Emacs is Beautiful.

----
This post is archived at
http://xahlee.org/emacs/google-earth.html

Xah
xa*@xahlee.org
http://xahlee.org/

Dec 14 '06 #1
1 7197
This is off-topic in c.i.w.a.h.
Dec 14 '06 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

49
IDE
by: Thomas Lindgaard | last post by:
Hello I am probably going to start a war now... but so be it :) I just want to hear what all you guys who eat pythons for breakfast use for python coding. Currently I use Kate, but I would...
11
by: Magnus Lycka | last post by:
While the official Python Tutorial has served its purpose well, keeping it up to date is hardly anyones top priority, and there are others who passionately create really good Python tutorials on...
2
by: Bell, Kevin | last post by:
Sorry if this is an off topic shot in the dark, but... Does anyone know a contact for anyone that works for Google Earth? I wanted to shoot 'em an email about a possible enhancement, but they're...
3
by: clintonG | last post by:
How f*cked up and behind the curve do you have to be to use Google Earth on your own broadcasting network? <%= Clinton Gallagher NET csgallagher AT metromilwaukee.com URL...
12
by: JDW | last post by:
Maybe a stupid plan, but I want by double clicking on a field in a Form, export an address to the search box of Google Earth and fly to this address... Who can help me with the event procedure...
1
by: gjsonke | last post by:
I need to get the dimensions of the Google Earth render window and I know squat about Window Handles. I've been sniffing around and I'm geting the idea that you can do lots of fun things with...
6
by: =?utf-8?B?4piG4piG4piG4piG4piGIFPDvCBLZWl0aCBDaGFr | last post by:
Ok. Let's say Im writing a game and I have a class table for my character's stats. (Don't worry about classes yet ,you'll run into them soon enough). Say this table includes all his stats, age,...
1
by: John Walsh | last post by:
Hi, I'd like to write a python script to control Google Earth, and I've read that Google Earth provides a COM api, and that Python has a COM module 'pythoncom'. Anyone know where to get...
2
by: xahlee | last post by:
In this week i wrote a emacs program and tutorial that does archiving a website for offline reading. (See http://xahlee.org/emacs/make_download_copy.html ) In the process, i ran into a problem...
0
by: erikbower65 | last post by:
Using CodiumAI's pr-agent is simple and powerful. Follow these steps: 1. Install CodiumAI CLI: Ensure Node.js is installed, then run 'npm install -g codiumai' in the terminal. 2. Connect to...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
How does React native implement an English player?
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.