Clip shapefile by feature
ClipByFeatures.cpp
// 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.
// 

  
#include "ClipByFeatures.h"

int main(int argc, char** argv)
{
  // Process the arguments and get the data files
  std::cerr << "ClipByFeatures - Environmental Systems Research Institute" 
            << std::endl << std::endl;

  if (argc != 5)
  {
    std::cerr << "Usage: ClipByFeatures " 
              << "<Input Feature Dataset> "
              << "<Clip Feature Dataset> " 
              << "<Output Feature Dataset> " 
              << "<Cluster Tolerance (a double)>" 
              << std::endl;

    AoExit(0);
  }

  char* src = argv[1];
  char* clip = argv[2];
  char* result = argv[3];
  double tolerance = atoi(argv[4]);

  HRESULT hr;

  InitializeApp();

  // Clip the shapefile
  hr = ClipFile(src, clip, result, tolerance);
    
  ShutdownApp();

  if (FAILED(hr))
    std::cerr << "Clip Failed: hr = " << hr << std::endl;
  else
    std::cerr << result << " created!" << std::endl;

  AoExit(0);
}

HRESULT ClipFile(char* src, char* clip, char* result, double tolerance)
{
  // Path parsing arguments
  CComBSTR bsSrcPath; 
  CComBSTR bsSrcName;
  CComBSTR bsClipPath; 
  CComBSTR bsClipName; 
  CComBSTR bsOutPath;
  CComBSTR bsOutName;
  CComBSTR bsSrcTable;
  CComBSTR bsClipTable;

  HRESULT hr = GetParentDirFromFullPath(src, &bsSrcPath);
  if (FAILED(hr) || bsSrcPath.Length() <= 0)
  {
    std::cerr << "Can't get the source path." << std::endl;
    return E_FAIL;
  }
  hr = GetFileFromFullPath(src, &bsSrcName);
  if (FAILED(hr) || bsSrcName.Length() <= 0)
  {
    std::cerr << "Can't get the source file name." << std::endl;
    return E_FAIL;
  }
  hr = AppendFileExtensionIfNeeded(bsSrcName, CComBSTR(L".dbf"), &bsSrcTable);
  if (FAILED(hr) || bsSrcTable.Length() <= 0)
  {
    std::cerr << "Can't get the source table." << std::endl;
    return E_FAIL;
  }
  hr = GetParentDirFromFullPath(clip, &bsClipPath);
  if (FAILED(hr) || bsClipPath.Length() <= 0)
  {
    std::cerr << "Can't get the clip path." << std::endl;
    return E_FAIL;
  }
  hr = GetFileFromFullPath(clip, &bsClipName);
  if (FAILED(hr) || bsClipName.Length() <= 0)
  {
    std::cerr << "Can't get the clip file name." << std::endl;
    return E_FAIL;
  }
  hr = AppendFileExtensionIfNeeded(bsClipName, CComBSTR(L".dbf"), &bsClipTable);
  if (FAILED(hr) || bsClipTable.Length() <= 0)
  {
    std::cerr << "Can't get the clip table." << std::endl;
    return E_FAIL;
  }
  hr = GetParentDirFromFullPath(result, &bsOutPath);
  if (FAILED(hr) || bsOutPath.Length() <= 0)
  {
    std::cerr << "Can't get the output path." << std::endl;
    return E_FAIL;
  }
  hr = GetFileFromFullPath(result, &bsOutName);
  if (FAILED(hr) || bsOutName.Length() <= 0)
  {
    std::cerr << "Can't get the output file name." << std::endl;
    return E_FAIL;
  }

  // Open the source workspace
  IWorkspaceNamePtr ipSrcWkspName(CLSID_WorkspaceName);
  ipSrcWkspName->put_PathName(bsSrcPath);
  ipSrcWkspName->put_WorkspaceFactoryProgID(
    CComBSTR("esriDataSourcesFile.ShapefileWorkspaceFactory"));
  IDatasetNamePtr ipSrcDataName(CLSID_TableName);
  ipSrcDataName->put_Name(bsSrcTable);
  ipSrcDataName->putref_WorkspaceName(ipSrcWkspName);
  INamePtr ipSrcName(ipSrcDataName);
  IUnknownPtr ipSrcUnk;
  hr = ipSrcName->Open(&ipSrcUnk);
  if (FAILED(hr) || ipSrcUnk == 0)
  {
    std::cerr << "Couldn't open source dataset." << std::endl;
    return hr;
  }
  ITablePtr ipSrcTable(ipSrcUnk);

  // Open Clip workspace
  IWorkspaceNamePtr ipClipWkspName(CLSID_WorkspaceName);
  ipClipWkspName->put_PathName(bsClipPath);
  ipClipWkspName->put_WorkspaceFactoryProgID(
    CComBSTR("esriDataSourcesFile.ShapefileWorkspaceFactory"));
  IDatasetNamePtr ipClipDataName(CLSID_TableName);
  ipClipDataName->put_Name(bsClipName);
  ipClipDataName->putref_WorkspaceName(ipClipWkspName);
  INamePtr ipClipName(ipClipDataName);
  IUnknownPtr ipClipUnk;
  hr = ipClipName->Open(&ipClipUnk);
  if (FAILED(hr) || ipClipUnk == 0)
  {
    std::cerr << "Couldn't open clip dataset." << std::endl;
    return hr;
  }
  ITablePtr ipClipTable(ipClipUnk);

  // Resulting feature class
  IWorkspaceFactoryPtr ipShapefileFactory(CLSID_ShapefileWorkspaceFactory);
  IWorkspacePtr ipWksp;
  ipShapefileFactory->OpenFromFile(bsSrcPath, 0, &ipWksp);
  IFeatureClassPtr ipSrcShapefile;
  hr = ((IFeatureWorkspacePtr) ipWksp)->OpenFeatureClass(bsSrcName, 
                                                         &ipSrcShapefile);
  if (FAILED(hr) || ipSrcShapefile == 0)
  {
    std::cerr << "Couldn't open source feature class." << std::endl;
    return hr;
  }
  IFeatureClassNamePtr ipFCName(CLSID_FeatureClassName);
  ipFCName->put_FeatureType(esriFTSimple);
  ipFCName->put_ShapeFieldName(CComBSTR(L"Shape"));
  esriGeometryType geomType;
  ipSrcShapefile->get_ShapeType(&geomType);
  ipFCName->put_ShapeType(geomType);

  // Open target workspace
  IWorkspaceNamePtr ipOutWkspName(CLSID_WorkspaceName);
  ipOutWkspName->put_PathName(bsOutPath);
  ipOutWkspName->put_WorkspaceFactoryProgID(
    CComBSTR("esriDataSourcesFile.ShapefileWorkspaceFactory"));
  IDatasetNamePtr ipOutDataName(ipFCName);
  ipOutDataName->put_Name(bsOutName);
  ipOutDataName->putref_WorkspaceName(ipOutWkspName);

  IBasicGeoprocessorPtr ipBasicGeoProc(CLSID_BasicGeoprocessor);
  IFeatureClassPtr ipResultFC;
//std::cerr << "got here" << std::endl;
  hr = ipBasicGeoProc->Clip(ipSrcTable, VARIANT_FALSE, 
                            ipClipTable, VARIANT_FALSE,
                            tolerance, ipFCName, &ipResultFC);

  return hr;
}