CSIP_Read_AND_SPLIT.java [src/java/methods] Revision: default  Date:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package methods;

import com.vividsolutions.jts.geom.*;

import com.vividsolutions.jts.io.WKTReader;

import csip.SessionLogger;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import lamps.CSIP_Const;

import org.geotools.data.DataStore;
import org.geotools.data.FeatureSource;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.NameImpl;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.MultiCurve;
import org.geotools.kml.v22.KML;
import org.geotools.kml.v22.KMLConfiguration;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.xml.Encoder;
import org.opengis.feature.Property;

import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.FeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.feature.type.Name;
import org.opengis.feature.type.PropertyDescriptor;
import org.opengis.geometry.aggregate.MultiSurface;
import org.opengis.geometry.primitive.Curve;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CRSAuthorityFactory;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author hokipka
 */
public class CSIP_Read_AND_SPLIT {

    //LMAPS vector input data reading with extend generating
    /**
     *
     * @param hru_url
     * @param outputDir
     * @param partitionSize
     * @param Count_Polys
     * @param avg_Area
     * @param LOG
     * @return
     * @throws Exception
     */
    public static Integer URL_Read_Geometry_File_new(URL hru_url, File outputDir, Integer partitionSize, List Count_Polys, List avg_Area, SessionLogger LOG) throws Exception {

        List<Geometry> Input_Geometries = new ArrayList<>();

        CoordinateReferenceSystem srcCRS = null;
        FeatureCollection featureCollection = null;

        SimpleFeatureCollection collection = null;

        CRSAuthorityFactory factory = CRS.getAuthorityFactory(true);
        CoordinateReferenceSystem kmlCRS = CRS.parseWKT(CSIP_Const.WKT_KML);

        List<SimpleFeature> list = new ArrayList<>();
        List<SimpleFeature> list2 = new ArrayList<>();
        List<Double> list3 = new ArrayList<>();
        SimpleFeatureType TYPE = null;

        File orgFileName = new File(hru_url.toURI());

        //shape file detection
        if (hru_url.toURI().toString().endsWith(".shp")) {

            LOG.info(" .shp File");
            CoordinateReferenceSystem targetCRS = CRS.parseWKT(CSIP_Const.WKT_CooSyst);
            File dir = new File(hru_url.toURI());

            //shapefile reading and original coodinates system detection
            FileDataStore dataStore = FileDataStoreFinder.getDataStore(dir);
            FeatureSource shapefileSource = dataStore.getFeatureSource();
            FeatureType schema = shapefileSource.getSchema();
            srcCRS = schema.getCoordinateReferenceSystem();

            MathTransform transform = CRS.findMathTransform(srcCRS, targetCRS, true);

            featureCollection = (FeatureCollection) featureCollectionFromShapefile(hru_url);
            int number_polys = featureCollection.size();

            try (FeatureIterator iterator = featureCollection.features()) {
                //loop over each feature/geometry/polygon to get the extend coordinates
                int o = 0;
                while (iterator.hasNext() && o < number_polys) {
                    SimpleFeature feature = (SimpleFeature) iterator.next();

                    Geometry geometry = (Geometry) feature.getDefaultGeometry();
                    Geometry targetGeometry = JTS.transform(geometry, transform);

                    if (!targetGeometry.isValid()) {
                        targetGeometry = targetGeometry.convexHull();
                    }

                    int last = targetGeometry.getCoordinates().length - 1;
                    if (!targetGeometry.getCoordinates()[0].equals(targetGeometry.getCoordinates()[last])) {
                        targetGeometry = targetGeometry.convexHull();
                    }

                    Geometry kmlGeometry = targetGeometry;
                    MathTransform kmltransform = CRS.findMathTransform(targetCRS, kmlCRS, true);
                    kmlGeometry = JTS.transform(targetGeometry, kmltransform);

                    //TYPE = createFeatureType(feature.getProperties(), kmlGeometry, "" + o, CRS.parseWKT(CSIP_Const.WKT_KML));
                    TYPE = createFeatureType(kmlGeometry, "" + o, CRS.parseWKT(CSIP_Const.WKT_KML));
                    //SimpleFeature simpfeat = createFeature("" + o, kmlGeometry, TYPE, feature.getProperties());
                    SimpleFeature simpfeat = createFeature("" + o, kmlGeometry, TYPE);
                    list.add(simpfeat);
                    list2.add(feature);
                    list3.add((targetGeometry.getArea() / 1000000));

                    Input_Geometries.add(targetGeometry);
                    o++;
                }
            }
        }

        if (hru_url.toURI().toString().endsWith(".kmz")) {
            LOG.info(" .kmz File");
            File ff = new File(outputDir, "kmztokml.kml");
            OutputStream out = new FileOutputStream(ff);
            FileInputStream fin = new FileInputStream(hru_url.getPath());
            BufferedInputStream bin = new BufferedInputStream(fin);
            ZipInputStream zin = new ZipInputStream(bin);
            ZipEntry ze = null;
            while ((ze = zin.getNextEntry()) != null) {
                if (ze.getName().equals("doc.kml")) {
                    byte[] buffer = new byte[8192];
                    int len;
                    while ((len = zin.read(buffer)) != -1) {
                        out.write(buffer, 0, len);
                    }
                    out.close();
                    break;
                }
            }
            hru_url = ff.toURI().toURL();
            fin.close();
            bin.close();
            zin.close();
        }

        if (hru_url.toURI().toString().endsWith(".kml")) {
            LOG.info(" .kml File");

            srcCRS = CRS.parseWKT(CSIP_Const.WKT_KML);

            WKTReader reader = new WKTReader();

            CoordinateReferenceSystem targetCRS = CRS.parseWKT(CSIP_Const.WKT_CooSyst);
            MathTransform transform = CRS.findMathTransform(srcCRS, targetCRS, true);

            try (InputStream isn = new FileInputStream(new File(hru_url.toURI()))) {
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(isn);
                doc.getDocumentElement().normalize();

                NodeList PlacemarkList = doc.getElementsByTagName("Placemark");

                for (int i = 0; i < PlacemarkList.getLength(); i++) {
                    Node n = PlacemarkList.item(i);
                    if (n.getNodeType() == Node.ELEMENT_NODE) {
                        Element eElement = (Element) n.getChildNodes();
                        NodeList Place_coords = eElement.getElementsByTagName("coordinates");

                        if (Place_coords.getLength() > 1) {
                            Geometry all = null;
                            for (int j = 0; j < Place_coords.getLength(); j++) {

                                String[] coords = Place_coords.item(j).getTextContent().trim().split(" ");
                                String comma_changed = "";

                                for (int ai = 0; ai < coords.length; ai++) {
                                    String[] each_coords = coords[ai].trim().split(",");

                                    comma_changed = comma_changed + each_coords[0] + " " + each_coords[1] + ",";
                                    if (coords.length - 1 == ai) {
                                        comma_changed = comma_changed + each_coords[0] + " " + each_coords[1];
                                    }
                                }
                                Geometry tShape = reader.read("POLYGON((" + comma_changed + "))");
                                Geometry targetGeometry = JTS.transform(tShape, transform);

                                if (all == null) {
                                    all = targetGeometry;
                                } else {
                                    all = all.union(targetGeometry);
                                }
                                if (!all.isValid()) {
                                    all = all.convexHull();
                                }
                            }
                            int last = all.getCoordinates().length - 1;
                            if (!all.getCoordinates()[0].equals(all.getCoordinates()[last])) {
                                all = all.convexHull();
                            }

                            Geometry kmlGeometry = all;
                            MathTransform kmltransform = CRS.findMathTransform(targetCRS, kmlCRS, true);
                            kmlGeometry = JTS.transform(all, kmltransform);

                            //TYPE = createFeatureType(feature.getProperties(), kmlGeometry, "" + o, CRS.parseWKT(CSIP_Const.WKT_KML));
                            TYPE = createFeatureType(kmlGeometry, "" + i, CRS.parseWKT(CSIP_Const.WKT_KML));
                            //SimpleFeature simpfeat = createFeature("" + o, kmlGeometry, TYPE, feature.getProperties());
                            SimpleFeature simpfeat = createFeature("" + i, kmlGeometry, TYPE);
                            list.add(simpfeat);
                            list2.add(simpfeat);
                            list3.add((all.getArea() / 1000000));

                            Input_Geometries.add(all);

                        } else {
                            //ok placemark
                            String[] coords = Place_coords.item(0).getTextContent().trim().split(" ");

                            String comma_changed = "";

                            for (int ci = 0; ci < coords.length; ci++) {
                                String[] each_coords = coords[ci].trim().split(",");

                                comma_changed = comma_changed + each_coords[0] + " " + each_coords[1] + ",";
                                if (coords.length - 1 == ci) {
                                    comma_changed = comma_changed + each_coords[0] + " " + each_coords[1];
                                }
                            }
                            Geometry tShape = reader.read("POLYGON((" + comma_changed + "))");
                            Geometry targetGeometry = JTS.transform(tShape, transform);
                            if (!targetGeometry.isValid()) {
                                targetGeometry = targetGeometry.convexHull();
                            }

                            int last = targetGeometry.getCoordinates().length - 1;
                            if (!targetGeometry.getCoordinates()[0].equals(targetGeometry.getCoordinates()[last])) {
                                targetGeometry = targetGeometry.convexHull();
                            }
                            Geometry kmlGeometry = targetGeometry;
                            MathTransform kmltransform = CRS.findMathTransform(targetCRS, kmlCRS, true);
                            kmlGeometry = JTS.transform(targetGeometry, kmltransform);

                            //TYPE = createFeatureType(feature.getProperties(), kmlGeometry, "" + o, CRS.parseWKT(CSIP_Const.WKT_KML));
                            TYPE = createFeatureType(kmlGeometry, "" + i, CRS.parseWKT(CSIP_Const.WKT_KML));
                            //SimpleFeature simpfeat = createFeature("" + o, kmlGeometry, TYPE, feature.getProperties());
                            SimpleFeature simpfeat = createFeature("" + i, kmlGeometry, TYPE);
                            list.add(simpfeat);
                            list2.add(simpfeat);
                            list3.add((targetGeometry.getArea() / 1000000));

                            Input_Geometries.add(targetGeometry);
                        }
                    }
                }
            }
        }

        if (hru_url.toURI().toString().endsWith(".geojson")) {
            LOG.info(" .geojson File");
            try (InputStream isn = new FileInputStream(new File(hru_url.toURI()))) {
                srcCRS = factory.createCoordinateReferenceSystem("EPSG:4326");

                CoordinateReferenceSystem targetCRS = CRS.parseWKT(CSIP_Const.WKT_CooSyst);
                MathTransform transform = CRS.findMathTransform(srcCRS, targetCRS, true);

                FeatureJSON fj = new FeatureJSON();
                FeatureIterator<SimpleFeature> features = fj.streamFeatureCollection(isn);

                while (features.hasNext()) {
                    SimpleFeature feature = (SimpleFeature) features.next();
                    Geometry geometry = (Geometry) feature.getDefaultGeometry();
                    Geometry targetGeometry = JTS.transform(geometry, transform);
                    if (!targetGeometry.isValid()) {
                        targetGeometry = targetGeometry.convexHull();
                    }

                    int last = targetGeometry.getCoordinates().length - 1;
                    if (!targetGeometry.getCoordinates()[0].equals(targetGeometry.getCoordinates()[last])) {
                        targetGeometry = targetGeometry.convexHull();
                    }
                    Input_Geometries.add(targetGeometry);
                }
                features.close();
            }

        }

        Input_Geometries.clear();

        String fileName = orgFileName.getName();
        fileName = fileName.substring(0, fileName.lastIndexOf(".") + 1);
        fileName = fileName.replace(".", "");

        String header = "LAMPS_Single_Run_ID,";
        for (int x = 1; x < list2.get(0).getAttributeCount(); x++) {
            header = header + list2.get(0).getFeatureType().getAttributeDescriptors().get(x).getLocalName() + ",";
        }

        List<List<SimpleFeature>> partitions_simpfeatures = new LinkedList<>();
        List<List<SimpleFeature>> partitions_features = new LinkedList<>();

        LOG.info(" Multi_Run Value " + partitionSize);
        LOG.info(" List Size " + list.size());

//        if (partitionSize < list.size()) {
//            for (int i = 0; i < list.size(); i += partitionSize) {
//                partitions_simpfeatures.add(list.subList(i, Math.min(i + partitionSize, list.size())));
//                partitions_features.add(list2.subList(i, Math.min(i + partitionSize, list2.size())));
//                number_of_parts++;
//            }
//        } else {
//            partitions_simpfeatures.add(list);
//        }
        double part_tot_area = 0;
        double tot_area = 0;
        int count_number_of_poly = 0;
        int number_of_parts = 0;

        List<SimpleFeature> area_simpfeatures = new LinkedList<>();
        List<SimpleFeature> area_features = new LinkedList<>();

        for (int i = 0; i < list.size(); i++) {
            part_tot_area += list3.get(i);

            area_simpfeatures.add(list.get(i));
            area_features.add(list2.get(i));

            count_number_of_poly++;

            if (part_tot_area >= partitionSize || i == list.size() - 1) {
                partitions_simpfeatures.add(area_simpfeatures);
                partitions_features.add(area_features);
                Count_Polys.add(new Double(count_number_of_poly));
                avg_Area.add(part_tot_area);
                LOG.info(" ============== "+i+" Total Area in km2: " + part_tot_area);
                LOG.info(" ============== "+i+" Number of Parts  : " + count_number_of_poly);

                number_of_parts++;

                part_tot_area = 0;
                count_number_of_poly = 0;
                area_simpfeatures = new LinkedList<>();
                area_features = new LinkedList<>();
            }

            tot_area += list3.get(i);
        }

        LOG.info(" Total Area in km2: " + tot_area);

        int count_i = 0;
        for (int j = 0; j < partitions_simpfeatures.size(); j++) {

            LOG.info(" In Chunk Loop " + j);
            LOG.info(" Number of Polygon " + Count_Polys.get(j));
            LOG.info(" SplitKML_" + j + "_Attributes.csv");
            LOG.info(" # of Features " + partitions_simpfeatures.get(j).size());

            PrintWriter w = new PrintWriter(new FileWriter(new File(outputDir, "SplitKML_" + j + "_Attributes.csv")));
            w.println(header);

            for (int i = 0; i < partitions_features.get(j).size(); i++) {
                //String values = single_run_id + ",";
                String values = count_i + ",";
                for (int x = 1; x < partitions_features.get(j).get(i).getAttributeCount(); x++) {
                    values = values + partitions_features.get(j).get(i).getAttribute(x).toString() + ",";
                }
                w.println(values);
                //single_run_id++;
                count_i++;
            }
            collection = new ListFeatureCollection(TYPE, partitions_simpfeatures.get(j));
            polygonToKML(outputDir, "SplitKML_" + j + "_" + fileName + ".kml", collection);

            w.close();

            try {
                zip(new File(outputDir, "SplitKML_" + j + "_" + fileName + ".kmz"), new File(outputDir, "SplitKML_" + j + "_" + fileName + ".kml"));
            } catch (IOException ex) {
            }

            try {
                File file = new File(outputDir, "SplitKML_" + j + "_" + fileName + ".kml");
                file.delete();
            } catch (Exception e) {
            }
        }

//        collection = new ListFeatureCollection(TYPE, list);
//        CSIP_READ_AND_SPLIT.polygonToKML(outputDir, "SplitKML_Full.kml", collection);
//        try {
//            zip(new File(outputDir, "SplitKML_Full.kmz"), new File(outputDir, "SplitKML_Full.kml"));
//        } catch (IOException ex) {
//        }
//        try {
//            File file = new File(outputDir, "SplitKML_Full.kml");
//            file.delete();
//        } catch (Exception e) {
//        }
//
//        LOG.info("number of entities: " + list.size() + " ");
        return number_of_parts;

    }

    /**
     *
     * @param shapefile
     * @return
     * @throws IOException
     */
    protected static FeatureCollection featureCollectionFromShapefile(URL shapefile) throws IOException {
        DataStore dataStore = new ShapefileDataStore(shapefile);
        FeatureSource featureSource = dataStore.getFeatureSource(dataStore.getTypeNames()[0]);
        dataStore.dispose();
        return featureSource.getFeatures();
    }

    protected static Geometry transformToGeo(Geometry source, CoordinateReferenceSystem srcCRS) throws FactoryException, TransformException {
        CoordinateReferenceSystem destCRS = DefaultGeographicCRS.WGS84;
        boolean lenient = true; // allow for some error due to different datums
        MathTransform transform = CRS.findMathTransform(srcCRS, destCRS, lenient);
        return JTS.transform(source, transform);
    }

    static void polygonToKML(File outputDir, String name, FeatureCollection features) throws IOException {
        try (OutputStream outputstream = new BufferedOutputStream(new FileOutputStream(new File(outputDir, name)))) {
            Encoder encoder = new Encoder(new KMLConfiguration());
            encoder.setIndenting(true);
            encoder.encode(features, KML.kml, outputstream);
            outputstream.close();
        }
    }

    public static void zip(File zip, File file) throws IOException {
        ZipOutputStream zos = null;
        try {
            String name = file.getName();
            zos = new ZipOutputStream(new FileOutputStream(zip));

            ZipEntry entry = new ZipEntry(name);
            zos.putNextEntry(entry);

            FileInputStream fis = null;
            try {
                fis = new FileInputStream(file);
                byte[] byteBuffer = new byte[1024];
                int bytesRead = -1;
                while ((bytesRead = fis.read(byteBuffer)) != -1) {
                    zos.write(byteBuffer, 0, bytesRead);
                }
                zos.flush();
            } finally {
                try {
                    fis.close();
                } catch (IOException e) {
                }
            }
            zos.closeEntry();

            zos.flush();
        } finally {
            try {
                zos.close();
            } catch (IOException e) {
            }
        }
    }

    public static SimpleFeature createFeature(String id, Geometry geometry, SimpleFeatureType featureType, Collection<Property> originalAttributes) {

        if (geometry == null || geometry.isEmpty()) {
            return null;
        }

        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
        SimpleFeature feature = null;
        Collection<PropertyDescriptor> featureTypeAttributes = featureType.getDescriptors();

        Object[] newData = new Object[featureType.getDescriptors().size()];

        int i = 0;
        for (PropertyDescriptor propertyDescriptor : featureTypeAttributes) {
            for (Property originalProperty : originalAttributes) {

                if (propertyDescriptor.getName().getLocalPart().equals(originalProperty.getName().getLocalPart())) {
                    if (propertyDescriptor instanceof GeometryDescriptor) {
                        newData[i] = geometry;
                    } else {
                        newData[i] = originalProperty.getValue();
                    }
                }
            }

            if (propertyDescriptor instanceof GeometryDescriptor) {
                if (geometry.getGeometryType().equals("Point")) {
                    Point[] points = new Point[1];
                    points[0] = (Point) geometry;
                    newData[i] = geometry.getFactory().createMultiPoint(points);
                } else if (geometry.getGeometryType().equals("LineString")) {
                    LineString[] lineString = new LineString[1];
                    lineString[0] = (LineString) geometry;
                    newData[i] = geometry.getFactory().createMultiLineString(lineString);
                } else if (geometry.getGeometryType().equals("Polygon")) {
                    Polygon[] polygons = new Polygon[1];
                    polygons[0] = (Polygon) geometry;
                    newData[i] = geometry.getFactory().createMultiPolygon(polygons);
                } else {
                    //newData[i] = geometry;
                    Polygon[] polygons = new Polygon[geometry.getNumGeometries()];
                    for (int j = 0; j < geometry.getNumGeometries(); j++) {
                        polygons[j] = (Polygon) geometry.getGeometryN(j);
                    }
                    newData[i] = geometry.getFactory().createMultiPolygon(polygons);
                }
            }
            i++;
        }

        feature = featureBuilder.buildFeature(id, newData);

        return feature;
    }

    public static SimpleFeatureType createFeatureType(Collection<Property> attributes, Geometry newGeometry, String uuid, CoordinateReferenceSystem coordinateReferenceSystem) throws FactoryException {
        String namespace = "http://www.52north.org/" + uuid;

        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        if (coordinateReferenceSystem == null) {
            coordinateReferenceSystem = CRS.parseWKT(CSIP_Const.WKT_KML);
        }
        typeBuilder.setCRS(coordinateReferenceSystem);
        typeBuilder.setNamespaceURI(namespace);
        Name nameType = new NameImpl(namespace, "Feature-" + uuid);
        typeBuilder.setName(nameType);

        for (Property property : attributes) {
            if (property.getValue() != null) {
                String name = property.getName().getLocalPart();
                Class<?> binding = property.getType().getBinding();
                if (binding.equals(Envelope.class)) {
                    continue;
                }
                if ((binding.equals(Geometry.class)
                        || binding.equals(GeometryCollection.class)
                        || binding.equals(MultiCurve.class)
                        || binding.equals(MultiLineString.class)
                        || binding.equals(Curve.class)
                        || binding.equals(MultiPoint.class)
                        || binding.equals(MultiPolygon.class)
                        || binding.equals(MultiSurface.class)
                        || binding.equals(LineString.class)
                        || binding.equals(Point.class)
                        || binding.equals(LineString.class)
                        || binding.equals(Polygon.class))
                        && !name.equals("location")) {

                    if (newGeometry.getClass().equals(Point.class) && (!name.equals("location"))) {
                        typeBuilder.add("GEOMETRY", MultiPoint.class);
                    } else if (newGeometry.getClass().equals(LineString.class) && (!name.equals("location"))) {

                        typeBuilder.add("GEOMETRY", MultiLineString.class);
                    } else if (newGeometry.getClass().equals(Polygon.class) && (!name.equals("location"))) {

                        typeBuilder.add("GEOMETRY", Polygon.class);
                    } else if (!binding.equals(Object.class)) {
                        //typeBuilder.add("GEOMETRY", newGeometry.getClass());
                        typeBuilder.add("GEOMETRY", Polygon.class);
                    }
                } else {
                    if (!name.equals("location") && binding.equals(Object.class)) {
                        try {
                            Geometry g = (Geometry) property.getValue();
                            if (g.getClass().equals(Point.class) && (!name.equals("location"))) {
                                typeBuilder.add("GEOMETRY", MultiPoint.class);
                            } else if (g.getClass().equals(LineString.class) && (!name.equals("location"))) {

                                typeBuilder.add("GEOMETRY", MultiLineString.class);
                            } else if (g.getClass().equals(Polygon.class) && (!name.equals("location"))) {

                                typeBuilder.add("GEOMETRY", Polygon.class);
                            } else {
                                //typeBuilder.add("GEOMETRY", g.getClass());
                                typeBuilder.add("GEOMETRY", Polygon.class);
                            }

                        } catch (ClassCastException e) {

                        }
                    } else if (!name.equals("location")) {
                        typeBuilder.add(name, binding);
                    }
                }
            }

        }

        SimpleFeatureType featureType;

        featureType = typeBuilder.buildFeatureType();
        return featureType;
    }

    public static SimpleFeature createFeature(String id, Geometry geometry, SimpleFeatureType featureType) {

        if (geometry == null || geometry.isEmpty()) {
            return null;
        }

        SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(featureType);
        SimpleFeature feature = null;

        Object[] newData = new Object[featureType.getDescriptors().size()];

        int i = 0;

        if (geometry.getGeometryType().equals("Point")) {
            Point[] points = new Point[1];
            points[0] = (Point) geometry;
            newData[i] = geometry.getFactory().createMultiPoint(points);
        } else if (geometry.getGeometryType().equals("LineString")) {
            LineString[] lineString = new LineString[1];
            lineString[0] = (LineString) geometry;
            newData[i] = geometry.getFactory().createMultiLineString(lineString);
        } else if (geometry.getGeometryType().equals("Polygon")) {
            Polygon[] polygons = new Polygon[1];
            polygons[0] = (Polygon) geometry;
            newData[i] = geometry.getFactory().createMultiPolygon(polygons);
        } else {
            newData[i] = geometry;
        }

        feature = featureBuilder.buildFeature(id, newData);

        return feature;
    }

    public static SimpleFeatureType createFeatureType(Geometry newGeometry, String uuid, CoordinateReferenceSystem coordinateReferenceSystem) throws FactoryException {
        String namespace = "http://www.52north.org/" + uuid;

        SimpleFeatureTypeBuilder typeBuilder = new SimpleFeatureTypeBuilder();
        if (coordinateReferenceSystem == null) {
            coordinateReferenceSystem = CRS.parseWKT(CSIP_Const.WKT_KML);
        }
        typeBuilder.setCRS(coordinateReferenceSystem);
        typeBuilder.setNamespaceURI(namespace);
        Name nameType = new NameImpl(namespace, "Feature-" + uuid);
        typeBuilder.setName(nameType);

        typeBuilder.add("GEOMETRY", Polygon.class);

        SimpleFeatureType featureType;

        featureType = typeBuilder.buildFeatureType();
        return featureType;
    }

    public static boolean ALL_CHUNCK_FILES(File outputDir, Integer multi_run, SessionLogger LOG) throws Exception {

        File folder = new File(outputDir.getPath());
        File[] listOfFiles = folder.listFiles();

        for (int i = 0; i < listOfFiles.length; i++) {
            if (listOfFiles[i].isFile()) {
                System.out.println("File " + listOfFiles[i].getName());
            } else if (listOfFiles[i].isDirectory()) {
                System.out.println("Directory " + listOfFiles[i].getName());
            }
        }
        return true;
    }

    public static void mergeFiles(File[] files, File mergedFile) {

        FileWriter fstream = null;
        BufferedWriter out = null;
        try {
            fstream = new FileWriter(mergedFile, true);
            out = new BufferedWriter(fstream);
        } catch (IOException e1) {
        }

        for (File f : files) {
            System.out.println("merging: " + f.getName());
            FileInputStream fis;
            try {
                fis = new FileInputStream(f);
                try (BufferedReader in = new BufferedReader(new InputStreamReader(fis))) {
                    String aLine;
                    while ((aLine = in.readLine()) != null) {
                        out.write(aLine);
                        out.newLine();
                    }
                }
            } catch (IOException e) {
            }
        }

        try {
            out.close();
        } catch (IOException e) {
        }
    }
}