6

I am trying to create labels with arbitrary values on a WMS map using GeoTools (9.4). I have created a feature type, a feature (in a data store), and a user layer. With that I generated an SLD document and sent it to Geoserver.

Here is my code:

double x_min, y_min, x_max, y_max, width, height, x_center, y_center;

x_min = -10491786.13906;
y_min = 3869280.8541878;
x_max = -10478619.86094;
y_max = 3877727.1458122;

width = x_max - x_min;
height = y_max - y_min;

x_center = x_min + height / 2;
y_center = y_min + height / 2;

//  Create labels
SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder();
b.setName("ml");
b.setNamespaceURI("http://www.mylabel.com/");
b.setSRS("EPSG:900913");
b.add("geom", Point.class);
b.add("label", Integer.class);

SimpleFeatureType sft = b.buildFeatureType();

SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(sft);
GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();

Point point = geometryFactory.createPoint(new Coordinate(x_center, y_center));
featureBuilder.add(point);
featureBuilder.add(1);

SimpleFeature feature = featureBuilder.buildFeature(null);

List<SimpleFeature> features = new ArrayList<SimpleFeature>();

features.add(feature);

MemoryDataStore mds = new MemoryDataStore(sft);

mds.addFeatures(features);


//  Create symbolization
StyleFactory sf = CommonFactoryFinder.getStyleFactory();
FilterFactory ff = CommonFactoryFinder.getFilterFactory();

Fill fillFont = sf.createFill(ff.literal("#ff0000"));
Font[] font = new Font[1];
font[0] = sf.createFont(ff.literal("sans-serif"), ff.literal("normal"), ff.literal("normal"), ff.literal(12));
Fill fillHalo = sf.createFill(ff.literal("#ffffff"));
Halo halo = sf.createHalo(fillHalo, ff.literal(3));
AnchorPoint ap = sf.createAnchorPoint(ff.literal(0.5), ff.literal(0.5));
Displacement d = sf.createDisplacement(ff.literal(0), ff.literal(0));
PointPlacement pp = sf.createPointPlacement(ap, d, ff.literal(0));
Symbolizer symbolizer = sf.createTextSymbolizer(fillFont, font, halo, ff.literal("label"), pp, "geom");
Style style = sf.createStyle();
style.setName("my-label");
StyleBuilder sb = new StyleBuilder();
style.featureTypeStyles().add(sb.createFeatureTypeStyle("my-label", new Symbolizer[] { symbolizer }));


//  Create SLD
StyledLayerDescriptor sld = sf.createStyledLayerDescriptor();
UserLayer ul = sf.createUserLayer();
ul.setInlineFeatureDatastore(mds);
ul.setInlineFeatureType(sft);
ul.addUserStyle(style);
sld.addStyledLayer(ul);

/*
// use UserLayerBuilder
UserLayerBuilder ulb = new UserLayerBuilder();
ulb.inlineData(mds, TYPE);
StyledLayerDescriptor sld = ulb.buildSLD();
*/

SLDTransformer styleTransform = new SLDTransformer();
String sXml = styleTransform.transform(sld);

//  Create map
URL url = new URL("http://localhost:9080/geoserver/wms");
WebMapServer wms = new WebMapServer(url);

WMSCapabilities capabilities = wms.getCapabilities();
org.geotools.data.ows.Layer[] layers = WMSUtils.getNamedLayers(capabilities);

GetMapRequest map_request = wms.createGetMapRequest();
map_request.setFormat("image/png");
map_request.setDimensions(100, 100);
map_request.setTransparent(true);
map_request.setSRS("EPSG:900913");
map_request.setBBox(new Double(x_min).toString() + "," + new Double(y_min).toString() + "," + new Double(x_max).toString() + "," + new Double(y_max).toString());

map_request.setProperty(GetMapRequest.SLD_BODY, URLEncoder.encode(sXml, "UTF-8"));

GetMapResponse map_response = (GetMapResponse)wms.issueRequest(map_request);

Here is the SLD document:

<?xml version="1.0" encoding="UTF-8"?>
<sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0">
<sld:UserLayer>
<sld:InlineFeature>
<FeatureCollection>
<gml:boundedBy>
<gml:Box srsName="900913">
<gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-1.04875629932E7,3873504 -1.04875629932E7,3873504</gml:coordinates>
</gml:Box>
</gml:boundedBy>
<gml:featureMember>
<ml fid="fid--57398c6c_140a74006e1_-7fdf">
<:geom>
<gml:Point srsName="900913">
<gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">-1.04875629932E7,3873504</gml:coordinates>
</gml:Point>
</:geom>
<:label>1</:label>
</:ml>
</gml:featureMember>
</FeatureCollection>
</sld:InlineFeature>
<sld:LayerFeatureConstraints>
<sld:FeatureTypeConstraint/>
</sld:LayerFeatureConstraints>
<sld:UserStyle>
<sld:Name>my-label</sld:Name>
<sld:Title/>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:FeatureTypeName>my-label</sld:FeatureTypeName>
<sld:Rule>
<sld:TextSymbolizer>
<sld:Geometry>
<ogc:PropertyName>geom</ogc:PropertyName>
</sld:Geometry>
<sld:Label>label</sld:Label>
<sld:Font>
<sld:CssParameter name="font-family">sans-serif</sld:CssParameter>
<sld:CssParameter name="font-size">12</sld:CssParameter>
<sld:CssParameter name="font-style">normal</sld:CssParameter>
<sld:CssParameter name="font-weight">normal</sld:CssParameter>
</sld:Font>
<sld:LabelPlacement>
<sld:PointPlacement>
<sld:AnchorPoint>
<sld:AnchorPointX>0.5</sld:AnchorPointX>
<sld:AnchorPointY>0.5</sld:AnchorPointY>
</sld:AnchorPoint></sld:PointPlacement>
</sld:LabelPlacement>
<sld:Halo>
<sld:Radius>3</sld:Radius>
<sld:Fill>
<sld:CssParameter name="fill">#ffffff</sld:CssParameter>
</sld:Fill>
</sld:Halo>
<sld:Fill>
<sld:CssParameter name="fill">#ff0000</sld:CssParameter>
</sld:Fill>
</sld:TextSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:UserLayer>
</sld:StyledLayerDescriptor>

Geoserver returns the following error:

Element type "ml" must be followed by either attribute specifications, ">" or "/>".

I am expecting an image with a "1" in the center.

The problem seems to be related to a missing namespace, but I don't know how to correct that.

Thanks.

1

Based on the example here you need to have a namespace for your feature or nothing at all (so no :):

    <sld:InlineFeature>
        <sld:FeatureCollection>
           <sld:featureMember>
              <polygonProperty>
                 <gml:Polygon>
                    <gml:outerBoundaryIs>
                       <gml:LinearRing>
                          <gml:coordinates>240167.78347885,869905.5610437
                             249317.75340551,869905.5610437 249317.75340551,879026.25071433
                             240167.78347885,879026.25071433
                          240167.78347885,869905.5610437</gml:coordinates>
                       </gml:LinearRing>
                    </gml:outerBoundaryIs>
                 </gml:Polygon>
              </polygonProperty>
           </sld:featureMember>
        </sld:FeatureCollection>
     </sld:InlineFeature>

Also if you want to refer to the label elelment of the feature then you need a <PropertyName> tag around label in the <label> tag.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.