3

I want to develop a simple GIS application using GeoTools. I have looked at the tutorials but i could get to much meaningful from them.

I have a simple JMapFrame to which add can add a featureLayer from a shapefile

public void action(ActionEvent e) throws Throwable{
 sourceFile = JFileDataStoreChooser.showOpenFile("shp", null);
 if (sourceFile == null) {
 return;
 }
 FileDataStore store = FileDataStoreFinder.getDataStore(sourceFile);
 featureSource = store.getFeatureSource();
 Style style = SLD.createSimpleStyle(featureSource.getSchema());
 Layer layer = new FeatureLayer(featureSource, style);
 map.addLayer(layer);
}

Now, lets say I want to create a buffer around my features. From what I have understood I have to get the featureSource, then create a featureCollection, iterate through the features and for each of those feature I have to cast them to a Geometry, then create a buffer.

When I have created a buffer should I go all the way back to featureLayer and add it to my map?

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Oct 10, 2018 at 11:39

1 Answer 1

3

In general GeoTools always looks to display Layers in the JMapFrame, so any time you want to display something new you will need to construct a new layer and add it to the MapContext.

For any operation involving features (such as buffering) then you will need to loop through all of the features you need and apply the operation to them. This will usually use a SimpleFeatureIterator and generate a new SimpleFeatureCollection which you can generate a new layer from.

I'd use something like this to do the buffering:

 public SimpleFeature bufferFeature(SimpleFeature feature, Quantity<Length> distance) {
 // extract the geometry
 GeometryAttribute gProp = feature.getDefaultGeometryProperty();
 CoordinateReferenceSystem origCRS = gProp.getDescriptor().getCoordinateReferenceSystem();
 Geometry geom = (Geometry) feature.getDefaultGeometry();
 Geometry retGeom = bufferPoint(distance, origCRS, geom);
 // return a new feature containing the geom
 SimpleFeatureType schema = feature.getFeatureType();
 SimpleFeatureTypeBuilder ftBuilder = new SimpleFeatureTypeBuilder();
 ftBuilder.setCRS(origCRS);
 for (AttributeDescriptor attrib : schema.getAttributeDescriptors()) {
 AttributeType type = attrib.getType();
 if (type instanceof GeometryType) {
 String oldGeomAttrib = attrib.getLocalName();
 ftBuilder.add(oldGeomAttrib, Polygon.class);
 } else {
 ftBuilder.add(attrib);
 }
 }
 ftBuilder.setName(schema.getName());
 SimpleFeatureType nSchema = ftBuilder.buildFeatureType();
 SimpleFeatureBuilder builder = new SimpleFeatureBuilder(nSchema);
 List<Object> atts = feature.getAttributes();
 for (int i = 0; i < atts.size(); i++) {
 if (atts.get(i) instanceof Geometry) {
 atts.set(i, retGeom);
 }
 }
 SimpleFeature nFeature = builder.buildFeature(null, atts.toArray());
 return nFeature;
 }
 /**
 * @param distance
 * @param origCRS
 * @param geom
 * @return
 */
 @SuppressWarnings("unchecked")
 public Geometry bufferPoint(Quantity<Length> distance, CoordinateReferenceSystem origCRS, Geometry geom) {
 Geometry pGeom = geom;
 MathTransform toTransform, fromTransform = null;
 // reproject the geometry to a local projection
 Unit<Length> unit = distance.getUnit();
 if (!(origCRS instanceof ProjectedCRS)) {
 double x = geom.getCoordinate().x;
 double y = geom.getCoordinate().y;
 String code = "AUTO:42001," + x + "," + y;
 // System.out.println(code);
 CoordinateReferenceSystem auto;
 try {
 auto = CRS.decode(code);
 toTransform = CRS.findMathTransform(origCRS, auto);
 fromTransform = CRS.findMathTransform(auto, origCRS);
 pGeom = JTS.transform(geom, toTransform);
 unit = SI.METRE;
 } catch (MismatchedDimensionException | TransformException | FactoryException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 } else {
 unit = (Unit<Length>) origCRS.getCoordinateSystem().getAxis(0).getUnit();
 }
 UnitConverter converter = distance.getUnit().getConverterTo(unit);
 // buffer
 Geometry out = pGeom.buffer(converter.convert(distance.getValue()).doubleValue());
 Geometry retGeom = out;
 // reproject the geometry to the original projection
 if (!(origCRS instanceof ProjectedCRS)) {
 try {
 retGeom = JTS.transform(out, fromTransform);
 } catch (MismatchedDimensionException | TransformException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 }
 return retGeom;
 }
answered Oct 12, 2018 at 13:23
5
  • Thanks for the answer! Could you say what imports you are using for Quantity<>, Unit<> and Length as I cannot figure out the right library. Commented Oct 22, 2018 at 14:31
  • 1
    depends on your version - see docs.geotools.org/stable/userguide/welcome/upgrade.html for more detail Commented Oct 22, 2018 at 14:37
  • Great! I do really appreciate your answers. Do you know any "step by step" tutorials for performing analysis in Geotools? I know it is all in docs but, as I hope you understand, it is quite a lot be look at for a beginner. Anyway, thank you for your time! Commented Oct 22, 2018 at 14:51
  • 1
    most analysis boils down to a SimpleFeatureIterator loop and some simple code Commented Oct 22, 2018 at 15:19
  • hi ian , one question in your experience, Would it be possible to receive a wkt string and convert it to geometry, then apply the buffer to it, keeping in mind that the crs could see the source but it should always come out as 4326? Commented Dec 29, 2022 at 5:15

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.