public File writeShapefile(FeatureCollection<SimpleFeatureType, SimpleFeature> src)
      throws IOException {
    SimpleFeatureType srcSchema = src.getSchema();

    // shapeSchema
    SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
    builder.init(srcSchema);
    builder.add(ORIG_FID_FIELD, String.class);
    builder.add(TIMESTAMP_FIELD, String.class);
    final SimpleFeatureType shapeSchema = builder.buildFeatureType();

    // retyped collection
    final SimpleFeatureBuilder fb = new SimpleFeatureBuilder(shapeSchema);
    final String timestamp = timestampFormat().format(new Date());
    FeatureCollection<SimpleFeatureType, SimpleFeature> retyped =
        new RetypingFeatureCollection<SimpleFeatureType, SimpleFeature>(src, shapeSchema) {

          protected SimpleFeature retype(SimpleFeature feature) {
            for (AttributeDescriptor attrType : shapeSchema.getAttributeDescriptors()) {
              Object value = feature.getAttribute(attrType.getName());
              fb.set(attrType.getName(), value);
            }
            fb.set(ORIG_FID_FIELD, feature.getID());
            // FIXME this should be the proper global timestamp from FeatureStateTracker;
            // otherwise each and every re-generate of the shapfile causes (wrong) exceptions
            // on save; see ShapefileContainer for more info
            fb.set(TIMESTAMP_FIELD, timestamp);
            return fb.buildFeature(feature.getID());
          }
        };

    ShapefileDataStoreFactory shapeFactory = new ShapefileDataStoreFactory();

    Map<String, Serializable> params = new HashMap<String, Serializable>();
    params.put("url", newFile.toURI().toURL());
    params.put("create spatial index", Boolean.TRUE);

    ShapefileDataStore shapeDs = (ShapefileDataStore) shapeFactory.createNewDataStore(params);
    shapeDs.createSchema(shapeSchema);

    // shapeDs.forceSchemaCRS(DefaultGeographicCRS.WGS84);
    // shapeDs.setStringCharset( )

    // write shapefile
    //        Transaction tx = new DefaultTransaction( "create" );

    String typeName = shapeDs.getTypeNames()[0];
    FeatureStore<SimpleFeatureType, SimpleFeature> shapeFs =
        (FeatureStore<SimpleFeatureType, SimpleFeature>) shapeDs.getFeatureSource(typeName);

    // doing this without tx saves a LOT of memory; and tx is not
    // strictly necessary here
    //        shapeFs.setTransaction( tx );
    //        try {
    shapeFs.addFeatures(retyped);
    //            tx.commit();
    //        }
    //        catch (IOException e) {
    //            tx.rollback();
    //            throw e;
    //        }
    //        finally {
    //            tx.close();
    //        }

    return newFile;
  }
  public KPTShapefileWriter(String directory, String fileName) {
    this.directory = directory;
    this.fileName = fileName;
    crs = DefaultGeographicCRS.WGS84;

    try {
      TYPE =
          DataUtilities.createType(
              "Location",
              "" //
                  + "cadastral_number:String," // <- a String attribute
                  + "state:String," // a number attribute
                  + "date_created:String," //
                  + "area:String," //
                  + "area_unit:String," //
                  + "name:String," //
                  + "location_in_bounds:String," //
                  + "address_okato:String," //
                  + "address_kladr:String," //
                  + "address_region:String," //
                  + "address_district_name:String," //
                  + "address_district_type:String," //
                  + "address_city_name:String," //
                  + "address_city_type:String," //
                  + "address_locality_name:String," //
                  + "address_locality_type:String," //
                  + "address_street_name:String," //
                  + "address_street_type:String," //
                  + "address_level_1_type:String," //
                  + "address_level_1_value:String," //
                  + "addess_note:String," //
                  + "category:String," //
                  + "utilization:String," //
                  + "utilization_by_doc:String," //
                  + "cadastral_cost:String," //
                  + "cadastral_unit:String," //
                  + "location:Polygon:srid=4326" // <- the geometry attribute: Point type
              );
    } catch (SchemaException e) {
      e.printStackTrace();
    }

    File newFile =
        new File(directory + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + ".shp");

    ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();

    Map<String, Serializable> params = new HashMap<>();
    try {
      params.put("url", newFile.toURI().toURL());
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
    params.put("create spatial index", Boolean.TRUE);

    try {
      newDataStore = (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
    } catch (IOException e) {
      e.printStackTrace();
    }
    try {
      newDataStore.createSchema(TYPE);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  public void dumpBuffer(List<OSMEdge> edges, String filename) throws SchemaException, IOException {

    final SimpleFeatureType TYPE =
        DataUtilities.createType(
            "route",
            "location:LineString:srid=4326,"
                + // <- the geometry attribute: Polyline type
                "name:String,"
                + // <- a String attribute
                "number:Integer" // a number attribute
            );

    // 1. build a feature
    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(TYPE);
    ArrayList<SimpleFeature> features = new ArrayList<SimpleFeature>();

    Iterator<OSMEdge> iter = edges.iterator();
    while (iter.hasNext()) {
      OSMEdge o = iter.next();
      SimpleFeature feature = featureBuilder.buildFeature(null);
      feature.setDefaultGeometry(o.getGeometry());
      features.add(feature);
    }
    SimpleFeatureCollection collection =
        new ListFeatureCollection(TYPE, features); // FeatureCollections.newCollection();

    logger.info("Writing to shapefile " + filename);
    File newFile = new File(filename);
    // File newFile = getNewShapeFile(file);

    ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();

    Map<String, Serializable> params = new HashMap<String, Serializable>();
    params.put("url", newFile.toURI().toURL());
    params.put("create spatial index", Boolean.TRUE);

    ShapefileDataStore newDataStore =
        (ShapefileDataStore) dataStoreFactory.createNewDataStore(params);
    newDataStore.createSchema(TYPE);

    // You can comment out this line if you are using the createFeatureType method (at end of
    // class file) rather than DataUtilities.createType
    newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84);

    Transaction transaction = new DefaultTransaction("create");

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

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

      featureStore.setTransaction(transaction);
      try {
        featureStore.addFeatures(collection);
        transaction.commit();
      } catch (Exception problem) {
        problem.printStackTrace();
        transaction.rollback();
      } finally {
        transaction.close();
      }
      // System.exit(0); // success!
    } else {
      logger.error(typeName + " does not support read/write access");
      // System.exit(1);	// exit program with status 1 (error)
    }
  }