Chart a Course

Building Dynamic Maps with ASP.NET, XML, and SVG





Chart a Course

Building Dynamic Maps with ASP.NET, XML, and SVG


By Dan Wahlin


Displaying custom maps in a Web page has always been a challenging task that often requires third-party software or GIS systems. Several options exist for displaying maps, such as Adobe Flash, Google maps, or the Microsoft virtual earth service (to name only a few). In addition to these options, Scalable Vector Graphics (SVG) can also be used in cases where you need complete control over what is drawn and how users interact with it. SVG is an open vector graphics standard approved by the W3C ( that allows dynamic graphics to be created using XML syntax. Changing the source XML data causes the vector graphics image to be dynamically redrawn without posting back to the server. There are a variety of free SVG viewers available, including Adobe s SVG Viewer 3.03 (, which plugs directly into the browser.


In this article I ll discuss how XML data containing world mapping points, airport locations, and flight routes from Flight Simulator 2004 can be dynamically parsed and used to generate SVG graphics using C# and ASP.NET. Because the images are vector-based, users can zoom in and out without affecting the image quality. This article will also show how Web services can be integrated into SVG. Airports shown on the SVG map can be selected to view temperature and wind data.


The SVG image shown in Figure 1 was initially generated using an XSLT stylesheet to transform the source XML data into SVG-compliant XML. However, because of the size of the XML documents involved, XSLT was abandoned in favor of using the XmlReader and XmlWriter classes in .NET 2.0. These two classes provide an extremely efficient reading and writing combination that can parse large amounts of XML data.


Figure 1: Dynamically drawing maps and flight routes using SVG.


Creating SVG Graphics

SVG documents follow the rules of XML, which means all elements must be closed properly, attributes must be quoted, start and end elements must be cased properly, etc. SVG documents have a root element that acts as the parent container for other elements:



 SVG Text


Different shapes can be created and displayed by adding additional tags, such as , , , and , into the SVG document. Lines can be drawn using the element and text can be drawn using the element. Figure 2 shows how to use the and elements together to create a rectangle with text graphic.


Figure 2: SVG documents consist of XML tags that are dynamically read to create graphics. This example shows how to use the and tags to render a simple graphic.


SVG documents can also contain JavaScript and CSS. This allows dynamic functionality to be performed, such as adding additional images, morphing images, or even making external calls to Web services. By embedding CSS within a document, styles can be applied to different parts of the graphic to control the look and feel. Although a complete discussion of SVG syntax is beyond the scope of this article, you ll find several good examples at to get you started.


Once an SVG document is created, it can be displayed using Adobe s SVG Viewer in the browser by using the HTML tag:


  src="XML/Simple.svg" type="image/svg-xml"



The tag allows the overall size of the SVG viewer to be defined, along with the MIME type and SVG document location.


Mapping the World

SVG can be used to draw any type of map, including the one shown in Figure 1. All that s required is a file containing the world s data points and a little .NET coding to parse the file and generate the necessary SVG syntax. To create the world map shown in Figure 1 (only part of the overall world map is shown in the figure) the XmlReader and XmlWriter classes in the System.Xml namespace can be used.


The XmlReader class parses the source data to locate the necessary world mapping points (see Figure 3 for an example) and feeds the data to the XmlWriter to take the data and convert it to conformant SVG syntax. This type of chaining operation provides an extremely efficient input and output mechanism that can parse large XML documents without consuming much memory. XSLT stylesheets could also be used when the source documents are relatively small. The XML data documents included with this article s downloadable code are 30+ meg in size, which is why the XmlReader and XmlWriter classes were chosen (see end of article for download details).


















Figure 3: Points (longitude and latitude) used to map the world s continents and boundaries are used to draw the map shown in Figure 1. This example shows a portion of the data points from a file named world.xml.


Figure 4 shows a portion of the code from a class named SVGCreator (located in the App_Code folder in the downloadable code) used to read the source XML data containing the world s mapping points and output the necessary SVG syntax to map the world. The code starts by creating an XmlReader object that parses XML data in a file named world.xml. Because the parsing process looks for elements named and , it adds these into the XmlReader s name table so that object comparisons can be done, which enhances the overall parsing performance. This technique is useful when you expect to find the same element many times within an XML document.


//Create Reader

XmlReader reader = XmlReader.Create(xmlPath,rs);

string line_segment = reader.NameTable.Add("line_segment");

string point = reader.NameTable.Add("point");

//Create Writer

MemoryStream ms = new MemoryStream();

XmlWriter writer = XmlWriter.Create(ms, ws);

int pointPosition = 0;

while (reader.Read()) {

 //Check for start elements

 if (reader.NodeType == XmlNodeType.Element) {

   if (reader.Name.Equals(line_segment)) {







   if (reader.Name.Equals(point)) {               

     if (pointPosition == 0) {

         writer.WriteString("M ");


         writer.WriteString(" ");


     } else {

         writer.WriteString(" L ");


         writer.WriteString(" ");






   //Check for end elements

   if (reader.NodeType == XmlNodeType.EndElement) {

       if (reader.Name.Equals("line_segment")) {

           pointPosition = 0;








Figure 4: The XmlReader provides a stream API that can parse XML data efficiently without tying up a lot of memory. In this example the XmlReader feeds data it finds to the XmlWriter, which outputs the necessary SVG code to draw a world map.


Once the XmlReader finds a start element the XmlWriter creates an SVG element and adds several attributes to it to style the path. Basically, the element is used to draw one or more lines. When the XmlReader finds a element in the world.xml file shown in Figure 3, it parses the lon and lat attributes and feeds the values to the XmlWriter, which then adds them to the tag s d attribute. The d attribute is used to identify all the different data points for a given path. Once all the points are parsed and the end element is found, the XmlWriter ends the d attribute (by adding the closing quote) and closes the element. Figure 5 shows the result of parsing the world.xml file and outputting the SVG path syntax.


Figure 5: This image of the world is generated by parsing an XML document containing the world s mapping points.


Mapping Airports and Flights

Microsoft s Flight Simulator 2004 program contains flight data used by the simulator to locate airports, as well as planes in the air at any given time (fictitious flights are used in this example). This data was extracted and converted to XML so that it could be overlaid on the world map previously discussed. An example of the data used to determine airport locations is shown in Figure 6. The XmlReader and XmlWriter classes are used to parse the data and plot the airports on the world map within the SVG document.









Figure 6: Airport data is stored within an XML file named airports.xml.


Figure 7 shows a portion of the code used to complete the task of adding airports to the world map. It outputs a tag that represents an airport grouping, then adds a child element. The tag contains an onclick attribute that calls a JavaScript function to retrieve weather data about the airport (more on this later). It also contains onmouseover and onmouseout attributes that point to JavaScript functions that enlarge and minimize the airport circle. The JavaScript functions are embedded directly in the SVG document within a