Map 3D. Ошибка при переклассификации COGO-точек. Civil 3D 2015, .NET 4.5

Автор Тема: Map 3D. Ошибка при переклассификации COGO-точек. Civil 3D 2015, .NET 4.5  (Прочитано 16694 раз)

0 Пользователей и 3 Гостей просматривают эту тему.

Отмечено как Решение Разживин Алексей 11-09-2015, 05:46:19

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
На основе вот этого.
Вроде работает. Код написан по-быстрому и без проверок.
Код - C# [Выбрать]
  1. [assembly: Autodesk.AutoCAD.Runtime.CommandClass(typeof(TestProject.TestClass))]
  2.  
  3. namespace TestProject
  4. {
  5.     using System;
  6.     using System.Collections.Specialized;
  7.  
  8.     using Autodesk.AutoCAD.ApplicationServices.Core;
  9.     using Autodesk.AutoCAD.DatabaseServices;
  10.     using Autodesk.AutoCAD.Runtime;
  11.     using Autodesk.Civil.DatabaseServices;
  12.     using Autodesk.Gis.Map;
  13.     using Autodesk.Gis.Map.Classification;
  14.  
  15.     using Trace = System.Diagnostics.Trace;
  16.     using System.Collections;
  17.     using Autodesk.Gis.Map.ObjectData;
  18.     using Autodesk.Gis.Map.Project;
  19.  
  20.     /// <summary>
  21.     /// Тестовый класс для демонстрации ошибки, связанной с повторной классификацией объекта.
  22.     /// </summary>
  23.     public class TestClass : IExtensionApplication
  24.     {
  25.         /// <summary>
  26.         /// Инициализация расширения.
  27.         /// </summary>
  28.         public void Initialize()
  29.         {
  30.             HostMapApplicationServices.Application.LogIn("SuperUser", "SUPERUSER");
  31.         }
  32.  
  33.         /// <summary>
  34.         /// Закрытие расширения.
  35.         /// </summary>
  36.         public void Terminate()
  37.         {
  38.         }
  39.  
  40.         /// <summary>
  41.         /// Классификация точки первым классом.
  42.         /// </summary>
  43.         [CommandMethod("CLASSIFY1")]
  44.         public void ClassifyOne()
  45.         {
  46.             var objId = GetCogoPoint();
  47.             Classify(objId, "Класс 1", "Свойство 1", "Свойство 2");
  48.         }
  49.  
  50.        
  51.  
  52.         /// <summary>
  53.         /// Классификация точки вторым классом.
  54.         /// </summary>
  55.         [CommandMethod("CLASSIFY2")]
  56.         public void ClassyfyTwo()
  57.         {
  58.             var objId = GetCogoPoint();
  59.             Unclassify(objId, "Класс 1");
  60.             Classify(objId, "Класс 2", "Свойство 3", "Свойство 4");
  61.         }
  62.  
  63.  
  64.        
  65.  
  66.         /// <summary>
  67.         /// Классификация объекта и выставление ему пользовательских свойств.
  68.         /// </summary>
  69.         /// <param name="objectId">Идентификатор объекта.</param>
  70.         /// <param name="className">Имя результирующего класса.</param>
  71.         /// <param name="properties">Массив имен свойств.</param>>
  72.         private static void Classify(ObjectId objectId, string className, params string[] properties)
  73.         {
  74.             var manager = HostMapApplicationServices.Application.ActiveProject.ClassificationManager;
  75.  
  76.             // здесь классифицируем
  77.             using (var ids = new ObjectIdCollection { objectId })
  78.             using (var failIds = new ObjectIdCollection())
  79.             {
  80.                 var errorCodes = new FeatureClassErrorCodeCollection();
  81.                 // manager.Unclassify(objectId); <-- Не помогает
  82.                 manager.Classify(failIds, errorCodes, ids, className, true, true);
  83.                 manager.Audit(objectId, true, true);
  84.             }
  85.  
  86.             // ниже выставляем значения свойств
  87.             using (var featureClassDefinition = manager[className])
  88.             {
  89.                 var collection = new StringCollection { "Пользовательский" };
  90.  
  91.                 foreach (var propertyName in properties)
  92.                 {
  93.                     using (var property = featureClassDefinition.GetProperty(collection, propertyName))
  94.                     {
  95.                         var value = property.FromString(DateTime.Now.Millisecond.ToString());
  96.                         try
  97.                         {
  98.                             property.SetValue(objectId, value, true);
  99.                         }
  100.                         catch (MapFeatureClassException mfce)
  101.                         {
  102.                             Trace.WriteLine((FeatureClassErrorCode)mfce.ErrorCode);
  103.                             throw;
  104.                         }
  105.                     }
  106.                 }
  107.             }
  108.         }
  109.  
  110.         /// <summary>
  111.         /// Получение идентификатора первой попавшейся коготочки.
  112.         /// </summary>
  113.         /// <returns>Идентификатор коготочки.</returns>
  114.         private static ObjectId GetCogoPoint()
  115.         {
  116.             var doc = Application.DocumentManager.MdiActiveDocument;
  117.  
  118.             using (var trans = doc.TransactionManager.StartTransaction())
  119.             using (var bt = (BlockTable)trans.GetObject(doc.Database.BlockTableId, OpenMode.ForRead))
  120.             using (var btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead))
  121.             {
  122.                 foreach (var objectId in btr)
  123.                 {
  124.                     using (var dbObj = trans.GetObject(objectId, OpenMode.ForRead))
  125.                     {
  126.                         if (dbObj is CogoPoint)
  127.                         {
  128.                             return objectId;
  129.                         }
  130.                     }
  131.                 }
  132.  
  133.                 trans.Commit();
  134.             }
  135.  
  136.             return ObjectId.Null;
  137.         }      
  138.  
  139.         /// <summary>
  140.                 /// Деклассификация объекта и удаление его пользовательских свойств.
  141.                 /// </summary>
  142.                 /// <param name="objectId">Идентификатор объекта.</param>
  143.                 /// <param name="className">Имя класса.</param>               
  144.                 private static void Unclassify(ObjectId objectId, string className)
  145.         {
  146.             var manager = HostMapApplicationServices.Application
  147.                 .ActiveProject.ClassificationManager;
  148.             manager.Unclassify(objectId);            
  149.  
  150.             MapApplication mapApp = HostMapApplicationServices.Application;
  151.  
  152.             ProjectModel activeProj = mapApp.ActiveProject;
  153.  
  154.             Tables odTables = activeProj.ODTables;
  155.  
  156.             try
  157.             {
  158.                 using (Transaction tr = objectId.Database.TransactionManager.StartTransaction())
  159.                 {
  160.                     ObjectId nodId = objectId.Database.NamedObjectsDictionaryId;
  161.                     DBDictionary nod = tr.GetObject(nodId, OpenMode.ForRead) as DBDictionary;
  162.                     ObjectId acadOCId = nod.GetAt("ACAD_OC");
  163.                     DBDictionary acadOc = tr.GetObject(acadOCId, OpenMode.ForRead) as DBDictionary;
  164.                     ObjectId defFileId = acadOc.GetAt("DefinitionFile");
  165.                     DBDictionary defFile = tr.GetObject(defFileId, OpenMode.ForRead) as DBDictionary;
  166.                     ObjectId classDataId = defFile.GetAt(className);
  167.                     DataTable classData = tr.GetObject(classDataId, OpenMode.ForWrite) as DataTable;
  168.                     for (int i = 0; i < classData.NumRows; i++)
  169.                     {
  170.                         if (classData.GetCellAt(i, 0).Value.Equals(objectId))
  171.                         {
  172.                             classData.RemoveRowAt(i);
  173.                             break;
  174.                         }
  175.                     }
  176.                     tr.Commit();
  177.                 }
  178.  
  179.             }
  180.             catch (MapException exc)
  181.             {
  182.  
  183.             }
  184.         }
  185.  
  186.        
  187.     }
  188. }

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Вроде работает. Код написан по-быстрому и без проверок.
Очень интересно. Как я понимаю manager.Unclassify(objectId); должно делать то, что ты делаешь дальше в коде. Но по какой-то причине это не происходит.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Да, наверное упустили это. Или есть в этом какой-то скрытый смысл. Кто знает, может после такой чистки где-нибудь нарушится связанность данных и вылезет потом в самый неподходящий момент...

Оффлайн Разживин АлексейАвтор темы

  • ADN Club
  • Сообщений: 12
  • Карма: 0
  • До-диез
  • Skype: tapraa
Большое спасибо Дмитрию Загорулькину и всем соучастным. Решение потестировал на всяких граничных условиях, вроде работает как надо. Посмотрим что скажут тестировщики.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Получил ответ от ADN DevHelp, что воспроизвести такое поведение они смогли и обсудят эту проблему с командой профильных инженеров. Я сообщил что Дмитрий Загорулькин нашёл работающий workaround, но попросил всё-таки уточнить возможность тоже самое сделать используя стандартное Map 3D API.
Дима! Твой workaround Augusto Goncalves обозвал Excellent и поблагодарил тебя за то, что ты им поделился. Так что принимай поздравления  ;)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
О... ничего себе :) Спасибо!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Получил новый ответ от Augusto Goncalves - штатного workaround нет. Создан запрос команде инженеров на изменение поведения программы, но с учетом найденного Дмитрий Загорулькин решения я бы не рассчитывал на исправление в ближайшей версии.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение