How to insert features using an insert cursor


This sample demonstrates how to use an insert cursor to load features. The other option for loading features in CreateFeature/Store. The primary difference between the two methods is: insert cursors bypass calling IFeature::Store, which performs all object behavior, making loading simple features much quicker. However, Store must be called on complex features and insert cursors automatically perform this when complex features are detected. In the case of complex features then, both methods yield the same performance.
The macro loads features from one shapefile into another shapefile. For simplicity sake, the code has been written to run within ArcMap and it does not create the output shapefile, you must create this before running the code. The Java version does not require ArcMap.

How to use

  1. Add the functions to your project.
  2. Modify the code to point to the desired shapefiles.
  3. Call LoadFeatures().
[VCPP]
HRESULT AddFields(IFeatureBuffer *pFeatureBuffer, IFeature *pFeature)
{
  if (0 == pFeatureBuffer)
    return E_POINTER;

  if (0 == pFeature)
    return E_POINTER;

  // Copy the attributes of the orig feature to the new feature
  IRowBufferPtr ipRowBuffer(pFeatureBuffer);

  IFieldsPtr ipNewFields; // fields on target feature class
  ipRowBuffer->get_Fields(&ipNewFields);

  IFieldsPtr ipFields; // fields on original feature class
  pFeature->get_Fields(&ipFields);

  IFieldPtr ipField;
  esriFieldType type;
  VARIANT_BOOL bFieldEditable;
  CComBSTR bstrName;
  CComVariant varValue;
  long lNewFieldIndex;
  long lFieldCount;
  ipFields->get_FieldCount(&lFieldCount);
  for (int i = 0; i < lFieldCount; ++i)
  {
    ipFields->get_Field(i, &ipField);
    ipField->get_Type(&type);
    ipField->get_Editable(&bFieldEditable);
    if (type != esriFieldTypeGeometry && type != esriFieldTypeOID &&
      VARIANT_TRUE == bFieldEditable)
    {
      ipField->get_Name(&bstrName);
      ipNewFields->FindField(bstrName, &lNewFieldIndex);
      if (lNewFieldIndex !=  - 1)
      {
        pFeature->get_Value(i, &varValue);
        pFeatureBuffer->put_Value(lNewFieldIndex, varValue);
      }
    }
  }

  return S_OK;
}

HRESULT OpenFeatureClass(BSTR bstrWorkspace, BSTR bstrFeatureClass,
  IFeatureClass **ppFeatureClass)
{
  // Create the workspace name object
  IWorkspaceNamePtr ipShpWorkspaceName(CLSID_WorkspaceName);
  ipShpWorkspaceName->put_PathName(bstrWorkspace);
  ipShpWorkspaceName->put_WorkspaceFactoryProgID(L 
    "esriDataSourcesFile.shapefileworkspacefactory.1");

  // Create the feature class name object
  IDatasetNamePtr ipDatasetName(CLSID_FeatureClassName);
  ipDatasetName->put_Name(bstrFeatureClass);
  ipDatasetName->putref_WorkspaceName(ipShpWorkspaceName);

  // Open the feature class
  INamePtr ipName(ipDatasetName);
  IUnknownPtr ipUnknown;
  ipName->Open(&ipUnknown);
  IFeatureClassPtr ipFeatureClass(ipUnknown);

  *ppFeatureClass = ipFeatureClass;
  if (*ppFeatureClass)
    (*ppFeatureClass)->AddRef();
  else
    return E_FAIL;

  return S_OK;
}

HRESULT LoadFeatures()
{
  // Open shapefile where new features will be written to// For simplicity, sample does not contain code to create a new shapefile
  IFeatureClassPtr ipOutFeatureClass;
  OpenFeatureClass(CComBSTR(L "d:\\data\\usa"), CComBSTR(L "test"),
    &ipOutFeatureClass);
  if (0 == ipOutFeatureClass)
    return E_FAIL;

  IFeatureCursorPtr ipInsertFeatureCursor;
  ipOutFeatureClass->Insert(VARIANT_TRUE, &ipInsertFeatureCursor);

  IFeatureBufferPtr ipInsertFeatureBuffer;
  ipOutFeatureClass->CreateFeatureBuffer(&ipInsertFeatureBuffer);

  // Open shapefile containing the features that will be copied
  IFeatureClassPtr ipInFeatureClass;
  OpenFeatureClass(CComBSTR(L "d:\\data\\usa"), CComBSTR(L "counties"),
    &ipInFeatureClass);
  if (0 == ipInFeatureClass)
    return E_FAIL;

  CComVariant varVariant;
  IGeometryPtr ipGeom;
  int nNewFeatureCount(0);
  // Loop through all the features in InFeatureClass
  IFeatureCursorPtr ipSearchFeatureCursor;
  ipInFeatureClass->Search(0, VARIANT_TRUE, &ipSearchFeatureCursor);
  IFeaturePtr ipFeature;
  ipSearchFeatureCursor->NextFeature(&ipFeature);
  while (ipFeature)
  {
    // Add the original feature's geometry to the feature buffer
    ipFeature->get_Shape(&ipGeom);
    ipInsertFeatureBuffer->putref_Shape(ipGeom);
    // Add all the original feature's fields to the feature buffer
    AddFields(ipInsertFeatureBuffer, ipFeature);
    // Insert the feature into the cursor
    ipInsertFeatureCursor->InsertFeature(ipInsertFeatureBuffer, &varVariant);
    nNewFeatureCount += 1;
    // Flush the feature cursor every 100 features// This is safer because you can write code to handle a flush error// If you don't flush the feature cursor it will automatically flush but// after all of your code executes at which time you have no control
    if (100 == nNewFeatureCount)
    {
      ipInsertFeatureCursor->Flush();
      nNewFeatureCount = 0;
    }
    ipSearchFeatureCursor->NextFeature(&ipFeature);
  }

  ipInsertFeatureCursor->Flush(); // Flush the cursor one last time

  return S_OK;
}






Development licensing Deployment licensing
Engine Developer Kit Engine