[Geoserver-devel] WMS point labels being dropped

I have both points & lines in my data. WMS labels are getting dropped for a lot of points. I tried using the tilecache to rectify the problem by giving the metaBuffer value. As I increase the tilecache metaBuffer value, more & more point labels are getting included but now my line labels are being chopped arbitrarily.

My hypothesis was that point labels are precisely defined where they need to be positioned because of SLD anchor & displacement values. So they get rendered partially in two adjoining metatiles and everything comes out fine as long as I have metabuffer defined.

But the labels for lines are not precisely defined as to where they should be placed. So one metatile decides to put some part of the label into metabuffer but the next adjoining metatile never considered the label. If only both adjoining metatiles have decided to position the line label at the same precise location, everything would have been okay.

I dumped the tilecache and started using the on-the-fly metatiling from geoserver by setting "TILED=true" "TILESORIGIN=-180,-90,180,90" and "BUFFER=20". The line labels are fine but point label issue is not still corrected. A lot of point labels are still getting dropped.

Anybody has any ideas? What am I doing wrong?

Few more questions:
1) What is the logic used by the geoserver renderer to place line labels and point labels? Is there a tile to tile dependency? I mean, do the two adjoining tiles have any knowledge of each other's placement of labels?

2) Can somebody point me to geoserver source files which has the logic for rendering?

3) Is this something correctable in SLD rewriting or geoserver tuning?

Thanks in advance..
Louvy Joseph

louvy.joseph@anonymised.com ha scritto:

I have both points & lines in my data. WMS labels are getting dropped for a lot of points. I tried using the tilecache to rectify the problem by giving the metaBuffer value. As I increase the tilecache metaBuffer value, more & more point labels are getting included but now my line labels are being chopped arbitrarily.

My hypothesis was that point labels are precisely defined where they need to be positioned because of SLD anchor & displacement values. So they get rendered partially in two adjoining metatiles and everything comes out fine as long as I have metabuffer defined.

Bad assumption, you're not taking into consideration the label conflict
resolution algorithm (the one that avoids having two labels sit one
on top of the other).

But the labels for lines are not precisely defined as to where they should be placed. So one metatile decides to put some part of the label into metabuffer but the next adjoining metatile never considered the label. If only both adjoining metatiles have decided to position the line label at the same precise location, everything would have been okay.

I dumped the tilecache and started using the on-the-fly metatiling from geoserver by setting "TILED=true" "TILESORIGIN=-180,-90,180,90" and "BUFFER=20". The line labels are fine but point label issue is not still corrected. A lot of point labels are still getting dropped.

Anybody has any ideas? What am I doing wrong?

Few more questions:
1) What is the logic used by the geoserver renderer to place line labels and point labels? Is there a tile to tile dependency? I mean, do the two adjoining tiles have any knowledge of each other's placement of labels?

The renderer has no notion of tiling, besides the ability to automtically compute a meta buffer for the sole reason of rendering
completely the geometric parts (think very thick lines or point symbols).
About labelling, this is what happens
Every time a geometry needs to be labelled, some information, such as
the geometry, the text style, and the label itself, are given to a
separate object, the label cache.
When rendering the geometries is done, the label cache starts and
determines the label point for each geometry, sees if the current
label conflicts with another already defined label, and if not, renders
it and adds its bounds to the "busy" areas so that no other label
will overlap with it.

For points as you say the position is defined. For lines and polygons,
a mid point is found for the label considering only the part of the geometry that sits inside the currently rendered area (your tile, or
the meta tile if you enabled server side meta tiling).

Geometries are added to the label cache in the order they are loaded,
so the bottom-most layers will have a higher likeliness of having
their labels displayed. This is, unless you play with some extra params
(vendor specific) that allow you to give a higher priority to
certain geometries. To play with these options see:
http://docs.codehaus.org/display/GEOSDOC/LabelingOptions

2) Can somebody point me to geoserver source files which has the logic for rendering?

Rendering is done by GeoTools, the classes that do the rendering are
StreamingRenderer and LabelCacheDefault. The latter in particular is
the one that compute label points and runs the label conflict resolution
algorithm:
http://svn.geotools.org/geotools/trunk/gt/modules/library/render/src/main/java/org/geotools/renderer/lite/LabelCacheDefault.java

As for the meta buffer, there is no way I know of that playing with it will
give you good results. GeoServer does not draw labels that do cross the border of the current rendering area, and there is a solid reason for that.
Say you have a point whose label crosses the rendering area, and does
not conflict with anything in this area. So you decide to render it,
and you have only part of it in the current tile.
In the next tile, let's say the same point won't be renderer because the label conflicts with another one that can only be seen in the next tile,
but that happens to have been added to the label cache before the one
that crosses the tile limits.

If you extend this reasoning, you'll see there is no way to draw labels
that do span the tile borders, because to know if a label will be rendered for sure you'll have to consider all the map at the same time,
at the specific zoom level you're trying to render it.
This is something that can be done, and I suspect that's what big
map providers such as Google Maps do. I believe they have a fixed set of
zoom levels,a map that does not change often, so they first run a global
labelling algorithm on the whole map, deciding where each label will be positioned, and thus creating a new point layer that has the position
and style of each label, and then they run a tiled rendering that
does render the labels exactly where the label layer says, without
the need to consider conflict resolution (because it has been addressed
once and for all in the previous step).

This kind of algorithm is something we don't have at the moment, thought
one day I would like to implement it.

As for your specific issue, if you want to give point higher priority,
use the priority vendor parameter, use smaller fonts to reduce
the contention, and instead of using the meta buffer, that will only
introduce more cut labels, use tilecache to expand the meta tile
used during rendering so that fewer labels actually cross the rendering
borders.

If despite this you think you've found a bug, or you have suggestions
on how to improve labelling, I'm all ears :slight_smile:

Cheers
Andrea