arcgissamples\geometry\ClipShapefileByEnvelope.java—ArcObjects 10.4 Help for Java | ArcGIS for Desktop
Clip a shapefile by envelope
arcgissamples\geometry\ClipShapefileByEnvelope.java
/* Copyright 2015 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 at <your ArcGIS install location>/DeveloperKit10.4/userestrictions.txt.
* 
*/
package arcgissamples.geometry;

import java.io.File;
import java.io.IOException;

import com.esri.arcgis.datasourcesfile.ShapefileWorkspaceFactory;
import com.esri.arcgis.geodatabase.IFeature;
import com.esri.arcgis.geodatabase.IFeatureBuffer;
import com.esri.arcgis.geodatabase.IFeatureClass;
import com.esri.arcgis.geodatabase.IFeatureCursor;
import com.esri.arcgis.geodatabase.IField;
import com.esri.arcgis.geodatabase.IFields;
import com.esri.arcgis.geodatabase.SpatialFilter;
import com.esri.arcgis.geodatabase.Workspace;
import com.esri.arcgis.geodatabase.esriFieldType;
import com.esri.arcgis.geodatabase.esriSpatialRelEnum;
import com.esri.arcgis.geometry.Envelope;
import com.esri.arcgis.geometry.IGeometry;
import com.esri.arcgis.geometry.ITopologicalOperator;
import com.esri.arcgis.system.AoInitialize;
import com.esri.arcgis.system.EngineInitializer;
import com.esri.arcgis.system.esriLicenseProductCode;
import com.esri.arcgis.system.esriLicenseStatus;

/**
 * Description: This sample takes a source shapefile and the name of a target shapefile, along with the extents of a
 * clipping envelope. These are used to export the features inside the clipping envelope to the newly created target
 * shapefile. Any feature crossing the clipping envelope is clipped. Inputs: Shapefile - input shapefile dataset.
 * Outputs: Shapefile - a new shapefile representing the new clip extent.
 */
public class ClipShapefileByEnvelope
{
  public ClipShapefileByEnvelope()
  {
    
  }

  public static void main(String[] args)
  {
    System.out.println("Starting ClipShapefileByEnvelope - An ArcObjects Java SDK Developer Sample");
    try
    {
      // Initialize the engine and licenses.
      EngineInitializer.initializeEngine();

      AoInitialize aoInit = new AoInitialize();
      initializeArcGISLicenses(aoInit);

      //Get DEVKITHOME Home
      String devKitHome = System.getenv("AGSDEVKITJAVA");

      if (!(new File(devKitHome).exists()))
      {
        System.out.println(devKitHome + " does not exist.\nExiting...");
        System.exit(-1);
      }
      final String srcShapefilePath = devKitHome + "java" + File.separator + 
      "samples" + File.separator + 
      "data" + File.separator + 
      "usa";
      
      final String srcShapefileName = "states.shp";
      final String clippedShapefilePath = getOutputDir() + File.separator + "clipbyenvelope";
      final String clippedShapefileName = "clipped.shp";
      final double llLng = -115.216;
      final double llLat = 44.3;
      final double urLng = -92.45;
      final double urLat = 35.67;
  
      File clippedShapefileFile = new File(clippedShapefilePath, clippedShapefileName);
      if (clippedShapefileFile.exists())
      {
        System.out.println("Output shapefile already exists: " + clippedShapefileFile.getAbsolutePath());
        System.out.println("Delete it (plus related files) and rerun");
        System.exit(0);
      }
      File clippedDir = new File(clippedShapefilePath);
      clippedDir.mkdir();      

      IFeatureClass clippedFeatureClass = clip(srcShapefilePath, srcShapefileName, clippedShapefilePath,
          clippedShapefileName, llLng, llLat, urLng, urLat);
      System.out.println("Created " + clippedShapefileFile.getAbsolutePath());
      System.out.println("It contains " + clippedFeatureClass.featureCount(null) + " feature(s).");
      aoInit.shutdown();
    }
    catch (IOException e)
    {
      e.printStackTrace();
      System.out.println(e.getMessage());
      System.out.println("Sample failed.  Exiting...");
      System.exit(-1);
    }
  }
  
  /**
   * Clips shapefile
   * @param srcShapefilePath
   * @param srcShapefileName
   * @param clippedShapefilePath
   * @param clippedShapefileName
   * @param llLng
   * @param llLat
   * @param urLng
   * @param urLat
   * @return
   * @throws IOException
   */
  public static IFeatureClass clip(String srcShapefilePath, String srcShapefileName, String clippedShapefilePath,
      String clippedShapefileName, double llLng, double llLat, double urLng, double urLat) throws IOException
  {
    // open source shapefile
    ShapefileWorkspaceFactory shapefileWorkspaceFactory = new ShapefileWorkspaceFactory();
    Workspace srcWorkspace = new Workspace(shapefileWorkspaceFactory.openFromFile(srcShapefilePath, 0));
    IFeatureClass srcFeatureClass = srcWorkspace.openFeatureClass(srcShapefileName);

    // create clip envelope to clip against the source features
    Envelope theClipEnvelope = new Envelope();
    theClipEnvelope.putCoords(llLng, llLat, urLng, urLat);

    // define a spatial query filter
    SpatialFilter spatialFilter = new SpatialFilter();
    spatialFilter.setGeometryByRef(theClipEnvelope);
    spatialFilter.setGeometryField(srcFeatureClass.getShapeFieldName());
    spatialFilter.setSpatialRel(esriSpatialRelEnum.esriSpatialRelIntersects);

    // get a cursor based on the spatial query for the source features
    IFeatureCursor srcFeatureCursor = srcFeatureClass.search(spatialFilter, true);

    // create target clip shapefile with same fields as source shapefile
    Workspace clippedWorkspace = new Workspace(shapefileWorkspaceFactory.openFromFile(clippedShapefilePath, 0));
    IFeatureClass clippedFeatureClass = clippedWorkspace.createFeatureClass(clippedShapefileName, srcFeatureClass
        .getFields(), srcFeatureClass.getCLSID(), srcFeatureClass.getEXTCLSID(), srcFeatureClass
        .getFeatureType(), srcFeatureClass.getShapeFieldName(), "");

    // create a cursor and buffer for the clipped features
    IFeatureCursor clippedFeaturesCursor = clippedFeatureClass.IFeatureClass_insert(true);
    IFeatureBuffer clippedFeaturesBuffer = clippedFeatureClass.createFeatureBuffer();
    //
    // Loop through the source features and copy them to the clipped shapefile.
    //
    IFeature srcIFeature = srcFeatureCursor.nextFeature();
    System.out.print("working: ");
    while (srcIFeature != null)
    {
      System.out.print(" . ");
      // get the source shape to clip. It may be a polygon, point, polyline, etc.
      IGeometry srcShapeGeometry = srcIFeature.getShapeCopy();
      //
      // Only an object that implements IToplogicalOperator can clip and
      // call buffer() on itself, so we check and then cast the geometry/shape to it,
      // If we knew we would always be dealing with a polygon, or polyline
      // or point or multipoint, etc, we could cast to it instead.
      //
      if (!(srcShapeGeometry instanceof ITopologicalOperator))
      {
        continue;
      }
      ITopologicalOperator srcShapeTopoGeom = (ITopologicalOperator) srcShapeGeometry;
      srcShapeTopoGeom.clip(theClipEnvelope);

      clippedFeaturesBuffer.setShapeByRef(srcShapeTopoGeom.buffer(0));
      //
      // Copy fields too, except the ID and geometry/shape fields
      //
      IFields srcFields = srcIFeature.getFields();
      IFields clippedFields = clippedFeaturesBuffer.getFields();
      int srcNFields = srcFields.getFieldCount();
      for (int i = 0; i < srcNFields; i++)
      {
        IField srcField = srcFields.getField(i);
        if (srcField.getType() == esriFieldType.esriFieldTypeOID
            || srcField.getType() == esriFieldType.esriFieldTypeGeometry)
        {
          continue;
        }
        String srcFieldName = srcField.getName();
        int srcFieldNameIndex = srcFields.findField(srcFieldName);
        Object srcFeatureNameValue = srcIFeature.getValue(srcFieldNameIndex);
        int clippedFieldNameIndex = clippedFields.findField(srcFieldName);
        clippedFeaturesBuffer.setValue(clippedFieldNameIndex, srcFeatureNameValue);
      }
      clippedFeaturesCursor.insertFeature(clippedFeaturesBuffer);
      srcIFeature = srcFeatureCursor.nextFeature();
    }
    System.out.println();
    clippedFeaturesCursor.flush();
    return clippedFeatureClass;
  }
    
  /**
   * Initializes the lowest available ArcGIS License
   */
  private static void initializeArcGISLicenses(AoInitialize aoInit)
  {
    try
    {
      if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) == esriLicenseStatus.esriLicenseAvailable)
      {
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine);
      }
      else if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeBasic) == esriLicenseStatus.esriLicenseAvailable)
      {
        aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeBasic);
      }
      else
      {
        System.err.println("Could not initialize an Engine or Basic License. Exiting application.");
        System.exit(-1);
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }    

  /**
   * Returns output directory
   * @return
   */
  private static String getOutputDir()
  {
    String userDir;
    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;

  }
}