Как получить выбранные объекты / геометрию из буфера обмена Windows в ArcMap / C #?

14

У меня есть специальный инструмент в ArcMap 10. Рабочий процесс выглядит следующим образом:

  • Выберите объекты в слое с помощью инструмента «Выбор объектов по прямоугольнику»
  • Скопируйте объекты в буфер обмена, используя STRG + c
  • Выберите пользовательский инструмент
  • Инструмент проверяет буфер обмена. В случае обнаружения скопированного объекта в буфере обмена рабочий процесс изменяется

Я нашел пример на http://kiwigis.blogspot.com/2011/07/how-to-create-drop-target-for-layers-in.html, где похожие вещи реализованы с помощью перетаскивания.

Следование и адаптация примера и попытка скопировать слои в оглавлении в ArcMap в буфер обмена с помощью STRG + c работают для меня:

//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 не будут работать.

Есть идеи?

prisma.ph
источник
+1 хороший вопрос. Как вы определили, что вам нужно передать «Список геометрии ESRI» в GetData?
Кирк Кайкендалл
@Kirk Kuykendall Я могу вызвать clipBoardDataObject.GetFormats (), который дает мне список формата, с которым связаны данные. Строка результата, если я скопировал объекты в буфер обмена, это «Список геометрии ESRI».
prisma.ph
Учитывая, что буфер обмена содержит функции, я думаю, что список геометрии ESRI может быть немного обманчивым. Особенность имеет гораздо больше, чем просто геометрия. Интересно, можно ли использовать отражение и циклически проходить через каждый интерфейс в каждой сборке ESRI? Для каждого интерфейса получите его guid и посмотрите, возвращает ли LoadObject что-нибудь.
Кирк Куйкендалл
Я протестировал все интерфейсы System, Carto, Geometry, Geodatabase и Frameworks и не нашел работающий интерфейс. Может быть, это интерфейс Microsoft?
Goldorak84
Кто-нибудь нашел решение? Я также пробовал приводить к интерфейсам System и Geodatabase, но безуспешно.

Ответы:

2

Я сделал что-то похожее на ваш инструмент / рабочий процесс. Я тоже не мог понять, как в автоматическом режиме направить скопированные объекты на соответствующий слой. В моей ситуации я использовал команды ArcMap Копировать и Вставить, чтобы перемещать выбранные объекты с одного слоя на другой во время сеанса редактирования. Пользователь просто должен был выполнить шаг вручную и определить целевой слой.

artwork21
источник