I've just discovered the GeoTools tutorial to generate a Shapefile from a CSV containing a list of cities. I've managed to make it work but when I try to create a new Geography in SpaceStat, importing the newly created Shapefile, I get an error that says:

Import failed: No valid objects were found

I tried to take a look at SpaceStat docs but I didn't find anything about this error. Are there particular requirements for the Shapefile to be imported in SpaceStat?

Here's the code I use to generate the shapefile.

public class Csv2Shape {

SimpleFeatureType TYPE = null;

public Csv2Shape() {

    try {
        TYPE = DataUtilities.createType("Location", "location:Point:srid=4326," + "name:String," + "number:Integer");
        System.out.println("Type init: "+ TYPE);
    } catch (SchemaException e) {
        // TODO Auto-generated catch block


public static void main(String[] args) throws Exception {

    File file = JFileDataStoreChooser.showOpenFile("csv", null);
    if (file == null) {
    Csv2Shape csvshape = new Csv2Shape();

     * We create a FeatureCollection into which we will put each Feature created from a record
     * in the input csv data file
    List<SimpleFeature> collection = new ArrayList<SimpleFeature>();
     * GeometryFactory will be used to create the geometry attribute of each feature (a Point
     * object for the location)
    GeometryFactory geometryFactory = new GeometryFactory();

    SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(csvshape.TYPE);

    BufferedReader reader = new BufferedReader(new FileReader(file));
    try {
        /* First line of the data file is the header */
        String line = reader.readLine();
        System.out.println("Header: " + line);

        for (line = reader.readLine(); line != null; line = reader.readLine()) {
            if (line.trim().length() > 0) { // skip blank lines
                String tokens[] = line.split("\\,");

                double latitude = Double.parseDouble(tokens[0]);
                double longitude = Double.parseDouble(tokens[1]);
                String name = tokens[2].trim();
                int number = Integer.parseInt(tokens[3].trim());

                /* Longitude (= x coord) first ! */
                Point point = geometryFactory.createPoint(new Coordinate(longitude, latitude));

                SimpleFeature feature = featureBuilder.buildFeature(null);
    } finally {

    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);

     * You can comment out this line if you are using the createFeatureType method (at end of
     * class file) rather than DataUtilities.createType

     * Write the features to the shapefile
    Transaction transaction = new DefaultTransaction("create");

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

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


        try {
            SimpleFeatureCollection sfcollection = DataUtilities.collection(collection);

        } catch (Exception problem) {

        } finally {
        System.exit(0); // success!
    } else {
        System.out.println(typeName + " does not support read/write access");


 * Prompt the user for the name and path to use for the output shapefile
 * @param csvFile
 *            the input csv file used to create a default shapefile name
 * @return name and path for the shapefile as a new File object
private static File getNewShapeFile(File csvFile) {
    String path = csvFile.getAbsolutePath();
    String newPath = path.substring(0, path.length() - 4) + ".shp";

    JFileDataStoreChooser chooser = new JFileDataStoreChooser("shp");
    chooser.setDialogTitle("Save shapefile");
    chooser.setSelectedFile(new File(newPath));

    int returnVal = chooser.showSaveDialog(null);

    if (returnVal != JFileDataStoreChooser.APPROVE_OPTION) {
        // the user cancelled the dialog

    File newFile = chooser.getSelectedFile();
    if (newFile.equals(csvFile)) {
        System.out.println("Error: cannot replace " + csvFile);

    return newFile;

  • 1
    can you open the shapefile in any other tools (QGis)? – Ian Turton Jul 25 '14 at 9:05
  • I tried to open it with QGIS but it seems to be empty even if the associated dbf seems to contain the correct data. Any idea? – Daniela Mogini Jul 25 '14 at 10:11
  • in that case we need to see the GeoTools code you are using? – Ian Turton Jul 25 '14 at 11:19

You have been caught out by a (recent) update to the shapefile read/writer code. The geometry field of a shapefile must be called the_geom (if you check http://docs.geotools.org/latest/userguide/tutorial/feature/csv2shp.html you'll see it is there). This is an attempt to fit in with how other programs interpret the ShapeFile specification (I believe).

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