This article gives a brief introduction to using KML and Google Earth, provides links to more detailed information and contains examples of how to create kml in your application.
Introduction to KML
The first think to know about KML is that it is yet another XML based format. This is very important as it means it is very easy for you and your software to read and manipulate.
The basic structure of a KML file starts with the familiar xml tag and a kml tag with the namespace reference. The main body of the file can contain several different tags. The Document and NetworkLink tags are described here, for more information on the other available tags see the links at the end. The Document tag serves as a container for many other tags and specifies basic information about the content of the file, for example the Name and Description. A Document can contain many tags of various types, the simplest and probably most used is the Placemark as described below.
Adding a Placemark to your KML file will cause Google Earth to display a pin marking the given location on the map. To do this a Placemark tag requires several additional tags to give information about this mark and its location. As with Document the Name and Description tags, as well as many others not mentioned here, provide this functionality. However one of the most important tags to include here is the Point tag, it specifies location information for this Placemark.
<kml xmlns="https://earth.google.com/kml/2.1">
<Document>
<name>a name for this list</name>
<description>a useful description</description>
<Placemark>
<name>A name for this place</name>
<description>Some Description Here</description>
<Point>
<coordinates>5,20,100</coordinates>
</Point>
</Placemark>
</Document>
</kml>
The example above shows a very simple KML file with only one Placemark. As mentioned above the Point tag specifies the location of a Placemark, but it requires the Coordinates tag to actually set the GPS position. Coordinates contains three decimal numbers the represent the Latitude, Longitude and Altitude in that order. Latitude and Longitude need to be in Decimal format rather than Degrees, Minutes and Seconds, an example of how to calculate this is included in the source code or see the references section below.
There are many other tags that can be used within a Placemerk, for example LookAt specifies the position of the camera when the placemark is selected. The source code contains more detailed examples or see the links below for more information.
Linking to Dynamic Content
KML provides a special tag for linking to other files. This can be used to link to static files or with a scripting language like PHP to dynamically generate the KML content. Or even, as in the rest of this article, with a custom web server built into your application. The Example below shows a simple KML file containing a NetworkLink tag.
<kml xmlns="https://earth.google.com/kml/2.1">
<NetworkLink>
<name>This is a Network Link</name>
<Link>
<href>https://stealthware.co.uk/example.kml</href>
</Link>
</NetworkLink>
</kml>
The NetworkLink tag is similar to Document as it is used at the top level in a KML file and contains the basic tags like Name. However it cannot contain tags such as Placemark, instead it just requires one tag, the Link tag. This is used to specify the link to the file itself within a href tag, and aditional parameters such as RefreshInterval that control if and when the link will be reloaded.
Creating you own Web Server in C#
Writing your own web server may sound like a very complicated thing to attempt and in many languages it would be, but not in C#. Using the HttpListerner class is fairly simple and with a few tweaks it can act as a complete web server.
The example code below shows how to create a HttpListener that will respond to a single request to download the file called icon.png. In order to create a fully working server from this you would need to put the code in a loop to serve multiple requests, and modify it to respond to requests for different files or add a general case to serve any file.
// create a new Http Listener
HttpListener listener = new HttpListener();
// add the ip:ports to listen on
listener.Prefixes.Add("https://localhost:81/kml/");
// start the listener
listener.Start();
// get the connection context, blocks until browser connects
HttpListenerContext ctx = listener.GetContext();
// set the response code to 200 OK
ctx.Response.StatusCode = 200;
// use the request object to find out what the browser wants
if (ctx.Request.Url.AbsoluteUri.EndsWith("icon.png"))
{
// set content type on the response
ctx.Response.ContentType = "image/png";
// open the image file and copy all data to the response output stream
CopyStream(File.OpenRead("icon.png"), ctx.Response.OutputStream);
// flush the output stream and close response
ctx.Response.OutputStream.Flush();
ctx.Response.Close();
}
Customising and Serving KML
With the simple web server you can now have your application provide content to a browser or Google Earth. Serving static content is useful, but not when compared to dynamically generated content. There are many ways to edit or create an XML file in C#. You could use XML Serialisation to create a file based on the data contained in a class in your program. You could use the built in libraries for traversing and manipulating an XML document, or as is done in this example you can simply replace keywords in the file with the required content.
// open the kml file and create in/out writers
StreamWriter writer = new StreamWriter(ctx.Response.OutputStream);
StreamReader read = new StreamReader(File.OpenRead("example.kml"));
while (!read.EndOfStream)
{
// read a line from the source file
string data = read.ReadLine();
// replace any special tags with the required value
if (data.Contains("<!NAME!>"))
data = data.Replace("<!NAME!>", name);
if (data.Contains("<!DESC!>"))
data = data.Replace("<!DESC!>", name + "<br />" + description + "<br />Browser: "
+ ctx.Request.UserAgent + "<br />Time: " + DateTime.Now.ToLongTimeString());
if (data.Contains("<!ICON!>"))
data = data.Replace("<!ICON!>", "icon.png");
// and write it out
writer.WriteLine(data);
}
This code opens the example.kml file and reads the contents, replaces any special markers with the correct value and writes it out to the client. As can be seen in the full source code this is used within the web server to process a request for the example.kml file.
This article is intended to provide you with enough information to start creating your own content using KML, and to publish that from within your own programs. However KML can do so much more than is covered here so I highly recommend you look some of the additional sources of information below, or just search for KML. Equally the web serving abilities of .Net are much greater than mentioned here, in fact it is possible to create a full web server, including the ability to process Asp.Net or even PHP content. There should be some extra details of how to continue extending and using these examples on this site in the future, so keep an eye out.
Downloads & References
- Download Source Code, requires Mono or .Net 2+
- KML 2.2 Documentation and Schema are available from the Google Code website
- Decimal Degrees Converter, or use formula DMS to decimal = (D + M/60 + S/3600)
- HttpListener from MSDN
Thanks for reading my Google Earth / KML / HttpListener tutorial, I hope it helps you. If you have any comments or questions please use the Post Comment link below or email me.
Originally written January 2008.