ADN Open CIS
Сообщество программистов Autodesk в СНГ

16/02/2015

Установка данных геолокации в чертеже AutoCAD с использованием .NET

API геолокации AutoCAD  - это очень актуальная и перспективная тема, которую пришло время обсудить. Итак начнем. :-)

Ниже пример кода на основе показанной на ADN DevDays в конце 2013 года - для AutoCAD версии 2014, - но тогда API оказалась не полностью реализованным (по крайней мере, насколько я помню – если я не прав, то поправьте меня) до версии 2015.

Я воспользовался возможностью для того, чтобы использовать Editor.Command (), чтобы вызвать пару команд синхронно - для включения информации Geomap и для зумирования до окружности, которую мы создаем вокруг нашего места – теперь этот API доступен.

Вот C# реализующий команду IGR:

Код - C#: [Выделить]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.Geometry;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. namespace GeoLocationAPI
  7. {
  8.   public class Commands
  9.   {
  10.     [CommandMethod("IGR")]
  11.     public void InsertGeoRef()
  12.     {
  13.       var doc = Application.DocumentManager.MdiActiveDocument;
  14.       if (doc == null)
  15.         return;
  16.       var ed = doc.Editor;
  17.       var db = doc.Database;
  18.       var msId = SymbolUtilityServices.GetBlockModelSpaceId(db);
  19.  
  20.       // Проверяем нет ли еще в чертеже данных геолокации
  21.  
  22.       bool hasGeoData = false;
  23.       try
  24.       {
  25.         var gdId = db.GeoDataObject;
  26.         hasGeoData = true;
  27.       }
  28.       catch { }
  29.  
  30.       if (hasGeoData)
  31.       {
  32.         // Информируем и выходим: можно открыть объект для записи и модифицировать параметры
  33.  
  34.         ed.WriteMessage("\nВ чертеже уже есть данные геолокации!");
  35.         return;
  36.       }
  37.  
  38.       // Создадим данные геолокации для этого чертежа,
  39.       // используем удобный способ для добавления к пространству модели
  40.       // (она будет добавлена в словарь расширения)
  41.  
  42.       var data = new GeoLocationData();
  43.       data.BlockTableRecordId = msId;
  44.       data.PostToDb();
  45.  
  46.       // Мы определяем нашу геолокацию в терминах
  47.       // широты/долготы при использовании Проекции Меркатора
  48.       // http://goo.gl/mXBQeT
  49.  
  50.       data.CoordinateSystem = "WORLD-MERCATOR";
  51.       data.TypeOfCoordinates = TypeOfCoordinates.CoordinateTypeGrid;
  52.  
  53.       // Используем широту-долготу La Tene, моего местного «пляжа»
  54.       // (это на озере :-)
  55.       // http://en.wikipedia.org/wiki/La_T%C3%A8ne,_Neuch%C3%A2tel
  56.  
  57.       var geoPt = new Point3d(7.019438, 47.005247, 0);
  58.  
  59.       // Преобразуем точку из географической в Пространство Модели
  60.       // и добавляем информацию о нашей геолокации
  61.  
  62.       var wcsPt = data.TransformFromLonLatAlt(geoPt);
  63.       data.DesignPoint = wcsPt;
  64.       data.ReferencePoint = geoPt;
  65.  
  66.       // Разрешаем команде ГЕОКАРТА (GEOMAP) показать
  67.       // наше географическое положение
  68.  
  69.       ed.Command("_.GEOMAP", "_AERIAL");
  70.  
  71.       // А теперь добавим окружность вокруг нашего положения
  72.       // и установим пределы нашего зумирования
  73.  
  74.       using (var tr = db.TransactionManager.StartTransaction())
  75.       {
  76.         var ms =
  77.           tr.GetObject(msId, OpenMode.ForWrite) as BlockTableRecord;
  78.         if (ms != null)
  79.         {
  80.           // Добавим красную окружность радиусом 7000
  81.           // с центром в нашей точке
  82.  
  83.           var circle = new Circle(wcsPt, Vector3d.ZAxis, 7000);
  84.           circle.ColorIndex = 1;
  85.           ms.AppendEntity(circle);
  86.           tr.AddNewlyCreatedDBObject(circle, true);
  87.         }
  88.         tr.Commit();
  89.       }
  90.  
  91.       // Ну а теперь выполним зум по нашей окружности
  92.  
  93.       ed.Command("_.ZOOM", "_OBJECT", "_L", "");
  94.     }
  95.   }
  96. }

Когда мы выполним наш код, мы увидим географическое положение в районе La Tene (место недалеко от моего дома) и окружность радиусом 7км вокруг него:

 

Небольшое предупреждение по поводу метода TransformFromLonLatAlt(): он подразумевает, что Point3d передаёт долготу, широту, высоту над уровнем моря в x, y, z полях именно в этом порядке. Я сделал ошибку, скопировав из Карт Гугл широту-долготу (не обратив внимание, что мне нужна долгота-широта), и обнаружил, что AutoCAD перебросил меня в место на расстоянии 1км внутри Эфиопии от границы Сомали. Я думаю, что очень показательно, что может получится если перепутать порядок долготы и широты. :)

Источник: http://through-the-interface.typepad.com/through_the_interface/2014/06/attaching-geo-location-data-to-an-autocad-drawing-using-net.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=1871

Опубликовано 16.02.2015
Отредактировано 16.02.2015 в 23:51:58