Установка данных геолокации в чертеже AutoCAD с использованием .NET
API геолокации AutoCAD - это очень актуальная и перспективная тема, которую пришло время обсудить. Итак начнем. :-)Ниже пример кода на основе показанной на ADN DevDays в конце 2013 года - для AutoCAD версии 2014, - но тогда API оказалась не полностью реализованным (по крайней мере, насколько я помню – если я не прав, то поправьте меня) до версии 2015.
Я воспользовался возможностью для того, чтобы использовать Editor.Command (), чтобы вызвать пару команд синхронно - для включения информации Geomap и для зумирования до окружности, которую мы создаем вокруг нашего места – теперь этот API доступен.
Вот C# реализующий команду IGR:
- using Autodesk.AutoCAD.ApplicationServices;
- using Autodesk.AutoCAD.DatabaseServices;
- using Autodesk.AutoCAD.Geometry;
- using Autodesk.AutoCAD.Runtime;
- namespace GeoLocationAPI
- {
- public class Commands
- {
- [CommandMethod("IGR")]
- public void InsertGeoRef()
- {
- var doc = Application.DocumentManager.MdiActiveDocument;
- if (doc == null)
- return;
- var ed = doc.Editor;
- var db = doc.Database;
- var msId = SymbolUtilityServices.GetBlockModelSpaceId(db);
- // Проверяем нет ли еще в чертеже данных геолокации
- bool hasGeoData = false;
- try
- {
- var gdId = db.GeoDataObject;
- hasGeoData = true;
- }
- catch { }
- if (hasGeoData)
- {
- // Информируем и выходим: можно открыть объект для записи и модифицировать параметры
- ed.WriteMessage("\nВ чертеже уже есть данные геолокации!");
- return;
- }
- // Создадим данные геолокации для этого чертежа,
- // используем удобный способ для добавления к пространству модели
- // (она будет добавлена в словарь расширения)
- var data = new GeoLocationData();
- data.BlockTableRecordId = msId;
- data.PostToDb();
- // Мы определяем нашу геолокацию в терминах
- // широты/долготы при использовании Проекции Меркатора
- // http://goo.gl/mXBQeT
- data.CoordinateSystem = "WORLD-MERCATOR";
- data.TypeOfCoordinates = TypeOfCoordinates.CoordinateTypeGrid;
- // Используем широту-долготу La Tene, моего местного «пляжа»
- // (это на озере :-)
- // http://en.wikipedia.org/wiki/La_T%C3%A8ne,_Neuch%C3%A2tel
- var geoPt = new Point3d(7.019438, 47.005247, 0);
- // Преобразуем точку из географической в Пространство Модели
- // и добавляем информацию о нашей геолокации
- var wcsPt = data.TransformFromLonLatAlt(geoPt);
- data.DesignPoint = wcsPt;
- data.ReferencePoint = geoPt;
- // Разрешаем команде ГЕОКАРТА (GEOMAP) показать
- // наше географическое положение
- ed.Command("_.GEOMAP", "_AERIAL");
- // А теперь добавим окружность вокруг нашего положения
- // и установим пределы нашего зумирования
- using (var tr = db.TransactionManager.StartTransaction())
- {
- var ms =
- tr.GetObject(msId, OpenMode.ForWrite) as BlockTableRecord;
- if (ms != null)
- {
- // Добавим красную окружность радиусом 7000
- // с центром в нашей точке
- var circle = new Circle(wcsPt, Vector3d.ZAxis, 7000);
- circle.ColorIndex = 1;
- ms.AppendEntity(circle);
- tr.AddNewlyCreatedDBObject(circle, true);
- }
- tr.Commit();
- }
- // Ну а теперь выполним зум по нашей окружности
- ed.Command("_.ZOOM", "_OBJECT", "_L", "");
- }
- }
- }
Когда мы выполним наш код, мы увидим географическое положение в районе La Tene (место недалеко от моего дома) и окружность радиусом 7км вокруг него:
Небольшое предупреждение по поводу метода TransformFromLonLatAlt(): он подразумевает, что Point3d передаёт долготу, широту, высоту над уровнем моря в x, y, z полях именно в этом порядке. Я сделал ошибку, скопировав из Карт Гугл широту-долготу (не обратив внимание, что мне нужна долгота-широта), и обнаружил, что AutoCAD перебросил меня в место на расстоянии 1км внутри Эфиопии от границы Сомали. Я думаю, что очень показательно, что может получится если перепутать порядок долготы и широты. :)
Обсуждение: http://adn-cis.org/forum/index.php?topic=1871
Опубликовано 16.02.2015Отредактировано 16.02.2015 в 23:51:58