Logo OpenStreetMap OpenStreetMap

Rendering is a Pain

Opublikowany przez asciipip, 2.05.2010 w języku English. Ostatnio zaktualizowany 3.05.2010.

Specifically, the stylesheets are a pain.

I want to render my own map tiles, mostly for use on my phone. I figured while I was at it, I'd modify the rendering a bit to show me some of the features that I want to map that aren't on the default slippy map (lanes, maxspeed, among others). Then I learned what a pain the mapnik stylesheets are.

Mapnik requires a lot of repetition; you have to respecify all of the rendering parameters for every variation of one of those parameters. (Make motorways wider at higher zoom levels? You have to repeat the color, linecap, and linejoin parameters.) This leads to a lot of work for modifying some of the rules.

I liked the idea of cascadenik, but I didn't like the look of the example rules it ships with. I tried replicating the default slippy map rules in cascadenik and quickly ran into a combinatorial explosion in the generated stylesheets: cascadenik generates rules for every combination of selectors you use, even if it's pointless. Because, for example, I used [highway=service][service=parking_aisle] in one rule, it generated two rules for every single highway= value, one with service=parking_aisle and one with service!=parking_aisle, even though the renderings for those rules were identical. That proliferation of rules makes the actual mapnik stylesheet *huge*. With just the road and path rules implemented (no landuse or buildings yet), cascadenik gives me a 30MB stylesheet, roughly 100 times the size of the standard stylesheet. That size comes at a rendering cost, too. I was doing renderings of features from zoom 9 down to 18 to compare the two rulesets. The cascadenik rules would take anywhere between four and ten minutes to render (of which about a minute was spend just reading in the generated stylesheet), while rendering with the standard stylesheet would finish in less than ten seconds.

I also took a look at spreadnik, but it's too basic at this juncture. It doesn't support mapnik ShieldSymbolizers, and not only do I want shields on my roads, that's an area that I want to experiment with. (I want to try putting the appropriate US road network shields on roads, as pulled from the route relations.)

At this point I'm torn between trying to optimize the cascadenik stylesheets (I think if I introduce more map layers and use fewer selectors--essentially moving the selection logic from the cascadenik selectors into the SQL statements--I can avoid a lot of the unnecessary rule generation) and giving up and just working with the standard stylesheet while keeping a cheatsheet of the common rendering for various styles (e.g. all motorway casings are #506077, except bridges, which are black; all non-tunnel motorway fills are #809bc0, while motorway tunnel fills are #d6dfea; etc.). I'm really leaning toward the "give up on stylesheet preprocessors" option.

ikona e-maila ikona Bluesky ikona Facebooka ikona LinkedIn ikona Mastodon ikona Telegrama ikona X

Dyskusja

Komentarz od JohnSmith z 2 maja 2010 o 17:19

Yes the mapnik style sheet is unwieldy, but not impossible if you are determined.

I've come up with custom shields + style sheet for Australian shields, feel free to email me if you want more details, or better still join the dev mailing list.

Komentarz od migurski z 2 maja 2010 o 19:35

Hi asciiphil,

Cascadenik is my project, thanks for your comments. The combinatorial explosion issue is very much something I've run into when developing stylesheets, and like you I've found myself pushing a lot of logic in SQL to fix the problem. Here, for example, is a SELECT statement from one recent project: http://dpaste.com/hold/190143/

The "is_tunnel" and "is_bridge" parts help handle the various different ways of saying "yes", and the "kind" result column groups together many different types of roads. There's also a subselect in there you might have noticed: it groups the lines from each layer into single MULTILINE geometries, which helps deal with certain casing issues. Ultimately this is the way I've made stylesheets workable for myself - keep the ability to separate line casings and widths and colors and zoom levels, and use the expressiveness of SQL to munge the planet database into something more directly applicable to rendering. I know that Cloudmade have done similar things, including I believe downsampling the detail level of the road vectors for certain rendered zoom levels.

Komentarz od migurski z 2 maja 2010 o 19:40

On further thought, it's probably worth noting that Mapnik's processing pipeline, the way that styles must be specified before geometry is passed through, is a major constraint here. I could imagine a future modification to Mapnik where it behaves more like HTML + CSS and applies the rules in-flight as they are needed, and removes the need to prepare all possible combinations. I expect this is many versions off, though.

Komentarz od Victor Bielawski z 2 maja 2010 o 22:43

Mapnik 2 (under development) should solve some of these problems. It can take width, image filenames, etc. directly from tags, instead of specifying every possible value in the stylesheet.

http://trac.mapnik.org/wiki/Mapnik2

Komentarz od asciipip z 2 maja 2010 o 23:29

Hmm. Mapnik 2 sounds like it'll have a number of features I could really use, ones that I was planning on working around by having a script that generated some rules based on database queries. migurski's convinced me to stick with cascadenik (since complicated stylesheets seem to be feasible with it, and I really hate having to repeat myself, especially when experimentally changing rules).

migurski, that query is really interesting. I assume the !BBOX! gets filled in by mapnik when it actually runs the query. The way collection is very interesting. (I'm still learning how all of this works together, so I didn't know about ST_Collect() or that Mapnik would work with MULTILINE geometries.) I suppose I could just try this (but I'd have to rework a bunch of rules first), but I initially tried using Cascadenik's outline symbolizer for bridges (with the thought that I might be able to skip the casing pass in a lot of cases), but when I had a divided highway at lower zoom levels, the second way's rendering drew its bridge outline on top of the first way. Am I correct in surmising that grouping the ways in a tile together like you have would avoid that artifact (because the outlines for both ways would be drawn together, followed by the main lines)?

Zaloguj się, aby dodać komentarz