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.
[VCPP]
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
- Add the functions to your project.
- Modify the code to point to the desired shapefiles.
- Call LoadFeatures().
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 |