3

I am trying to convert my shapefiles to CSV through a batch processing in Java using Geotools. The problem is I have more than 500 shapefiles (point features). The code is working fine for a small number of shp files. But when I am iterating the process over a large dataset (number of files), some of the files are not written and of 0 KB. I have no clue why this is happening.

I want all the files to be converted from shp to CSV.

Here is my Java code-

// shp2csv conversion
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.opengis.feature.simple.SimpleFeature;

public class GeoOpen
{


private static SimpleFeatureIterator simpleFeatureIterator;
static FileDataStore store ;
static String ID="";



public  static boolean openShapeFile(File srcfname) throws Exception



{
    String filename=srcfname.getAbsolutePath(); 
    File dataFile = new File(filename);
    dataFile.setReadOnly();
    store = FileDataStoreFinder.getDataStore(dataFile);
   // ShapefileDataStore store = new ShapefileDataStore(dataFile.toURL());

    SimpleFeatureSource source = store.getFeatureSource();
    SimpleFeatureCollection featureCollection = source.getFeatures();
    simpleFeatureIterator = featureCollection.features();
    return true;
}
public  static boolean iterate(File srcfname, String dest_path)
{
    File dest_file=srcfname;
    
    String dest_filename=GeoOpen.getFileNameWithoutExtension(dest_file)+".csv";
    
    try{
        BufferedWriter  bw=new BufferedWriter (new FileWriter(dest_path+dest_filename));
   
   bw.write("ID"+","+ "date"+","+"tstamp"+","+"X_prj"+","+"Y_prj"+","+"NEAR_FID"+","+"NEAR_DIST");
    while(simpleFeatureIterator.hasNext())
    {

        SimpleFeature f = simpleFeatureIterator.next();

     //  System.out.println(""+f.getID()+" ,"+f.getAttribute(1)+", "+f.getAttribute(2)); //ID, field 1: lat, field 2: long
       
   //writing in a CSV file
       bw.write("\n");
      
       int index = f.getID().lastIndexOf('.');
       ID=f.getID().substring(index+1); //get only the ID //by default ID comes with filename.ID format when getID() method called
      bw.write(Integer.parseInt(ID)+" ,"+f.getAttribute(1).toString()+", "+f.getAttribute(2)+","+f.getAttribute(3)+","+f.getAttribute(4)+","+f.getAttribute(5)+","+f.getAttribute(6));
  
    }
    
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    catch(Exception ex){
        ex.printStackTrace();
       
    }
    finally{
        simpleFeatureIterator.close();
        store.dispose();
      }

    return true;
}

public static String getFileNameWithoutExtension(File f)
{
    String s="";
    int index = f.getName().lastIndexOf('.');
    //System.out.println (index);
  if (index>0&& index <= f.getName().length() - 2 ) 
  {
      s= f.getName().substring(0, index);
  }
  return s;
}
public static void main(String[] args) {
    try {
       
      String dest_path="C:\\ArcGIS test data\\commonfiles csv\\001\\nr_train\\";
              
      File src_dir= new File ("C:\\ArcGIS test data\\commonfiles prj\\001\\nearTrain");
            
      File [] file_nr = src_dir.listFiles();  //array containing files from nearRoad
        for (int i=0; i<file_nr.length; i++)  //near road
        {
            if (file_nr[i].getName().endsWith(".shp"))
            {
                GeoOpen.openShapeFile(file_nr[i]);
                GeoOpen.iterate(file_nr[i], dest_path );
            }
        }

    } catch (Exception e) {
        
        e.printStackTrace();
    }
}
}
2
  • 2
    Why bother program and debugging a single-purpose tool when something similar already exists? E.g. ogr2ogr -f CSV -lco GEOMETRY=AS_XY points.csv points.shp made batchable using something like this.
    – Mike T
    Commented Aug 26, 2014 at 4:08
  • 1
    You'll need to look at the files that fail and see if there is some error message printed when you process them. You may need to add some error messages to your code too.
    – Ian Turton
    Commented Aug 26, 2014 at 7:46

2 Answers 2

6

I had same problem. I solved the problem.

My solution:

StringBuffer tmpStr = new StringBuffer();
tmpStr.append("ID,date,tstamp,X_prj,Y_prj,NEAR_FID,NEAR_DIST\n");

SimpleFeature f = null;
int index = 0;
String ID = null;

while(simpleFeatureIterator.hasNext()){
        f = simpleFeatureIterator.next();
        index = f.getID().lastIndexOf('.');
        ID = f.getID().substring(index+1);

        tmpStr.append(Integer.toString(Integer.parseInt(ID))).append(",")
                .append(f.getAttribute(1).toString()).append(",")
                .append(f.getAttribute(2).toString()).append(",")
                .append(f.getAttribute(3).toString()).append(",")
                .append(f.getAttribute(4).toString()).append(",")
                .append(f.getAttribute(5).toString()).append(",")
                .append(f.getAttribute(6).toString()).append("\n");
}

BufferedWriter bw = new BufferedWriter (new FileWriter(dest_path+dest_filename));
bw.write(tmpStr.toString());
bw.close();

-1

The easiest way to do this is to use the GeoTools CSV datastore, which has several advantages the most obvious being there is no need to store the whole dataset in memory, the next that this way you can pick a different output store if you decide to change your storage method with out having to change a lot of code.

File inFile = new File("/home/ian/Data/states/states.shp");
File outFile = new File("states.csv");
outFile.createNewFile();
// Read
DataStore inputDataStore = DataStoreFinder.getDataStore(
        Collections.singletonMap("url", URLs.fileToUrl(inFile)));

String inputTypeName = inputDataStore.getTypeNames()[0];
SimpleFeatureType inputType = inputDataStore.getSchema(inputTypeName);

FeatureSource<SimpleFeatureType, SimpleFeature>
        source = inputDataStore.getFeatureSource(inputTypeName);

FeatureCollection<SimpleFeatureType, SimpleFeature>
        inputFeatureCollection = source.getFeatures();

// Write
FileDataStore newDataStore = FileDataStoreFinder.getDataStore(outFile);

newDataStore.createSchema(inputType);
String typeName = newDataStore.getTypeNames()[0];

SimpleFeatureStore featureStore =
        (SimpleFeatureStore) newDataStore.getFeatureSource(typeName);

featureStore.addFeatures(inputFeatureCollection);

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.