Search code examples
javageotools

How do you use Java GeoTools to add text and display them on JMapFrame's map content?


I know how to create a layer and display points on JMapFrame. But I do not know how to add a text string next to a point? Below is the code to display multiple coordinates on JMapFrame, I thought adding text strings would have similar codes. Please help, thanks!

    SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
    builder.setName("feature1");
    builder.setCRS(DefaultGeographicCRS.WGS84);
    builder.add("location", Point.class);
    final SimpleFeatureType TYPE = DataUtilities.createType("Points", "points", "the_geom:MultiPoint");
    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    GeometryFactory geometryFactory = (GeometryFactory) JTSFactoryFinder.getGeometryFactory();
    MultiPoint points = geometryFactory.createMultiPoint(coordinates); //be careful of the order
    featureBuilder.add(points);
    SimpleFeature feature = featureBuilder.buildFeature(null);
    DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
    featureCollection.add(feature);
    Style style = SLD.createPointStyle("square", Color.red, Color.red, 1.0f, 8.0f);
    //Style style = SLD.createSimpleStyle(TYPE,Color.RED);
    Layer layer = new FeatureLayer(featureCollection, style);

That is how I created my layer and below I managed to display my points on a shape file. I did not post all my codes because it was too many, but this is the general implementation.

    MapContent map = new MapContent();
    map.layers().add(layer);
    JMapFrame.showMap(map);

Can anyone help me with adding text strings next to my points? Thank you so much!!!


Solution

  • You need to add a TextSymbolizer to your style to draw the text.

    Style style = SLD.createPointStyle("square", Color.red, Color.red, 1.0f, 8.0f);
    StyleBuilder styleBuilder = new StyleBuilder();
    String attributeName = "name";
    Font font = styleBuilder.createFont("Times New Roman", 10.0);
    TextSymbolizer textSymb = styleBuilder.createTextSymbolizer(Color.black, font, attributeName);
    Rule rule = styleBuilder.createRule(textSymb);
    style.featureTypeStyles().get(0).rules().add(rule);
    

    should do it. The key line is TextSymbolizer textSymb = styleBuilder.createTextSymbolizer(Color.black, font, attributeName); that creates the symbolizer using Black as the text color, font as the font to use (this must be a font on your machine) and finally attributeName is the data column (attribute) that should be used to create the label. If you instead want a fixed string then you can use styleBuilder.createStaticTextSymbolizer which just uses the last parameter as the labeltext.

    In general for real code it is better to use the StyleBuilder rather than the SLD methods for full control of your style. Internally GeoTools styles are represented as OGC Styled Layer Descriptors (SLD) so the SLD Cookbook may be helpful. I also regularly use this method when debugging.

    private static void printStyle(Style style) throws TransformerException {
    
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        SLDTransformer transformer = new SLDTransformer();
        transformer.setIndentation(2);
        transformer.transform(style, bos);
        String styleStr = bos.toString();
        System.out.println(styleStr);
      }
    

    Which will print this for the above code:

    <?xml version="1.0" encoding="UTF-8"?><sld:UserStyle xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc">
      <sld:Name>Default Styler</sld:Name>
      <sld:FeatureTypeStyle>
        <sld:Name>name</sld:Name>
        <sld:Rule>
          <sld:PointSymbolizer>
            <sld:Graphic>
              <sld:Mark>
                <sld:Fill>
                  <sld:CssParameter name="fill">#FF0000</sld:CssParameter>
                </sld:Fill>
                <sld:Stroke>
                  <sld:CssParameter name="stroke">#FF0000</sld:CssParameter>
                </sld:Stroke>
              </sld:Mark>
              <sld:Size>8.0</sld:Size>
            </sld:Graphic>
          </sld:PointSymbolizer>
        </sld:Rule>
        <sld:Rule>
          <sld:TextSymbolizer>
            <sld:Label>
              <ogc:PropertyName>name</ogc:PropertyName>
            </sld:Label>
            <sld:Font>
              <sld:CssParameter name="font-family">Times New Roman</sld:CssParameter>
              <sld:CssParameter name="font-size">10.0</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.0</sld:AnchorPointX>
                  <sld:AnchorPointY>0.5</sld:AnchorPointY>
                </sld:AnchorPoint>
              </sld:PointPlacement>
            </sld:LabelPlacement>
            <sld:Fill>
              <sld:CssParameter name="fill">#000000</sld:CssParameter>
            </sld:Fill>
          </sld:TextSymbolizer>
        </sld:Rule>
      </sld:FeatureTypeStyle>
    </sld:UserStyle>