I stumbled across this problem recently recently and found it somewhat intriguing.

My setup is an Openlayers client talking directly to mapserver in tiled WMS mode. My map data is a polygon coverage, being rendered as a single-pixel wide line. I noticed in several places, where the edge of a polygon was nearly parallel to and crossed the edge of the map tile, it is possible for a piece of the line to be missing. Ie. the tile on one side rendered the first 1/3 of the line, the tile on the other side rendered the last 1/3 of the line, but the 1/3 of the line in the middle went un-drawn by either tile.

I see that someone else has already documented something closely related to this issue:

http://crschmidt.net/blog/archives/154/mapserver-rendering-bug/

And that it has already been solved in tilecache by adding a buffer around the meta-tiles during rendering - but I don't think that solution will help with the single-pixel-wide line. Meta-tiling and/or increasing the size of the tiles would reduce the likelihood of this happening, but I don't think they could prevent it. Rendering oversize tiles/meta-tiles and cropping them wouldn't have any effect, unless you were using anti-aliasing, in which case the problem might be reduced to the line getting more faint as it crossed the edge, but still I don't think that the line would be properly rendered.

Without looking at the code, I suspect the heart of the problem is two-fold, (1) the clipper is rounding to the nearest pixel (possibly differently for each tile) and (2) the line rasterizer cannot and will not draw exactly the same pixels for lines that are clipped as it would for drawing the whole line (especially if they are clipped differently in each tile).

I suppose this might be considered a minor issue because of how rarely one would expect to have their lines be nearly parallel to and cross the tile boundaries, but I've actually seen that it can happen on just about any line that crosses a tile boundary at an acute angle.

It seems to me that the only solution is to not clip lines on the edge of the image, and instead keep the entire line to the next point (but not the entire linestring or polygon). This obviously has an impact (probably minor) on performance, so perhaps it should be an option to turn it on/off. Perhaps I'm completely off-base here, and maybe no-one cares how good non-anti-aliased, single-pixel-wide lines look. But the solution seems simple enough that it might be worth implementing.

Chris

Reply via email to