Abhishek Dey Das Abhishek Dey Das - 4 months ago 7x
Java Question

Need help converting an array of JTS Geometry objects to a shape file

I have an array of JTS Geometry objects that I need to put in a shape file. I also have some other attributes that needs to go in a DBase file. I need to index the spatial objects as well and if required create the projection file. Is there a way to do this using JTS/GeoTools. I tried ShapeFileWriter but that doesn't seem enough (no dbf support for instance).

public Shape(String shpFileName, String shxFileName) throws FileNotFoundException {
RandomAccessFile shpFile = new RandomAccessFile(shpFileName, "rw");
this.shpChannel = shpFile.getChannel();
RandomAccessFile shxFile = new RandomAccessFile(shxFileName, "rw");
this.shxChannel = shxFile.getChannel();

public void createShapeFile(GeometryCollection geometries, ShapeType shapeType) throws IOException {
ShapefileWriter writer = new ShapefileWriter(this.shpChannel, this.shxChannel);
writer.write(geometries, shapeType);



You can't write out a set of Geometries and get a DBF file (as there are no attributes to put in it). You need to create a FeatureCollection and then pass that to a ShapeFileDatastore.

You will need something like:

public boolean writeFeatures(
        FeatureCollection<SimpleFeatureType, SimpleFeature> features) {

    if (shpDataStore == null) {
        throw new IllegalStateException(
                "Datastore can not be null when writing");
    SimpleFeatureType schema = features.getSchema();
    GeometryDescriptor geom = schema

    try {

         * Write the features to the shapefile
        Transaction transaction = new DefaultTransaction(

        String typeName = shpDataStore.getTypeNames()[0];
        SimpleFeatureSource featureSource = shpDataStore

         * The Shapefile format has a couple limitations: - "the_geom" is always
         * first, and used for the geometry attribute name - "the_geom" must be of
         * type Point, MultiPoint, MuiltiLineString, MultiPolygon - Attribute
         * names are limited in length - Not all data types are supported (example
         * Timestamp represented as Date)
         * Because of this we have to rename the geometry element and then rebuild
         * the features to make sure that it is the first attribute.

        List<AttributeDescriptor> attributes = schema
        GeometryType geomType = null;
        List<AttributeDescriptor> attribs = new ArrayList<AttributeDescriptor>();
        for (AttributeDescriptor attrib : attributes) {
            AttributeType type = attrib.getType();
            if (type instanceof GeometryType) {
                geomType = (GeometryType) type;

            } else {

        GeometryTypeImpl gt = new GeometryTypeImpl(
                new NameImpl("the_geom"), geomType.getBinding(),
                geomType.isIdentified(), geomType.isAbstract(),
                geomType.getRestrictions(), geomType.getSuper(),

        GeometryDescriptor geomDesc = new GeometryDescriptorImpl(
                gt, new NameImpl("the_geom"),
                geom.getMinOccurs(), geom.getMaxOccurs(),
                geom.isNillable(), geom.getDefaultValue());

        attribs.add(0, geomDesc);

        SimpleFeatureType shpType = new SimpleFeatureTypeImpl(
                schema.getName(), attribs, geomDesc,
                schema.isAbstract(), schema.getRestrictions(),
                schema.getSuper(), schema.getDescription());


        if (featureSource instanceof SimpleFeatureStore) {
            SimpleFeatureStore featureStore = (SimpleFeatureStore) featureSource;

            List<SimpleFeature> feats = new ArrayList<SimpleFeature>();

            FeatureIterator<SimpleFeature> features2 = features
            while (features2.hasNext()) {
                SimpleFeature f = features2.next();
                SimpleFeature reType = SimpleFeatureBuilder
                        .build(shpType, f.getAttributes(), "");

            SimpleFeatureCollection collection = new ListFeatureCollection(
                    shpType, feats);

            try {
                List<FeatureId> ids = featureStore
            } catch (Exception problem) {
            } finally {
            return true;
        } else {
            System.err.println("ShapefileStore not writable");
            return false;
    } catch (IOException e) {
    return false;

There is a full working example at https://github.com/ianturton/geotools-cookbook/tree/master/modules/output/src/main/java/org/ianturton/cookbook/output (including the pom file to sort out the dependencies)