如何在ArcMap / C#中从Windows剪贴板获取选定的要素/几何?


14

我在ArcMap 10中有一个自定义工具。工作流如下:

  • 使用“按矩形选择要素”工具在图层中选择要素
  • 使用STRG + c将功能部件复制到剪贴板
  • 选择自定义工具
  • 该工具检查剪贴板。如果在剪贴板中找到复制的功能,则工作流程会更改

我在http://kiwigis.blogspot.com/2011/07/how-to-create-drop-target-for-layers-in.html上找到了一个示例,其中使用拖放实现了类似的内容。

按照并修改示例,并尝试使用STRG + c将ArcMap中的TOC中的图层复制到剪贴板对我来说是可行的:

//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;      
}

我可以将对象投射到ILayer,这可以正常工作!

尝试使用复制的功能实现相同效果对我来说不起作用,至少我真的不知道该怎么做。

//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?

您会在此处看到对象格式为“ ESRI几何列表”(我无法在线找到任何信息)。那么如何才能“拆开”这个物体呢?IFeatureSelection,IFeature,IGeometry不起作用。

有任何想法吗?


+1好问题。您如何确定需要将“ ESRI几何列表”传递给GetData?
Kirk Kuykendall,2012年

@Kirk Kuykendall我可以调用clipBoardDataObject.GetFormats(),该列表为我提供了与数据关联的格式的列表。如果我将要素复制到剪贴板,则字符串结果为“ ESRI Geometry List”。
pyramida.ph 2012年

考虑到剪贴板包含功能,我认为ESRI几何列表可能会引起误解。要素不仅具有几何图形,还具有很多其他功能。我想知道您是否可以使用反射并遍历每个ESRI程序集中的每个接口。对于每个接口,获取其GUID并查看LoadObject是否返回任何内容。
Kirk Kuykendall,2012年

我测试了System,Carto,Geometry,Geodatabase和Frameworks中的所有接口,但没有找到有效的接口。也许是微软的界面?
Goldorak84'8

有没有人找到解决方案?我也尝试转换为系统和地理数据库接口,但是没有任何运气。

Answers:


2

我已经完成了与您的工具/工作流程类似的操作。我也无法弄清楚如何以自动方式将复制的要素定向到适当的图层。就我的情况而言,我在编辑会话中使用ArcMap命令“复制和粘贴”将选定的要素从一层移动到另一层。用户只需要执行手动步骤并定义目标层即可。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.