Excel To KML
Excel To KML
Excel To KML
Article Index
Multiple Placemarks
Polygon function
Generating markers
Page 1 of 4
A very standard requirement is to convert geographical data stored in a spreadsheet into a map.
The simplest way to achieve this is to convert the data into a KML file and then load this into Google
Earth or a similar mapping/GIS application.
Converting raw co-ordinates into KML isn't a difficult task but it is time-consuming and its repetitive
nature makes it ideal for implementation as a macro. In this article we create a VBA macro that will
work with almost any version of Excel. (You can download the spreadsheet and macro from the
CodeBin - see the end of the article for details.)
If you want to know more about KML before moving on see: KML in Google Maps and Earth and if
you want to know more about using Google Earth try: Getting started with Google Earth. If you
want to know more about VBA macros in general then see: Automating Excel.
The data
The spreadsheet is assumed to contain two columns of latitude and longitude data. In addition the
example data, a series of earthquakes (well microtremors to be less alarmist) that occurred in July
2010 in the Alboran Sea, South-East Spain. There is a third column for earthquake magnitude.
(The spreadsheet is available for download.)
The macro takes each of the co-ordinates. creates a KML placemark at the location and a custom
symbol - a triangle in this case. The size of the symbol is set by the magnitude of the earthquake
but you can easily customise the macro to provide fixed size symbols or link the size to some other
data.
The raw data in this case came from the database maintained by the IGN (Instituto Geográfico
Nacional) and column A is the catalog number of the events.
The data
To get started we need to create a new Excel macro. exactly how you do this varies a lot between
different versions of Excel. Macros are also usually turned off for security reasons.
In most versions of Excel the command to get the Visual Basic Editor started is Tools, Macros,
Visual Basic Editor.
To get to the Visual Basic Editor in Excel 2010 is more complicated - see Getting started with Excel
VBA.
However once you get the Visual Basic Editor started it looks the same and is used in the same
way in all versions of Excel.
The easiest way to create a user interface is to use a UserForm. A UserForm can contains buttons,
textboxes and you can use one to create a fairly sophisticated user interface. To add a UserForm to
the project use the command Insert,UserForm.
Once you have the UserForm you can use the Toolbox to add a Button, three small textboxes and
one large textbox. You can also place labels and other "decoration" to make the form look more
professional and easy to use.
The UserForm
The idea of the user interface is that when the program is started the user can set the column letters
that the Latitude, Longitude and Magnitude are stored in. When this is done the Generated KML
button is clicked the program generates the KML and it is stored in the large textbox on the right.
The user can then select it and use copy and paste to transfer it to a mapping program to a text
editor to subsequently save as a KML file. It would be quite easy to add a button or a menu option
to save the KML in a file - but copy and paste is easy and versatile.
The program
The entire program is contained in the button's click event handler - nothing happens until the user
clicks the Generate KML button. The click handler can be generated automatically by double
clicking on the button in the UserForm editor.
The first task is to retrieve the column letters stored in each of the textboxes to discover which
columns the data is stored in. We also need to convert the column letters into column numbers to
make working with the data stored in the cells easier. The simplest way to convert a character to a
numeric value is to use the Asc functon which returns the ASCII code for the letter. To make sure
that A is converted to 1 we also have to subtract the ASCII code for A.This gives:
We can now start generating the KML as it always starts in the same way. To do this we make use
of a custom subroutine outputLine which adds the text to the textbox with a carriage return at the
end - that is it outputs a line:
The vbCr is a standard constant that contains the character code for carriage return.
Using this subroutine we can output the first three lines of KML:
Page 2 of 4
Placemarks galore
We are now ready to generate the KML for a Placemark. First it is assumed that the current sheet
i.e. the one open when the VBA program was started, is the one containing the data. If this is not
the case you need to extend the program to allow the user to specify the data sheet. It is also
assumed that the data starts in row 2 with column headings in row 1.
Again, if this is not the case you need to give the user some way to modify the default.
Now we get to the part of the code that does the real work. We use a Do loop to extract the data
from each row, process it and then move on to the next row. The loop ends when the Longitude
column contains a blank The test could be on any column - its just a matter of detecting when there
is no more data to process.
The work of generating the KML for the Placemark is done by the MakePlaceMark subroutine which
we have yet to write. Notice the way that the Cells function is used to get the data sorted in the cell
at a specified row and column. That is:
Cells(row,col)
retrieves the value in the cell at the intersection of row and col where column A is col=1 column B is
col=2 and so on.
After generating all of the KML for one Placemark for each row of data all that remains is to write
the customary closing KML tags:
Call outputLine("</Document>")
Call outputLine("</kml>")
End Sub
lat and lon are parameters which specify the position of the Placemark and in this case mag is a
parameter that controls the size of the symbol drawn. Notice that you can't use "long" as the name
of the longitude parameter because long is a reserved word i.e. it means something special to VBA.
Now we simply write the standard KML for a Placemark:
Call outputLine("<Placemark>")
Call outputLine("<Point> <coordinates>")
Call outputLine(lon & "," & lat)
Call outputLine("</coordinates> </Point>")
Call outputLine("</Placemark>")
End Sub
The position parameters are output to set the Placemark's position. If you use this version of the
MakePlaceMark subroutine then a standard Placemark icon is used. This might be what you want in
which case the program is finished.
The complete MakePlaceMark sutroutine is:
Call outputLine("<Placemark>")
Call outputLine("<Point> <coordinates>")
Call outputLine(lon & "," & lat)
Call outputLine("</coordinates> </Point>")
Call outputLine("</Placemark>")
End Sub
Here, however, we want to scale the symbol used for the placemark and to do this we will draw the
outline of a polygon. To do this we first need another subroutine to generate the points that define it.
Page 3 of 4
To generate the points of an n-sided polygon we simply need to evaluate the formulas for t
equal to mulitples of 2Pi/n. For example for a triangle the angle is 2Pi/3:
The only complication is that a XML polygon has two extra requirements. The first is that
you have to repeat the first point in its specification as the last point - i.e. to close the figure.
The second is that the points have to be listed in a clockwise order.
With these two practicalities in mind we can write the polygon function. First we need to
setup some basic variables and constants:
Private Function Polygon(
x As Double,
y As Double,
r As Double,
n As Integer) As String
Dim Angle As Double
Dim Coords As String
Coords = ""
Angle = 2 * 3.141592654 / n
The number of points to be generated is given by n and the results are to be returned in the
Coords string as a set in the format x,y,z with one point to a line.
The first and last points are best generated separately from the rest. The first point is:
px1 = r * Sin(Angle * i) + x
py1 = r * Cos(Angle * i) + y
Coords = Coords & px1 & "," & py1 & ",0 "
The final line converts the numeric values px1 and py1 into a comma separated string.
Next we use a for loop to generate the rest of the points in the polygon:
For i = 1 To n - 1
px = r * Sin(Angle * i) + x
py = r * Cos(Angle * i) + y
Coords = Coords & px & "," & py & ",0 "
Next i
Finally we repeat the first point as the last point and return the result:
Coords = Coords & px1 & "," & py1 & ",0"
Polygon = Coords
End Function
px1 = r * Sin(Angle * i) + x
py1 = r * Cos(Angle * i) + y
Coords = Coords & px1 & "," & py1 & ",0 "
For i = 1 To n - 1
px = r * Sin(Angle * i) + x
py = r * Cos(Angle * i) + y
Coords = Coords & px & "," & py & ",0 "
Next i
Coords = Coords & px1 & "," & py1 & ",0"
Polygon = Coords
End Function
Page 4 of 4
Call outputLine("<Style><PolyStyle>
<color>ff0000ff</color>
<fill>1</fill>
<outline>1</outline>
</PolyStyle></Style>")
Call outputLine("<MultiGeometry>
<Polygon> <outerBoundaryIs>
<LinearRing><coordinates>")
Call outputLine("</coordinates>
</LinearRing></outerBoundaryIs>
</Polygon></MultiGeometry>")
Call outputLine("</Placemark>")
End Sub
This is all that is required and if the program is run on the data a KML file with one symbol per line
of data is generated in the large textbox.