Como obter Recursos / Geometria selecionados da área de transferência do Windows no ArcMap / C #?

14

Eu tenho uma ferramenta personalizada no ArcMap 10. O fluxo de trabalho é o seguinte:

  • Selecionar recursos em uma camada com a ferramenta "Selecionar recursos por retângulo"
  • Copie os recursos para a área de transferência usando STRG + c
  • Selecione a ferramenta personalizada
  • A ferramenta verifica a área de transferência. No caso de encontrar um recurso copiado na área de transferência, o fluxo de trabalho muda

Encontrei um exemplo em http://kiwigis.blogspot.com/2011/07/how-to-create-drop-target-for-layers-in.html onde coisas semelhantes são implementadas usando arrastar e soltar.

Seguir e adaptar o exemplo e tentar copiar camadas no sumário no ArcMap para a área de transferência usando STRG + c está funcionando para mim:

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

Posso converter o objeto para ILayer, isso está funcionando!

Tentar conseguir o mesmo com os recursos copiados não está funcionando para mim, pelo menos eu realmente não sei o que fazer.

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

Você vê aqui que o formato do objeto é "Lista de geometria da ESRI" (da qual não consigo encontrar nenhuma informação online). Então, como posso "descompactar" esse objeto? IFeatureSelection, IFeature, IGeometry não funcionará.

Alguma ideia?

prisma.ph
fonte
+1 boa pergunta. Como você determinou que precisava passar a "Lista de geometria da ESRI" para o GetData?
Kirk Kuykendall
@Kirk Kuykendall, posso chamar clipBoardDataObject.GetFormats (), que me fornece uma lista do formato ao qual os dados estão associados. O resultado da string no caso de eu ter copiado recursos para a área de transferência é "ESRI Geometry List".
Prisma.ph
Dado que a área de transferência contém recursos, acho que a Lista de geometria da ESRI pode ser um pouco enganadora. Um recurso tem muito mais do que apenas geometria. Gostaria de saber se você poderia usar a reflexão e percorrer cada interface em cada montagem da ESRI. Para cada interface, obtenha seu guia e veja se o LoadObject retorna alguma coisa.
Kirk Kuykendall
Testei com todas as interfaces de Sistema, Carto, Geometria, Geodatabase e Frameworks e não encontrei uma interface que funcionasse. Talvez seja uma interface da Microsoft?
precisa saber é o seguinte
Alguém encontrou solução? Eu também tentei transmitir para interfaces de sistema e geodatabase, mas sem sorte.

Respostas:

2

Fiz algo semelhante à sua ferramenta / fluxo de trabalho. Eu também não conseguia descobrir como, em um fasion automatizado, direcionar os recursos copiados para a camada apropriada. Para minha situação, usei os comandos do ArcMap Copiar e Colar para mover os recursos selecionados de uma camada para outra durante uma sessão de edição. O usuário apenas precisou executar a etapa manual e definir a camada de destino.

artwork21
fonte