[GIS] How to get selected Features/Geometry from Windows Clipboard in ArcMap/C#

arcgis-10.0arcmaparcobjectscnet

I have a custom tool in ArcMap 10. The Workflow is the following:

  • Select Features in a Layer with the "Select Features by Rectangle" tool
  • Copy the Features to the Clipboard using STRG+c
  • Select the custom tool
  • The tool checks the Clipboard. In case of finding a copied Feature in the Clipboard the Workflow changes

I found an example on http://kiwigis.blogspot.com/2011/07/how-to-create-drop-target-for-layers-in.html where similar stuff is implemented using drag and drop.

Following and adapting the example and trying to copy layers in the TOC in ArcMap to the clipboard using STRG+c is working for me:

//Get the Data from the Clipboard
IDataObject clipBoardDataObject = Clipboard.GetDataObject();

//The format of the object data is "ESRI Layers" (this can be checked using clipBoardDataObject.GetFormats();) 
MemoryStream geomStream = clipBoardDataObject.GetData("ESRI Layers") as MemoryStream;                
byte[] bytes = geomStream.ToArray();

IMemoryBlobStreamVariant memoryBlobStreamVariant = new MemoryBlobStreamClass();
memoryBlobStreamVariant.ImportFromVariant(bytes);
IMemoryBlobStream2 memoryBlobStream = memoryBlobStreamVariant as IMemoryBlobStream2;
IStream stream = memoryBlobStream as IStream;
IObjectStream objectStream = new ObjectStreamClass();
objectStream.Stream = stream;

byte pv;
uint cb = sizeof(int);
uint pcbRead;

objectStream.RemoteRead(out pv, cb, out pcbRead);
int count = Convert.ToInt32(pv);

//Guid you find in the ESRI ILayer Interface
Guid iLayerGuid = new Guid("34C20002-4D3C-11D0-92D8-00805F7C28B0");

for (int i = 0; i < count; i++)
{
  object o = objectStream.LoadObject(ref iLayerGuid, null);
  ILayer layer = o as ILayer;      
}

I can cast the object to ILayer, this is working!

Trying to achieve the same with copied Features is not working for me, at least I don't really know what to do.

//Get the Data from the Clipboard
IDataObject clipBoardDataObject = Clipboard.GetDataObject();

MemoryStream geomStream = clipBoardDataObject.GetData("ESRI Geometry List") as MemoryStream;                
byte[] bytes = geomStream.ToArray();

IMemoryBlobStreamVariant memoryBlobStreamVariant = new MemoryBlobStreamClass();
memoryBlobStreamVariant.ImportFromVariant(bytes);
IMemoryBlobStream2 memoryBlobStream = memoryBlobStreamVariant as IMemoryBlobStream2;
IStream stream = memoryBlobStream as IStream;
IObjectStream objectStream = new ObjectStreamClass();
objectStream.Stream = stream;

byte pv;
uint cb = sizeof(int);
uint pcbRead;

objectStream.RemoteRead(out pv, cb, out pcbRead);
int count = Convert.ToInt32(pv);

//What to do next? What object do I need to unpack to?

You see here that the object format is "ESRI Geometry List" (of which I can't find any information online). So how can I "unpack" this object? IFeatureSelection, IFeature, IGeometry wont work.

Any Ideas?

Best Answer

I've done something similar to your tool/workflow. I too could not figure out how in an automated fasion to direct copied features to the appropriate layer. For my situation I used the ArcMap commands Copy and Paste to move selected features from one layer to another while in an edit session. The user just had to execute the manual step and define the target layer.