2

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?

2

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;
  }
  • 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. – Bartors Oct 22 '18 at 14:31
  • 1
    depends on your version - see docs.geotools.org/stable/userguide/welcome/upgrade.html for more detail – Ian Turton Oct 22 '18 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! – Bartors Oct 22 '18 at 14:51
  • most analysis boils down to a SimpleFeatureIterator loop and some simple code – Ian Turton Oct 22 '18 at 15:19

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.