Create a copy of a layer

82
3
01-22-2020 06:36 AM
Highlighted
New Contributor III

I am trying to create a deep copy of my layers. These layers could be either shape files or part of a geodatabase file. I need all the data to remain the same because I am creating tools to allow the user to clean up the data and the changes are saved to the new layers and not the original.

Here is the code that I am using, but it has a problem with geodatabase files where it does not seem to copy the shapes correctly. For instance, a few of the polylines go from having two points or more to having zero points. I am hoping that you have a better solution.

(code may have slight errors as I cannot do a direct copy from development machine and am retyping the code)

IFeatureClassName pInFeatureClassName, pFeatureClassName;

IDataset pDataset;

IDatasetName pInDsName, pOutDatasetName;

IWorkspaceName pWorkspaceName;

IFeatureLayer pFLayer = selectedLayer as IFeatureLayer; //selected layer is either a node or link layer

IFeatureClass pFc = pFLayer.FeatureClass;

IQueryFilter qf = new QueryFilterClass();

pDataset = pFc as IDataset;

pInFeatureClassName = pDataset.FullName as IFeatureClassName;

pInDsNamepInFeatureClassName as IDatasetName;

pFeatureClassName = new FeatureClassName() as IFeatureClassName;

pOutDatasetName = pFeatureClassName as IDatasetName;

pOutDatasetName.Name = "someNameWithGuid";

pWorkspaceName = new WorkspaceName() as IWorkspaceName;

IWorkspace pWorkspace = pDataset.Workspace;

string tempPath  = pWorkspace.PathName;

pWorkspaceName.PathName = tempPath;

pWorkspaceName .WorkspaceFacoryProgId = "esricCore.shapefileworkspacefactory.1";

pOutDatasetName.WorkspaceName = pWorkspaceName;

pFeatureClassName .ShapeType = esriGeometryType.esriGeometryAny;

pFeatureClassName .ShapeFieldName = "Shape";  //how to we programatically determine this?

IFeatureSelection pFSel = pFLayer as IFeatureSelection;

pFSel.SelectFeatures(qf, esriSelectionResultEnum.esriSelectionResultAdd, false); //selects everything on the map

ISelectionSet pSelSet = pFSel.SelectionSet as ISelectionSet;

IExportOperation pExportOp = new ExportOperation() as IExportOperation;

pExportOp.ExportFeatureClass(pInDsName, null, pSelSet, null, pOutDatasetName as IFeatureClassName, 0);

IWorkspaceFactory workspacefac = new ShapefileWorkspaceFactoryClass();

IFeatureWorkspace featworkspace = (IFeatureWorkspace)workspacefac .OpenFromFile(tempPath, 0);

IFeatureLayer lyr = new FeatureLayerClass();

IFeatureClass featclass = featworkspace.OpenFeatureClass(pOutDatasetName.Name + ".shp");

lyr.FeatureClass = featclass;

lyr.Name = pOutDatasetName.Name;

lyr.Visible = true;

currdoc.ActiveView.FocusMap.AddLayer(lyr);

Reply
0 Kudos
3 Replies
Highlighted
MVP Frequent Contributor

Rather than write a load of complex ArcObjects code and deal with all scenarios why not call the Copy Features tool via the IGeoProcessor? Simpler code to maintain... Just an idea.

Reply
0 Kudos
Highlighted
New Contributor III

That doesn't maintain the same OBJECTID. It seems to renumber them so would make it difficult for the users if they want to merge their changes back. Is there a way to preserve that and do a complete copy where all attributes remain the same?

Reply
0 Kudos
Highlighted
MVP Frequent Contributor

At this point I would be wondering why people are relying on an ObjectID field. Yes lots of people do use it but as it is system generated and system maintained field they are at the whims of system changes. For example you are concerned about merging but what happens if one of those users compacts the geodatabase? Well all your objectID's change...

In my opinion ObjectID's should be treated as an annoying field to be ignored (but a requirement of spatial dataset) as you can't rely on it, you should be maintaining your own ID field that YOU control.

I would be putting the breaks on your development and explore why there is a reliance on that system maintained field and how you can alter your workflows to avoid using it. You'll be thanking me later...