I've got a java Swing application which loads a shapefile and draw a map. Now I need to allow the user to click on the map and add points. I've successfully completed that with the following code.
private void runMe(double x, double y) {
final SimpleFeatureType TYPE = createFeatureType();
final SimpleFeatureBuilder BLDR = new SimpleFeatureBuilder(TYPE);
DefaultFeatureCollection featureCollection = new DefaultFeatureCollection("internal", TYPE);
// arbitrary start pos
Coordinate pos = new Coordinate(x, y);
int id = 0;
featureCollection.add(createFeature(BLDR, pos, id));
// Display the points on screen
Style style = SLD.createPointStyle("circle", Color.BLUE,
Color.BLUE, 1.0f, 5.0f);
Layer layer = new FeatureLayer(featureCollection, style);
map.addLayer(layer);
}
This function is called from a onMouseClicked() event. As obviously seen, this function adds a layer each time the function is called. Points are correctly displayed on the map.
Now I want to add only one layer to the existing map and add all the points to that layer. I've read that featurecollections can be added at a later time, so I've first added the layer with an empty feature collection as follows.
DefaultFeatureCollection featureCollection;
SimpleFeatureBuilder BLDR;
public void addPointFeature() {
final SimpleFeatureType TYPE = createFeatureType();
BLDR = new SimpleFeatureBuilder(TYPE);
featureCollection = new DefaultFeatureCollection("internal", TYPE);
// Display the points on screen
Style style = SLD.createPointStyle("circle", Color.BLUE,
Color.BLUE, 1.0f, 5.0f);
Layer layer = new FeatureLayer(featureCollection, style);
map.addLayer(layer);
}
Then at each onMouseClicked() event I add a point to the featureCollection as follows.
@Override
public void onMouseClicked(MapMouseEvent ev) {
DirectPosition2D p = ev.getWorldPos();
runMe2(p.getX(), p.getY());
}
private void runMe2(double x, double y){
// arbitrary start pos
Coordinate pos = new Coordinate(x, y);
val++;
featureCollection.add(createFeature(BLDR, pos, val));
mapPane.repaint();
}
private SimpleFeature createFeature(SimpleFeatureBuilder bldr,
Coordinate pos, int id) {
com.vividsolutions.jts.geom.Point p = GEOMFAC.createPoint(pos);
bldr.add(p);
bldr.add(id);
// null arg means allow the builder to generate a default feature ID
return bldr.buildFeature(null);
}
I can see the layer being added to the map. But none of the points are visible on the map.
I just noticed that, when I make any layer of the map invisible and visible again, all the points that I clicked appear (I use the map layer table toggle visibility button). This problem should be related to the layers not being refreshed/redrawn.
Best Answer
As you noticed in the previous discussion GeoTools used to have a complex event system to handle updates but it fell into disuse and no one has felt the need to fix it. The majority of GeoTools users manage the GUI (if they have one at all) themselves and "know" when to do a redraw based on the internal logic of the program.
You can directly call
redraw
on yourJPane
after you have updated your points. Or you could hook into the GeoTools event system by using a wrapper around yourFeatureLayer
:Then you can call
layer.update()
when you update theFeatureCollection
for the full Event experience you could also extend theFeatureCollection
to fire an event that your layer listened for to handle updates automatically.