2

I'm using GeoTools 14.3. I've used the following code segment to create a textsymbolizer on a point layer.

StyleBuilder sb = new StyleBuilder();
    FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();

    TextSymbolizer textSymbolizer = sb.createTextSymbolizer();
    textSymbolizer.setFill(sb.createFill(Color.BLACK));
    textSymbolizer.setFont(sb.createFont("Arial", 10));
    textSymbolizer.setName("MyName");
    textSymbolizer.setLabel(sb.attributeExpression("name"));
    textSymbolizer.getOptions().put(TextSymbolizer.FOLLOW_LINE_KEY, "true");

    Rule rule = sb.createRule(textSymbolizer);

    FeatureTypeStyle fts = sb.createFeatureTypeStyle("Feature", rule);

    Style st = ShpFileStyles.GetDefaultRoadStyle();
    st.featureTypeStyles().add(fts);

    if (isMacroMapSelected) {
        ((FeatureLayer) roadLayer).setStyle(st);
    } else {
        ((FeatureLayer) microRoadLayer).setStyle(st);
    }

Here I'm drawing the name attribute available in the point shapefile.

Objective

Now I need to get another property, trafficCount, from a separate database. So the algorithm would be as follows.

  1. get the id of the current node (done)
  2. find the trfficCount from the database based on that id (done)
  3. draw trafficCount on a text symbolizer on this point (?)

How would I draw this external value on the point layer.

Note:

I can't use, sb.literalExpression(), as I have different trafficCounts for different nodes.

1

GeoTools works with Features so the only way to render things on the map is to have them be attributes in a Feature. So if you have a collection of features you want to draw and a list of other values that you also want to use in the renderer you need to add the "extra" variable onto the features that are being drawn.

The quickest/easiest way to do this is to prepare the data before you load it into GeoTools. For example, you could create a DataBase view that joined two tables together and the create DataStore from that.

However if for some reason you can't go down that route you can create a new FeatureSource by merging the two sets of data in code. The following code shows you how to handle the simplest case of joining a List of data (that is in the "correct" order) to a FeatureSource. Obviously in a real world application you would need to use a join column to lookup values to match the feature before the join, and handle errors etc.

private SimpleFeatureSource join(SimpleFeatureSource source, List<?> column, String name) {
    SimpleFeatureType schema = source.getSchema();
    SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
    builder.setName(schema.getName());
    builder.addAll(schema.getAttributeDescriptors());
    builder.add(name, column.get(0).getClass());
    SimpleFeatureType outSchema = builder.buildFeatureType();
    SimpleFeatureBuilder fBuilder = new SimpleFeatureBuilder(outSchema);
    SimpleFeatureIterator itr = null;
    List<SimpleFeature> out = new ArrayList<>();
    try {
      itr = source.getFeatures().features();
      int i = 0;
      while (itr.hasNext()) {
        SimpleFeature f = itr.next();
        fBuilder.addAll(f.getAttributes());
        fBuilder.add(column.get(i++));
        out.add(fBuilder.buildFeature(f.getID()));
      }
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } finally {
      if (itr != null)
        itr.close();
    }
    return DataUtilities.source(DataUtilities.collection(out));
  }
  • I've followed your answer and now I have a SimpleFeatureSource with my new attribute value ("TRAFFIC"). I'm having trouble drawing this new attribute on a TextSymbolizer. I've followed [this] (docs.geotools.org/latest/userguide/library/render/…) tutorial but failed. Any hint on using the SimpleFeatureSource to draw a textsymbolizer? – tybandara May 14 '16 at 5:23

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.