Create a shapefile from a text file with XY values
arcgissamples\geodatabase\CreateShapefile.java
/* Copyright 2010 ESRI
* 
* All rights reserved under the copyright laws of the United States
* and applicable international laws, treaties, and conventions.
* 
* You may freely redistribute and use this sample code, with or
* without modification, provided you include the original copyright
* notice and use restrictions.
* 
* See the use restrictions.
* 
*/
package arcgissamples.geodatabase;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import com.esri.arcgis.datasourcesfile.ShapefileWorkspaceFactory;
import com.esri.arcgis.geodatabase.Feature;
import com.esri.arcgis.geodatabase.FeatureClass;
import com.esri.arcgis.geodatabase.FeatureCursor;
import com.esri.arcgis.geodatabase.Field;
import com.esri.arcgis.geodatabase.Fields;
import com.esri.arcgis.geodatabase.GeometryDef;
import com.esri.arcgis.geodatabase.Workspace;
import com.esri.arcgis.geodatabase.esriFeatureType;
import com.esri.arcgis.geodatabase.esriFieldType;
import com.esri.arcgis.geometry.IGeographicCoordinateSystem;
import com.esri.arcgis.geometry.Point;
import com.esri.arcgis.geometry.SpatialReferenceEnvironment;
import com.esri.arcgis.geometry.esriGeometryType;
import com.esri.arcgis.geometry.esriSRGeoCSType;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.Cleaner;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;

public class CreateShapefile {

  public CreateShapefile(){
    
  }
  
  /**
   * Main Method - The console application entry point.
   * 
   * @param args String[] Command line argument
   */
  public static void main(String[] args) {
    System.out.println("Starting CreateShapefile - An ArcObjects SDK Developer Sample");
    
    try{
      //Initialize engine console application
      EngineInitializer.initializeEngine();
      
      //Initialize ArcGIS license
      AoInitialize aoInit = new AoInitialize();
      initializeArcGISLicenses(aoInit);
      
      //Get DEVKITHOME Home
      String devKitHome = System.getenv("AGSDEVKITJAVA");
      
      //Data output setup
      String outPath = getOutputDir() + File.separator + "createshapefilefromtext";
      String outName = "shapefromtext.shp";
      String textFilePath = devKitHome + File.separator + "java" + File.separator + "samples"
                       + File.separator + "data" + File.separator + "text"
                       + File.separator + "texttoshape.txt";  
      boolean isFeatureBufferUsed = true;
      
      File shapefileDir = new File(outPath);
      shapefileDir.mkdir();
      
      File outShapefileFile = new File(shapefileDir, outName);
      if (outShapefileFile.exists()) {
        System.out.println("Output datafile already exists: " + outShapefileFile.getAbsolutePath());
        System.out.println("Delete it (plus .shx and .dbf files) and rerun");
        System.exit(-1);
      }
      
      File textFile = new File(textFilePath);
      if (!textFile.canRead()) {
        System.out.println("Cannot read input text file: " + textFile.getAbsolutePath());
        System.out.println("Exiting...");
        System.exit(-1);
      }

      CreateShapefile createShapefile = new CreateShapefile();
      FeatureClass featureClass = createShapefile.createShapefile(outPath, outName);
      createShapefile.addPoints(textFilePath, featureClass, isFeatureBufferUsed);
      
      System.out.println("Created " + outShapefileFile.getAbsolutePath() + " from " + textFilePath);
            
      //Ensure any ESRI libraries are unloaded in the correct order
      aoInit.shutdown();
    }catch(Exception e){
      System.out.println("Error: " + e.getMessage());
      System.out.println("Sample failed.  Exiting...");
      e.printStackTrace();
      System.exit(-1);
    }
  }

  /**
   * Checks to see if an ArcGIS Engine Runtime license or an ArcView License
   * is available. If so, then the appropriate ArcGIS License is initialized.
   * 
   * @param aoInit The AoInitialize object instantiated in the main method.
   */
  private static void initializeArcGISLicenses(AoInitialize aoInit) {
    try {
      if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeArcView) 
          == esriLicenseStatus.esriLicenseAvailable)
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeArcView);
      else{
        System.err.println("Could not initialize an Engine or ArcView license. Exiting application.");
        System.exit(-1);
      }
    } catch (Exception e) {e.printStackTrace();}
  }

  /**
   * Create a shapefile to add point features to.
   *
   * @param shapefilePath path to the shapefile being created.
   * @param shapefileName name of the shapefile being created.
   * @return FeatureClass the feature class to which points may be added.
   * @throws IOException when the shapefile cannot be created.
   */
  private FeatureClass createShapefile(String shapefilePath, String shapefileName) throws IOException {
    try {
      String geometryShapeFieldName = "Shape";
      
      // Get a feature workspace from the specified shapefile location
      ShapefileWorkspaceFactory shapefileWorkspaceFactory = new ShapefileWorkspaceFactory();
      Workspace workspace = (Workspace) shapefileWorkspaceFactory.openFromFile(shapefilePath, 0);
        
      // Create a GeometryDef object to hold geometry information
      GeometryDef geometryDef = new GeometryDef();
      geometryDef.setGeometryType(esriGeometryType.esriGeometryPoint);

      // Create spatial reference information, and add it to the geometry definition
      SpatialReferenceEnvironment spatialReferenceEnvironment = new SpatialReferenceEnvironment();
      IGeographicCoordinateSystem geographicCoordinateSystem = spatialReferenceEnvironment.createGeographicCoordinateSystem(
          esriSRGeoCSType.esriSRGeoCS_NAD1983);
      
      geometryDef.setSpatialReferenceByRef(geographicCoordinateSystem);

      // Create a geometry shape field and add the geometry definition to it.

      Field geometryShapeField = new Field();
      geometryShapeField.setName(geometryShapeFieldName);
      geometryShapeField.setType(esriFieldType.esriFieldTypeGeometry);
      geometryShapeField.setGeometryDefByRef(geometryDef);

      // Create point coordinate fields: Longitude, Latitude, and Value.
      // Note: We need not explicitly add latitude and longitude fields because
      // the shape field holds this type of data.  It is sometimes useful to
      // have these fields in the table, however.
      Field lngCoordField = new Field();
      lngCoordField.setLength(30);
      lngCoordField.setName("Longitude");
      lngCoordField.setType(esriFieldType.esriFieldTypeDouble);

      Field latCoordField = new Field();
      latCoordField.setLength(30);
      latCoordField.setName("Latitude");
      latCoordField.setType(esriFieldType.esriFieldTypeDouble);

      Field valCoordField = new Field();
      valCoordField.setLength(30);
      valCoordField.setName("Value");
      valCoordField.setType(esriFieldType.esriFieldTypeDouble);

      // Create a Fields object and add the fields to it.
      Fields fields = new Fields();
      fields.addField(lngCoordField);
      fields.addField(latCoordField);
      fields.addField(valCoordField);
      fields.addField(geometryShapeField);

      // Create a feature class defined by the shapefile name and the defined fields.
      // The creation of this feature class also causes a shapefile to be created.
      FeatureClass featureClass = new FeatureClass(workspace.createFeatureClass(shapefileName, fields, null, null,
          esriFeatureType.esriFTSimple, geometryShapeFieldName, ""));

      // Return the feature class for adding points.

      return featureClass;
    }catch (IOException e) {
      System.out.println("Could not create feature class for shapefile named: " + shapefileName);
      throw e;
    }
  }

  /**
   * Add the points from the text file to the shapefile.
   *
   * @param textFilePath path for the text file containing point coordinates.
   * @param featureClass the part of the shapefile to add point features to.
   * @param useFeatureBuffer whether to add points to a feature buffer or to individual features.
   * @throws IOException if cannot add points to the feature class.
   */
  private void addPoints(String textFilePath, FeatureClass featureClass, boolean useFeatureBuffer) throws IOException {
    System.out.println("Creating Point features...");
    try {
      if (useFeatureBuffer) {
        // Get an insert cursor and a feature buffer for the feature class, so we can add features
        // in a buffered manner.
        FeatureCursor featureCursor = new FeatureCursor(featureClass.IFeatureClass_insert(true));
        Feature featureBuffer = (Feature) featureClass.createFeatureBuffer();

        // Get the column indicies for the coordinate fields to be used
        // when setting values fort these fields.
        Fields fields = (Fields) featureBuffer.getFields();
        int lngIndex = fields.findField("Longitude");
        int latIndex = fields.findField("Latitude");
        int valIndex = fields.findField("Value");

        // Read in a line at a time, parsing the coordinate values for each point
        BufferedReader bufferedReader = new BufferedReader(new FileReader(textFilePath));
        int featureCount = 0;
        for (String textLine = bufferedReader.readLine(); textLine != null; textLine = bufferedReader.readLine(), featureCount++) {
          String[] tokens = textLine.split(", ");
          double lng = Double.parseDouble(tokens[0]);
          double lat = Double.parseDouble(tokens[1]);
          double val = Double.parseDouble(tokens[2]);

          System.out.println("Longitude: " + lng + " Latitude: " + lat + " Value: " + val);

          // Create a new point and set its X,Y coordinates from the longitude,latitude values.
          Point point = new Point();
          point.setX(lng);
          point.setY(lat);

          // Add the point's geometry to the feature buffer's shape field.
          featureBuffer.setShapeByRef(point);

          // Add longitude, latitude, and value values to their individual fields
          featureBuffer.setValue(lngIndex, new Double(lng));
          featureBuffer.setValue(latIndex, new Double(lat));
          featureBuffer.setValue(valIndex, new Double(val));

          // Add the feature at the current/cursor location in the shapefile
          featureCursor.insertFeature(featureBuffer);

          // Flush the insert cursor every 100 features
          if ((featureCount+1) % 100 == 0) {
            System.out.println("Flushing...");
            featureCursor.flush();
          }
        }

        // Flush the insert cursor at the end of the file
        featureCursor.flush();
        Cleaner.release(featureCursor);
      }else {
        //Use createFeature() and store()

        //Get the column indicies for the coordinate fields to be used
        //when setting values fort these fields.
        Fields fields = (Fields) featureClass.getFields();
        int lngIndex = fields.findField("Longitude");
        int latIndex = fields.findField("Latitude");
        int valIndex = fields.findField("Value");

        //Read in a line at a time, parsing the coordinate values for each point
        BufferedReader bufferedReader = new BufferedReader(new FileReader(textFilePath));
        for (String textLine = bufferedReader.readLine(); textLine != null; textLine = bufferedReader.readLine()) {
          String[] tokens = textLine.split(", ");
          double lng = Double.parseDouble(tokens[0]);
          double lat = Double.parseDouble(tokens[1]);
          double val = Double.parseDouble(tokens[2]);

          System.out.println("Longitude: " + lng + " Latitude: " + lat + " Value: " + val);

          //Create a new point and set its X,Y coordinates from the longitude,latitude values.
          Point point = new Point();
          point.setX(lng);
          point.setY(lat);

          //Create a new feature and add the point's geometry to it
          Feature feature = (Feature) featureClass.createFeature();
          feature.setShapeByRef(point);

          //Add longitude, latitude, and value values to their individual fields
          feature.setValue(lngIndex, new Double(lng));
          feature.setValue(latIndex, new Double(lat));
          feature.setValue(valIndex, new Double(val));

          //Persist changes by calling store()
          feature.store();
        }
      }
    }catch (IOException e) {
      System.out.println("Could not add points to shapefile");
      throw e;
    }
  }

  /**
   * Convenience method to generate an output directory based on the operating
   * system that the sample is being executed on. 
   * 
   * @return A path to the new directory is return
   */
  private static String getOutputDir() {
    String userDir;
    
    //Get the operating systems user profile or home location depending
    //on which operating system this sample is executed on.
    if(System.getProperty("os.name").toLowerCase().indexOf("win") > -1){
      userDir = System.getenv("UserProfile");
    }else{
      userDir = System.getenv("HOME");
    }
      
    String outputDir = userDir + File.separator + "arcgis_sample_output";
    
    System.out.println("Creating output directory - " + outputDir);
    
    new File(outputDir).mkdir();
    
    return outputDir;
  }
}