Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Web Development

SVG & Smart Maps


Mar03: SVG & Smart Maps

Keith works for KGIS (http://www.kgis.org/), which provides mapping services to Knoxville and Knox County, in Tennessee. Keith can be reached at [email protected].


The emergence of Scalable Vector Graphics (SVG) has given rise to new possibilities in the area of geospatial presentation. SVG, which is a dialect of XML and a W3C standard (see http://www.w3.org/TR/SVG/), is simply a plain-text format that can make graphics look "flashy," à la Macromedia's Flash graphics file format (http://www.macromedia.com/software/flash/).

One SVG feature is that you can code intelligence into graphical applications. In this article, I'll examine how SVG can be used to create "smart maps" that, unlike static JPEGs, can be dynamically updated, animated, and even searched.

Imagine, for instance, that you're planning a trip from Los Angeles to San Francisco. Wouldn't it be convenient to know where the road delays were due to construction, accidents, inclement weather, and the like? Or perhaps you need to provide a process-control interface and would like operators to see tanks being filled in real time, or maybe you need to send a bar chart of monthly sales figures to offices worldwide. SVG can be applied to these situations and many more.

To get started with SVG, you need a web browser with an SVG plug-in; several are available for free. I use the plug-in from Adobe (http://www.adobe.com/svg/viewer/install/main.html) with Internet Explorer. To actually create SVG maps/images, all you then need is an ASCII text editor (Notepad is fine). If you want to dynamically update SVG maps/images, you'll need something like a Java servlet, and if you plan on doing lots of really cool stuff with SVG, you should get an XML parser.

SVG Basics

SVG lets you draw graphic primitives—circles, rectangles, lines, polygons, and paths. Furthermore, SVG exposes a DOM interface, and the properties of these primitives can be changed on-the-fly with JavaScript, including animation. Figure 1 and Listing One demonstrate simple SVG animation where a small black rectangle travels along the solid red line (an SVG path object). This example could also have been built using JavaScript and the DOM, which is the approach I take with the SmartMap program (available electronically; see "Resource Center," page 5). While this is a straightforward example, it illustrates some useful SVG features. For example, the Interstate 40 highway symbol is a .GIF file using the xlink tag.

Another important SVG basic concerns the "z order" of objects shown in the map. Objects are drawn in the order in which they appear in the source code. For example, if I had first drawn the (red) interstate highway in Figure 2 and then the (blue) river, it would appear that the highway is a tunnel at the intersection with the river, instead of a bridge.

The SmartMap Program

For this article, I've created the SVG smart map in Figure 2. The code consists of two parts—an HTML document (SmartMap.htm), and the SVG source code (SmartMap.svg). (Both are available electronically.) I'll limit my discussion to the SVG code, since the HTML is self explanatory.

There are a couple of important features regarding this map. First, the map is embedded in the HTML document that sports an edit box and check box. The edit box is used as a feedback device for objects in the map. For example, you can click on the river, city park, and the gas station (the exact location of this object is in Figure 3). Doing so sends information about that object to this text box. The check box is used to show/hide all rivers and streams. The map also demonstrates "bubble help"—moving your mouse over the airport object to view pop-up information about the airport.

Another feature of the program is that some of the buildings (the small squares along the streets) change color. When the building is green, the store is open; when red, the store is closed. The gas station also sends text automatically to the HTML document when it is open or closed. This illustrates how you can push information to users whether they want it or not. The opening/closing of stores is tied to the computer's clock, which is also displayed inside the SVG map in the upper-left corner. This demonstrates dynamic updating. Otherwise, the map looks like any other map—it has a scale to provide a distance reference and a compass pointing north for orientation.

The SVG code begins with the opening tags. I've included both style and <defs> sections. A <defs> section is used to define objects that can be reused in several places. This helps keep the SVG file size to a minimum. The only thing that might be of interest to you here is the <pattern> tag, which is used for drawing the crossties in the railroad tracks; you may have to zoom in to see them more clearly. To zoom an SVG image, right-click the mouse and pick an option from the pop-up menu; otherwise, I just draw the objects in their proper order.

The interesting stuff is in the JavaScript code. You can embed JavaScript in SVG files by enclosing it inside these tags:

<script>

<![CDATA[

// your Javascript here

]]>

</script>

When the document loads, the init() function is called, which also creates the buildings used in the map. The clock is also initialized in this function, and a call is made to UpdateClock(). In addition to updating the clock on the screen, this function opens/closes some of the buildings ("stores") at regular intervals. The remaining functions are purely for housekeeping chores; like showing/hiding the bubble help message when the mouse is over the airport and responding to mouse clicks on the city park, river, and gas station.

The cars moving along the roads are created as SVG objects, not JavaScript objects. While I could have created them exactly as I did the buildings, seeing a variety of methods gives you a broader field of vision regarding SVG. The SVG file concludes by drawing the compass (which is defined as a symbol) and a few other objects. The code is well commented.

Furthermore, you can add an event listener when creating SVG objects via JavaScript. This lets you create objects (circles, rectangles, lines, or whatever), and trap mouse events for those objects. For example:

newRect.addEventListener("click", OnObjectClick, false);

where newRect is an SVG object created elsewhere in your SVG document (or JavaScript), and OnObjectClick is the name of the function to call when the object is clicked. This could come in handy if you create new objects dynamically and need to interact with them. The OnObjectClick(event) function could then get the ID of the object, and react accordingly. For instance, in Listing Two you could test the value of objId and, if it's something you're interested in, take appropriate action. The SVG DOM is powerful, and you should become familiar with it if you want to do serious SVG programming.

The last SmartMap feature concerns turning off/on layers (sometimes called "levels"). Maps can become crowded, and often times you're only interested in looking at certain things—hydrological features, vegetation, roads, and so on. SmartMap has a check box on the HTML document that lets you toggle water on/off. Since my map has only one river, this is toggled on/off in response to the check box. The river is part of a group in the SVG by use of the <g> tag. Inside this group tag you'll also find the text label for the river. This lets you toggle both the graphic and text label. In more complex applications, you would probably make use of a technique called "feature tagging"—a way of associating features with a class (rivers, roads, and so on) as previously described. For example, all rivers and streams might have a tag of 1, all primary roads a tag of 2, all secondary roads a tag of 3, and so on. You could then loop through all your SVG objects and show/hide the appropriate features.

Real-Time Updating

The easiest way to update the map in real time is to use a Java servlet. Although writing and presenting a servlet is beyond the scope of this article, I do want to explain how you might integrate this into the map in Figure 2. Suppose the temperature in the fictitious town drops to 30 degrees Fahrenheit and it starts to rain. Ideally, traffic should slow down and the speed of the cars needs to reflect this. The solution is to regularly call a function that checks for any new updates. This JavaScript calls a function every five seconds:

setTimeout('CheckForUpdate()',5000);

Inside CheckForUpdate() you would call a Java servlet that lives on your server. This servlet's only job is to send you either an XML file containing new update instructions or a text stream containing new processing information. This servlet could take HTML form data as input; for example, a human would have to tell the servlet what needs to be updated (road construction at such-and-such location). In this way, the loop gets closed from start to finish. Some data, such as weather conditions, could be "pulled" from other sites, obviating the need for human intervention. Your map could then be updated client-side by using whatever algorithms you've plugged into the map for this purpose.

Another option for dynamic updating might be to leave your SVG map on your server, and have your servlet do the updating there. This is a trade-off: If you lose your connection, you have neither a map nor live updates. With the map on the client, as in my example, you would lose updates, but at least you'd have the map.

Conclusion

In many cases, data necessary for creating SVG maps is readily available. For instance, raw geographical data is available at http://edc.usgs.gov/geodata/. You can also work with aerial photographs by inserting images from http://terraserver.homeadvisor.msn.com/. For illustration purposes, my boss was gracious enough to let me post a map of Knox County, Tennessee, on my personal web site (http://mywebpages.comcast.net/kebugg/ knoxcounty.htm). You will need the SVG plug-in to view it.

DDJ

Listing One

<?xml version="1.0" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" 
  "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg width="800" height="600" viewBox="0 0 800 600"
     xmlns="http://www.w3.org/2000/svg">
     <desc>Simple animation</desc>
    <defs>
       <rect id="car" x="0" y="0" width="10" height="5" 
         style="stroke:black;fill:black;"/>
    </defs>
<
path id="i40" d="M 0,300 h800 "
style="fill:black; stroke:red; stroke-width:3;fill:none" />
<
image x="400" y="275" width="23" height="21" xlink:href="i40.gif"/>
<use xlink:href="#car">
<animateMotion begin="0s" dur="4s" repeatCount="indefinite">
<mpath xlink:href="#i40"/>
</animateMotion>
</use>
</svg>

Back to Article

Listing Two

function OnObjectClick(evt)
{
    var target = evt.target;    // evt.target is obj. clicked
    var objId=target.getAttribute("id");// id of object 
    // now have object-change its properties, etc   
}       

Back to Article


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.