Monday, August 28, 2006

SVG Maps

For the last few months, I've kept the idea of SVG maps accessible from an internet browser in the back of my mind. The reason isn't so much for the technological challenges involved, but for a practical effect: I've been working predominantly from a 56k modem (which is maxes out at about 44k) dial-up internet connection. The major map tools out there (Google, Yahoo, and Mapquest) are intended for high speed connections. They reload new data for every zoom in/out, and it takes a full minute for maps to load, which is painful when you want to quickly check directions before hitting the road.

Using a scalable vector graphic (SVG) map would fix this pretty well. Most map features (except satellite images) are represented by lines or borders. These lines and borders can be compactly represented as a series of coordinates, which is precisely how SVG is done. SVG uses textual data in an XML format to draw all sorts of basic shapes, complete with fills, transparency, and a variety of special effects.

By leveraging SVG for online maps, we get several immediate results:
- Faster to load. Map feature coordinates would be sent to a set of client-side JavaScript functions which translate these into the appropriate SVG elements. This would require significantly less data transfer than the usual image files that are used.
- Faster to zoom. When you zoom in/out on an image based map, entirely new images must be fetched from the server. However, with SVG, only the "new" map feature coordinates must be fetched, as previous data can be reused from a different zoom level

One downside of this approach is that to use SVG, you need a newer browser that supports XHTML and SVG. Mozilla Firefox does this, and IE will do this if you use an Adobe plugin. On the flipside, this leads to another positive:
- SVG maps are ideal for cell phones and other embedded applications. One of the driving factors of using XHTML is that is simplifies a lot of things browser-side. By requiring XML well-formedness and other constraints, internet browsers get simpler and more easily integrated into things like cell phones. If we assume that cell phones of the future contain XHTML browsers, and that cell phone data transfer rates are always lower than that of a hardwired connection, it makes perfect sense to use SVG for map data (as opposed to using images, which are worse in terms of data size, flexibility, and reusability)

As for me, I've been playing around a bit with SVG and fleshing out a possible implementation strategy. The guys at carto.net seem to have a good head start on SVG mapping, but I don't see anything (so far) that seems to focus on creating a fully-featured map that offers things like driving directions, business searches, and so on. They do however, have some samples that show how to use JavaScript to interact with SVG, talk about browser compatibility, and they have some neat demos set up.

For the most part, I've set up an rxml file in Ruby on Rails using XmlBuilder that includes some SVG data. This way, I can easily integrate information from a database, minimizing the number of unnecessary headaches. Using the .xml extension, however, means that while it works in Firefox, it doesn't work in IE, because IE simply displays the content of XML files (regardless of the doctype). If I could get RoR to output files with the .xhtml extension (and no, .rxhtml is not recognized), there would be no issue, but I haven't gotten far enough or deep enough yet to make that happen.

Here's how I would implement my proposed map system:
- Create a database of all possible map elements, along with their coordinates. For long elements, like the Texas border, I'd break them down into smaller elements.
- Assign each element a unique ID. Order the IDs based on how "localized" a feature is. Basically, SVG documents are displayed so that the first element listed is painted on the screen first, so any subsequent elements occurring in the same area are painted over top of it. The last SVG element is the last to be drawn, so it will not be overwritten. By ordering the element IDs properly, we can establish the "drawing order" so we don't need to worry about a lake being drawn on top of a bridge.
- When the user accesses the map, the center screen coordinates and the zoom level is sent to the server. The server processes this information and sends the relevant data (to be displayed + some beyond visual extent) to the client. This information includes coordinates, feature type (interstate, country road, railroad, lake, state border, etc.), feature name, and the range of zoomlevels for which it should be displayed.
- The client receives this information and processes it (via JavaScript) into SVG data and stores the original XML. When the SVG data is added, it is added in order of unique ID for reasons mentioned above.
- During panning, zooming, or re-centering, a request is sent to the server containing the new coordinates and zoom level, along with the list of unique IDs already existing client-side. The server sends any new data that will need to be redisplayed on the map.
- The client processes the new data and the stored data and paints the displayable elements (that fit into the window and meet the withinzoomlevel requirements).
- Rinse, repeat, ???, profit

Note that business and address searches can also be handled dynamically in a similar manner.

One minor caveat to this whole thing is data accessibility. In my limited search for good map data to use, I've come up relatively empty-handed. I suspect that it costs quite a bit to get good map data, and I'm not at a point where I can pony up the money for something like that. I'm open to suggestions if anyone knows where this sort of information is available to the general public. Even if data were used from a vendor, it is possible that lat&long coordinates could be extracted from the SVG source, so there may be some needs for code obfuscation, which (ironically enough) is something strange enough that I haven't really looked into it before. befor