document.writeElement("g", asChild);
document.writeId("labels." + tile.getCode().toString());
for (InternalFeature feature : tile.getFeatures()) {
Coordinate pos = geoService.calcDefaultLabelPosition(feature);
if (null != pos) {
Point p = factory.createPoint(pos);
Point labelPos;
try {
String labelString = feature.getLabel();
if (null != labelString && labelString.length() > 0) {
labelPos = (Point) transformer.transform(p);
boolean createChild = true;
Rectangle2D textBox = textService.getStringBounds(labelString, labelStyle.getFontStyle());
document.writeElement("rect", createChild);
document.writeAttribute("id", feature.getId() + ".lblBG");
document.writeAttribute("x", labelPos.getX() - Math.round(textBox.getWidth() / 2));
document.writeAttribute("y", labelPos.getY() - Math.round(textBox.getHeight()));
document.writeAttribute("width", Math.round(textBox.getWidth()));
document.writeAttribute("height", Math.round(textBox.getHeight()));
document.writeAttribute("style", getCssStyle(bgStyle));
createChild = false;
// Text:
document.writeElement("text", createChild);
document.writeAttribute("id", feature.getId() + ".lblTXT");
document.writeAttribute("x", labelPos.getX());
// pull up baseline position to accommodate for descent
document.writeAttribute("y", labelPos.getY() - Math.round(textBox.getMaxY()));
// TODO: config option, center label
document.writeAttribute("text-anchor", "middle");
document.writeAttribute("style", getCssStyle(labelStyle.getFontStyle()));
document.writeTextNode(labelString);
}