Give Your Applications Mapping Capabilities, Part 2

oogle Earth (GE) provides a powerful 3D environment that you can use to provision your application with rich interactive 3D features. You can render points, lines or areas located at any point on earth—using either local, static, or positional data downloaded from the web. Your web applications publish the data to create useful maps or other information. You can also write files that cause GE to download data from your web site repeatedly, letting you show real-time positions.

Understanding Google Earth KML
GE works with XML in a form called the Keynote Markup Language (KML). You write KML documents to render data in GE. Because KML is a simple text-based format, you can use any programming language or text editor tool to create the KML files. KML lets you manage and render geo-information without having to know the details of how Google renders maps and data points.

Author’s Note: The downloadable code for this article is in VB.NET, but all it does is create KML files, so you should be able to translate it to C# or another language fairly easily.

Here’s the same simple KML file from Part 1 of this two-part article with a little more detail about its construction:

              Arena di Verona            Arena di Verona                10.99394514599905         45.44023503220072         200         759.5637314343327         58.7902038199754         0.8203667851755632         relativeToGround                       10.99451099760466,45.43891075160266,0                  

The root element is , which contains a element that holds a name, and the “camera” or view position from which to look at a point of interest on earth. Points (consisting of latitude, longitude, and altitude values) are the most basic type of geographical information. The element in the KML contains the values for the point the “camera” will look at. GE works with the latitude, longitude, and altitude of a point as three real numbers, written as a plain comma-delimited string. Note that order is significant; points are always specified in latitude, longitude, altitude sequence. The number format (using a period to separate the integer portion of a number from the fractional portion) and the comma separator are culture invariant.

In sum, the KML example actually defines two points. The “camera” point, which has separate nodes for latitude, longitude, altitude, and other data, is an exception to standard GE coordinate rules. The geographic point, with its comma-separated values, specifies the point data in a typical manner.

Author’s Note: KML defines all data as XML nodes, but points or lines require you to define coordinates as a plain string with all data comma separated. This “non-xml” approach to coordinate management is to improve performance and reduce data volumes. Files with many points (for example those that define a line) would otherwise require huge KML files.

Please note every object on earth in GE is defined as a “Placemark.” Therefore, to show a point (as in the previous example) you need to define a “point-placemark;” to show a line or a polygon you define a “linestring-placemark,” or a “polygon-placemark,” respectively. But remember that the base node is always .

Working with Lines
To show a line, you simply use a collection of points contained within a tag. The points define a connected set of line segments. GE will connect every pair of points with a direct line segment, so anything except a straight line will always require a sequence of linear segments. There’s no concept of curves—in other words, GE doesn’t provide a way to draw a “real curved line,” but you can approximate curved lines with close-set points. The more points you use, the better the approximation.

Here’s an example of the KML for a line (some points were removed for space reasons; you can find the complete sample in the downloadable code):

        A line            0       1       clampToGround                9.576918333333341,45.629865,213.8          9.57692833333333,45.6299466666667,215          9.576956666666669,45.63006,214          9.576985000000002,45.63015833333331,213          9.577021666666671,45.63027500000001,212          9.57706333333333,45.63040333333331,211          9.577108333333342,45.6305383333333,211          9.577159999999999,45.6306766666667,210          9.577206666666671,45.63081833333331,210          9.577235,45.63089,209          9.57726166666667,45.63096333333331,209          9.577286666666669,45.63103833333331,209          9.577318333333331,45.631115,208          9.577353333333329,45.6311933333333,208          ...               

Figure 1 shows the output.

Figure 1. KML Line: If you load the KML line example in GE, you’ll see this line, which is drawn using the complete list of points.

The simplest part—the coordinates—are defined in the node as a string with a sequence of comma-separated longitude, latitude, and altitude values. The tag specifies how you want GE to interpret altitude values. Absolute means that you will provide exact altitude values, but other options are clampToGround, to make GE ignore altitude values, or relativeToGround, meaning GE should interpret the altitude values you provide as “meters over the ground in that point.” Typically, you’ll use the absolute whenever your point data includes accurate altitude values and clampToGround if you didn’t collect or don’t have accurate altitude values (for example, if you’re working from a database containing only 2D data).

The and nodes are Boolean values that determine whether your line is connected to the ground (extrude), or whether the line will follow the terrain and cannot be underground (tessellate). For most applications you will always set extrude to 0 and tessellate to 1.

Working with Polygons
To define a solid polygon—for example, an area in GE—you use the tag inside the standard tag. A polygon is a closed figure with a boundary that defines an area. By default, polygons are filled areas, but you can nest them to create unfilled inner areas; in other words, you can nest two polygons. In such cases the enclosing polygon’s area consists of the area not enclosed by inner boundaries.

For example, here’s the KML for a polygon with inner and outer boundaries:

        A polygon            1       relativeToGround                                        -77.05788457660967,38.87253259892824,100              -77.05465973756702,38.87291016281703,100              -77.05315536854791,38.87053267794386,100              -77.05552622493516,38.868757801256,100              -77.05844056290393,38.86996206506943,100              -77.05788457660967,38.87253259892824,100                                                                   -77.05668055019126,38.87154239798456,100              -77.05542625960818,38.87167890344077,100              -77.05485125901024,38.87076535397792,100              -77.05577677433152,38.87008686581446,100              -77.05691162017543,38.87054446963351,100              -77.05668055019126,38.87154239798456,100           
Figure 2. Polygons in GE: The Pentagon is a good example of nested polygons with inner and outer boundaries.

The and nodes define the external and the internal boundary of this polygon. Both polygons boundaries are defined with child nodes; containing the sequence of points that define the boundary. The coordinate syntax is the same used with points and lines tags. Note that the tag is mandatory, but is optional; if you don’t provide it, GE will design a filled area. As an example, look at the Pentagon overlay in Figure 2, which is a polygon with a nested inner polygon.

KML Structure
KML is a standard XML file, where the schema defines GE objects. You’ve seen several important node types that define placemarks, points, lines, and polygons. Collectively, you can call them “GeoObject” nodes. The KML schema defines some other nodes that help organize and display the GeoObject nodes, such as the node and style-related nodes.

At the root of a KML document, you can define a folder, a GeoObject, or a style object. nodes can contain other nodes, GeoObject nodes, and so on, letting you create a hierarchy.

When you create a KML file, you’ll use folders to arrange GeoObjects. You define folders with a set of child nodes that control how GE will render the folder. Here’s an example:

        Main Folder     1            A folder is a container that can hold multiple other objects                 Folder object 1 (Point)                -122.377588,37.830266,0                        Folder object 2 (Polygon)                                                       -122.377830,37.830445,0               -122.377576,37.830631,0               -122.377840,37.830642,0               -122.377830,37.830445,0                                                         Folder object 3 (Line)                1                    -122.378009,37.830128,0 -122.377885,37.830379,0                        

The simple node above has a name and a description that will be visible to the user in the GE object tree—the sidebar panel that appears on the left side of the GE interface. The node defines the default status of the folder when the KML is loaded; folders can initially appear either open (1) or closed (0). This folder contains several placemarks, but remember, folders can contain other folders as well. You can create any folder hierarchy you need. For example:

        Main Folder             This is a main folder and can contain points,        lines, polygons or other folders                 SubFolder       0       This is a subfolder that is closed by default,         and can contain points, lines, polygons or other         folders                  A point                      -122.377588,37.830266,0                          

Creating KML Files Programmatically
The simplest way to create an XML file with .NET is to use the XmlWriter object. XmlWriter provides methods that help you write well-formed XML documents easily and efficiently. You can output the created XML to a standard file or stream it on the web.

This next example uses a MemoryStream to write XML to memory (see Listing 1). ASP.NET can direct the XML stream XML to an OutputStream. This sample will create a valid KML file that will contain a point placemark. Coordinates are received as input parameters, and XML is returned as string output parameter.

Most of the code in Listing 1 is quite easy to understand, but here are the important points:

The NumberFormatInfo object controls how the ToString() function formats the latitude, longitude, and altitude values. The code ensures that the decimal separator is a period and that the NumberGroupSeparator is a null string, conforming to KML specifications.

After creating the KML, the code rewinds the MemoryStream (memStream.Seek(0, IO.SeekOrigin.Begin), sets an encoding, and then reads the entire stream as the return value—in other words, the function returns a text string containing the created KML document. You could also return the MemoryStream itself or work with an ASP.NET OutputStream to write the KML directly to a browser.

The attached code contains a simple working program that uses the GetKML function in Listing 1 to create a KML document and display that to users. By extending the methods shown in this sample you can create any KML file you need, adding code to insert Folders, Lines, or other valid node types to the stream.

As you’ve seen, it’s easy to create KML files programmatically, but you can improve on that model by creating a class that “maps” a KML file in an object-oriented manner. That way you can work with typed data and with a reusable resource library without worrying about the details of the KML format and without having to rewrite similar code to produce other KML documents. A KML wrapper class would expose methods and properties such as:

   Public Function ToKml() as String   Public Property Title() As String   Public Property Folders() As FoldersCollection

You could define other classes that map the KML basic structures such as Point, Line, Shape, and Coordinate classes as well as Style and Folder classes.

GE and KML Files
GE can open KML files from your hard disk or download them from the web, so you can publish your data on your web site or from your web application. To publish simple static data that doesn’t require user interaction, all you need to do is create the KML files and make them available. People can download the files and load them into GE through the File ? Open menu. If you output a content-type metatag that specifies “application/,” the user’s browser will open it with GE, without any user interaction.

Author’s Note: from a web browser’s point of view, GE is a standard external plug-in, meaning that if GE hasn’t been installed on that machine, the browser will not show any content for downloaded KML documents, because it won’t know which helper application handles the KML format.

Displaying Real-Time Data in GE
When your application shows only static views (non-moving geographic data), you can pre-create the KML files or generate them at runtime (for example from an ASPX page), sending them to a user’s browser (and thus to GE) only once; however, when you need to display non-static data (for example, the real-time position of a car), you can cause GE to reload a file repeatedly after rendering the view the first time. To do that, use the element, which as the name implies, creates a link from GE to your web server. There are several options that I encourage you to explore, but the simplest is to tell GE to reload the KML file at some specified interval. Because the data in that file can change between loads, reloading the file periodically causes GE to update the view, letting you show “moving” data without any additional user interaction.

Here’s a simple example:

                  Network Links       Network link                Space Shuttle Current Position         Here's where the Space Shuttle is now                  0         1                     onInterval           10                        

As you can see, is basically just a pointer to a remote KML file with some ancillary information (name, description, refresh interval, etc.). The example above causes GE to load the linked KML file from the location specified in the tag, and subsequently refresh it according to the duration—every 10 seconds in this example.

The element causes GE to fly to the view position specified by the root element in the linked file. This is very important because it lets you download the file, show its content, and move the user perspective (the “camera”) to that position. If you set to 0 (false), and GE isn’t already showing a view that includes the location of the downloaded data, users will not see the downloaded data until they manually move the view so the location becomes visible. The element controls whether GE should apply the view settings in the downloaded KML each time it refreshes the file, or whether it should maintain user control, letting users change the view however they like. In the latter case, GE maintains the user-controlled view when it reloads the KML file.

The element sets the refresh mode policy. Besides the onInterval mode used here, other available modes are onChange (when link parameters change), and onExpire (refresh when an expiration time is reached, which can be the HTTP max-age header).

Figure 3. Flight Tracking: The lines track the flight patterns of aircraft near New York City’s JFK Airport.

Using this technique you can collect real-time positional data, write it to a KML file, and publish it on the web. Typically, you create a main KML file where the points to a secondary KML file that you’ll create dynamically with the updated real-time positional data.

This technique lets you develop near-real-time applications. For example provides the ability to track flights online (see Figure 3).

Google Earth is a powerful and customizable 3D earth-rendering engine. Using its XML format, KML, you can create exciting applications that show maps and other geographical views, you can make those available on the web, and you can update them to display real-time data.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin


Recent Articles: