Polymaps, TileStache and SVG CSS styling issues
A few days ago I started playing with Polymaps and TileStache, two very promising WebGIS building tools.
The final goal of this experiments was the integration with Django.
Polymaps
Polymaps is a Javascript library aimed to display svg maps in a web page, recently I’ve watched to an interesting talk about a Django-powered app built on top of Polymaps:
The main reason to give Polymaps a try is the interesting support to tiled vector layers, as far as I know a unique feature.
I’ve found the documentation of Polymaps a bit obscure and still incomplete (I just hope it isn’t another facade Open Source product where the lack of documentation and community support limits the use to commercial projects).
A quick look in the code shows no comments and rather obscure variable names, debbugging this library would certainly be a nightmare if you’re not the author, if you compare the source code with OpenLayers’s code you get the idea.
BTW I managed to make it work in a few hours (with all the server stuff).
TileStache
TileStache is a python library aimed to build, cache and manage map tiles. It’s similar to TileCache in scope and uses the well known Mapnik renderer while the data provider is implemented with shapely and OGR and can read the most widely used formats (postgis, shapefile, geojson).
TileStache is the ideal companion to Polymaps because it can handle and cache vector tiles (geojson) through the Vector class (don’t even try to use the PostgreSQL class you can find in Goodies, it’s kind of unofficially deprecated and it will let you waste your time).
I had to fork the project on github and made a pull request to fix the missing “port” parameter to the DB connection since I’m using a not-standard port.
SVG CSS
I admit I am a true beginner with SVG and while I was trying to experiment with the stylist features of Polymaps I discovered some counter-intuitive (at least for me, coming from XHTML CSS) behaviours:
You can define styles in three ways:
- CSS rules
- “style” attribute of the SVG element
- individual attributes (“stroke”, “fill” etc. etc.) of the SVG element
Strange enough, the priority is top-down, while I would have expected that point 3 had a higher priority.
Another thing worths noting is that what distinguish a polygon from a linestring in the Polymaps generated “path” SVG element is just that the “d” element (which contains the geometry) ends with a “Z”.
This is a linestring:
<path d="M101.99999715555555,189.9999971369224 L75.00000142222234,219.00000190473258 L75.00000142222234,242.49999834108655 L94.49999928888906,242.99999806558844 L102.49999928888906,255.4999976705726 L101.99970702222231,256"/>;
This is a polygon:
<path d="M95.07080533333351,256.00000052462633 L0,196.67516186124612 L0,192.0000022835775 L0,128.0000001888236L0,70.92093168072711 L175.92470186666674,0.000006325172648757871 L192,0.000006325172648757871 L256,0.000006325172648757871 L256,64.00000444302805 L256,128.0000001888236 L256,160.99230434784874 L113.66593991111131,256.00000052462633Z"/>;
Styling the plygon fill without hitting linestring in a GEOMETRYCOLLECTION layer turned out to be quite troublesome.
I ended up with a CSS-3 attribute CSS rule:
.layer path {
fill: cyan;
fill-opacity: .85;
stroke: #012;
stroke-linecap: round;
}
.layer circle {
fill: cyan;
fill-opacity: .85;
stroke: #012;
}
/* Don't fill in SVG */
.layer path:not([d$="Z"]){
fill: none;
stroke-width: 3px;
}
I wonder if there is a better way…
This story continues with: TileStache Django tiny wrapper.





2012-01-05 at 9.26 pm
Interesting choice by Polymaps about the polygons and linestrings, I’d assume it’s to make it easier to do calculations on the data. SVG has a polygon element which could have been used to distinguish the two. However, should you wish my guess is that its’s pretty simple to add a class to the elements that you want to reach quickly with stylerules. That should be more efficient than using the ‘.layer path:not([d$="Z"])’ rule.
2012-01-05 at 10.28 pm
Great article, and thanks for the patch to Tilestache! I’ve merged it in, and will push it out with the next release.
2012-01-06 at 11.23 am
@Erik
thanks for your comments, I myself was wondering why they’are not using the full set of geometric SVG elements (Polygon, Line etc.) instead of only Path and Circle.
About adding a class, the root of all my problems is that I’m using a GEOMETRYCOLLECTION type in my PostGIS DB. This triggers a lot of problems, to say one: Django OSM admin doesn’t support collections and OpenLayers has a longstanding bug in WKT format reader/writer, but I’ll write more on these topics in another post.
BTW I tried to add a class using a stylist (http://polymaps.org/docs/stylist.html) bound to the “load” or “show” event. Unfortunately this approach revealed to be problematic because the stylist receives a GeometryCollection object and not the individual components, there is a bug in the library that removes child elements in the SVG element, removing child geometries in case of collections.
I’m still trying to debug that messy library, Polymaps source code is a good example of how Javascript code can be similar to old good i386 assembly
2012-01-06 at 12.23 pm
@Michal
Thanks for the pull, it’s nice to know that TileStache is open to contributions (also when they’re so tiny
)
I’ve also forked and pulled a request to Polymaps, it (hopefully) fixes the bug in Stylist.title when dealing with geometry collections, let’s see if they also accept patches.
2012-01-10 at 4.58 pm
Alessandro, this is definitely very interesting post
2012-01-11 at 10.01 am
@Paolo
thanks Paolo, I’m happy to see how our “virtual life path” crosses again!
2012-01-11 at 7.21 pm
[...] This is the second part of the story about my experiments with the wonderful TileStache that I started with TileStache and Polymaps SVG experiments. [...]