Здесь показаны различия между двумя версиями данной страницы.
Следующая версия | Предыдущая версия | ||
developers:tutorial:algstationing [2022/07/07 04:43] proxor создано |
developers:tutorial:algstationing [2022/07/12 20:43] (текущий) proxor |
||
---|---|---|---|
Строка 1: | Строка 1: | ||
+ | ====== Выбор модели подобъекта и преобразование координат ====== | ||
+ | |||
В терминологии программного комплекса [[http://www.topomatic.ru|Топоматик Робур]] подобъектами принято называть модели [[road:road:start|автомобильных]] и [[rail:rail:start|железных дорог]], а также [[road:work_with_track:start|модели трасс]]. | В терминологии программного комплекса [[http://www.topomatic.ru|Топоматик Робур]] подобъектами принято называть модели [[road:road:start|автомобильных]] и [[rail:rail:start|железных дорог]], а также [[road:work_with_track:start|модели трасс]]. | ||
- | Программно подобъекты являются наследниками класса [[developers:references:topomatic.alg.model.alignmentmodel|AlignmentModel]]. Они содержат в себе информацию о плане линии, продольных и поперечных профилях и прочие данные присущие конкретному типу подобъекта. | + | Подобъекты являются наследниками класса [[developers:references:topomatic.alg.model.alignmentmodel|AlignmentModel]]. Они содержат в себе информацию о плане линии, продольных и поперечных профилях и прочие данные присущие конкретному типу подобъекта. |
При работе с подобъектами, подавляющее большинство операций производится посредством изменения состояния экземпляра класса [[developers:references:topomatic.alg.alignment|Alignment]], получаемого через свойство [[developers:references:topomatic.alg.model.alignmentmodel.alignment|Alignment]] модели подобъекта. | При работе с подобъектами, подавляющее большинство операций производится посредством изменения состояния экземпляра класса [[developers:references:topomatic.alg.alignment|Alignment]], получаемого через свойство [[developers:references:topomatic.alg.model.alignmentmodel.alignment|Alignment]] модели подобъекта. | ||
Строка 10: | Строка 12: | ||
* [[developers:references:topomatic.alg.alignment.stationing|Stationing]] - пикетаж | * [[developers:references:topomatic.alg.alignment.stationing|Stationing]] - пикетаж | ||
* [[developers:references:topomatic.alg.alignment.transitions|Transitions]] - продольные профили | * [[developers:references:topomatic.alg.alignment.transitions|Transitions]] - продольные профили | ||
+ | |||
+ | ===== Подготовка модуля ===== | ||
Создайте и настройте новый [[developers:tutorial:module|модуль]] для подключения к программному комплексу [[http://www.topomatic.ru|Топоматик Робур]]. | Создайте и настройте новый [[developers:tutorial:module|модуль]] для подключения к программному комплексу [[http://www.topomatic.ru|Топоматик Робур]]. | ||
Строка 16: | Строка 20: | ||
* [[developers:references:topomatic.alg|Topomatic.Alg]] - базовые классы подобъектов | * [[developers:references:topomatic.alg|Topomatic.Alg]] - базовые классы подобъектов | ||
- | * [[developers:references:topomatic.alg.runtime|Topomatic.Alg.Runtime]] - возможность использования класса [[developers:references:topomatic.alg.runtime.serviceclasses.activealignmentreciver|ActiveAlignmentReciver]] для получения модели активного подобъекта | ||
* [[developers:references:topomatic.cad.foundation|Topomatic.Cad.Foundation.dll]] - базовые математические типы и операции | * [[developers:references:topomatic.cad.foundation|Topomatic.Cad.Foundation.dll]] - базовые математические типы и операции | ||
* [[developers:references:topomatic.cad.view|Topomatic.Cad.View.dll]] - элемент управления для отображения слоёв моделей | * [[developers:references:topomatic.cad.view|Topomatic.Cad.View.dll]] - элемент управления для отображения слоёв моделей | ||
+ | Выбор подобъекта на экране осуществляется с помощью свойства [[developers:references:topomatic.cad.view.cadview.selectionset|SelectionSet]] класса [[developers:references:topomatic.cad.view.cadview|CadView]]. Подробнее о выборе объектов на экране можно узнать в разделе руководства [[developers:tutorial:cadcursors|Выбор элемента и ввод через курсор]]. Для выбора подобъекта воспользуемся методом [[developers:references:topomatic.cad.view.selectionset.selectobjectsatscreen_system.predicate_1_system.string_arr_system.string|SelectObjectsAtScreen]] с соответствующим [[https://docs.microsoft.com/ru-ru/dotnet/api/system.predicate-1?view=net-6.0|предикатом]]. Выбираемый объект должен реализовывать интерфейс IWrapped, а объект возвращаемый его свойством WrappedObject должен быть экземпляром класса [[developers:references:topomatic.alg.alignment|Alignment]]. | ||
+ | |||
+ | ===== Преобразование координат ===== | ||
+ | |||
+ | В этом примере мы укажем точку на плане и определим соответствующие этой точке пикетаж, смещение от оси и расстояние от начала трассы. | ||
+ | |||
+ | Сперва необходимо получить геометрию плана линии. Для этого у [[developers:references:topomatic.alg.alignment|Alignment]]'а получим значение свойства [[developers:references:topomatic.alg.alignment.plan|Plan]]. Далее у полученного плана линии ([[developers:references:topomatic.alg.plan.planline|PlanLine]]) вернём значение свойства [[developers:references:topomatic.alg.plan.planline.compoundline|CompoundLine]]. Смещение и расстояние от начала трассы получается методом [[developers:references:topomatic.alg.compoundline.postostaoffset_topomatic.cad.foundation.vector2d_ref_system.double_ref_system.double|PosToStaOffset]] класса [[developers:references:topomatic.alg.compoundline|CompoundLine]], которому передаётся указанная на плане точка. | ||
+ | |||
+ | Для преобразования расстояния от начала трассы в пикетаж получим пикетаж подобъекта через свойство [[developers:references:topomatic.alg.alignment.stationing|Stationing]] у [[developers:references:topomatic.alg.alignment|Alignment]]'а. Преобразование осуществляется методом [[developers:references:topomatic.alg.stationing.algbasestationing.stationtostring_system.double|StationToString]] класса [[developers:references:topomatic.alg.stationing.algbasestationing|AlgBaseStationing]]. | ||
+ | |||
+ | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «define_stationing_at_point» предложит пользователю указать точку на плане и определит её пикетаж, расстояние от начала трассы и смещение от оси подобъекта. | ||
+ | |||
+ | <code csharp> | ||
+ | ... | ||
+ | [cmd("define_stationing_at_point")] | ||
+ | private void DefineStationingAtPoint() | ||
+ | { | ||
+ | var cadview = CadView; | ||
+ | if (cadview == null) return; | ||
+ | |||
+ | //Выбираем трассу | ||
+ | object select; | ||
+ | var res = cadview.SelectionSet.SelectOneObjectAtScreen( | ||
+ | o => o is IWrapped && ((IWrapped)o).WrappedObject is Alignment, | ||
+ | out select, "Выберите подобъект:"); | ||
+ | cadview.SelectionSet.Clear(); | ||
+ | if (res != GetPointResult.Accept) return; | ||
+ | |||
+ | var alignment = ((IWrapped)select).WrappedObject as Alignment; | ||
+ | var compound = alignment.Plan.CompoundLine; | ||
+ | var stationing = alignment.Stationing; | ||
+ | |||
+ | //Указываем точку, в которой требуется определить пикетаж | ||
+ | Vector3D point; | ||
+ | var getPointRes = CadCursors.GetPoint(cadview, out point, "Укажите точку определения пикетажа:"); | ||
+ | if (!getPointRes) return; | ||
+ | |||
+ | //Определяем расстояние от начала пути и величину смещения до указанной точки | ||
+ | double station, offset; | ||
+ | var convertRes = compound.PosToStaOffset(point.Pos, out station, out offset); | ||
+ | if (!convertRes) | ||
+ | { | ||
+ | MessageDlg.Show("Не удалось определить расстояние от начала пути в указанной точке.", | ||
+ | MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | //Определяем пикетаж на полученном расстоянии от начала пути и выводим данные на экран | ||
+ | var pkPlus = stationing.StationToString(station); | ||
+ | var msg = string.Join(Environment.NewLine, | ||
+ | $"ПК{pkPlus}", | ||
+ | $"Расстояние: {ValueConverter.FloatToStr(station, 3)}", | ||
+ | $"Смещение: {ValueConverter.FloatToStr(offset, 3)}"); | ||
+ | MessageDlg.Show(msg, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | {{ :developers:tutorial:alignmentedit:tutalgpnttopksta.png?nolink&600 |}} | ||
+ | |||
+ | Далее выполним обратную операцию преобразования. Определим точку на плане по пикетажу и смещению введёнными пользователем. Для этого потребуется преобразовать значение пикетажа в расстояние от начала трассы с помощью метода [[developers:references:topomatic.alg.stationing.algbasestationing.trystringtostation_system.string_ref_system.double|TryStringToStation]] класса [[developers:references:topomatic.alg.stationing.algbasestationing|AlgBaseStationing]]. Точка на плане определяется методом [[developers:references:topomatic.alg.compoundline.staoffsettopos_system.double_system.double_ref_topomatic.cad.foundation.vector2d|StaOffsetToPos]] класса [[developers:references:topomatic.alg.compoundline|CompoundLine]], в который передаётся расстояние от начала трассы и смещение. | ||
+ | |||
+ | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «define_point_at_stationing» предложит пользователю ввести пикетаж и смещение от оси подобъекта и определит координаты точки, а также расстояние от начала трассы для введённых параметров. | ||
+ | |||
+ | <code csharp> | ||
+ | ... | ||
+ | [cmd("define_point_at_stationing")] | ||
+ | private void DefinePointAtStationing() | ||
+ | { | ||
+ | var cadview = CadView; | ||
+ | if (cadview == null) return; | ||
+ | |||
+ | //Выбираем трассу | ||
+ | object select; | ||
+ | var res = cadview.SelectionSet.SelectOneObjectAtScreen( | ||
+ | o => o is IWrapped && ((IWrapped)o).WrappedObject is Alignment, | ||
+ | out select, "Выберите подобъект:"); | ||
+ | cadview.SelectionSet.Clear(); | ||
+ | if (res != GetPointResult.Accept) return; | ||
+ | |||
+ | var alignment = ((IWrapped)select).WrappedObject as Alignment; | ||
+ | var compound = alignment.Plan.CompoundLine; | ||
+ | var stationing = alignment.Stationing; | ||
+ | |||
+ | //Вводим пикетаж и определяем расстояние от начала пути | ||
+ | var pkPlus = "0+00.00"; | ||
+ | res = CadCursors.GetString(cadview, ref pkPlus, "Введите пикетаж в формате ПК+:"); | ||
+ | if (res == GetPointResult.Cancel) return; | ||
+ | |||
+ | double station; | ||
+ | if (!stationing.TryStringToStation(pkPlus, out station)) | ||
+ | { | ||
+ | MessageDlg.Show("Указанный пикетаж не найден.", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | //Вводим смещение | ||
+ | var offset = 0.0; | ||
+ | res = CadCursors.GetDouble(cadview, ref offset, "Введите смещение:"); | ||
+ | if (res == GetPointResult.Cancel) return; | ||
+ | |||
+ | //Определяем координаты по задданым значениям и выводим значения на экран | ||
+ | Vector2D point; | ||
+ | var vectorFound = compound.StaOffsetToPos(station, offset, out point); | ||
+ | if (!vectorFound) | ||
+ | { | ||
+ | MessageDlg.Show("Не удалось определить координаты.", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var msg = string.Join(Environment.NewLine, | ||
+ | $"X: {ValueConverter.FloatToStr(point.X, 3)}", | ||
+ | $"Y: {ValueConverter.FloatToStr(point.Y, 3)}", | ||
+ | $"Расстояние: {ValueConverter.FloatToStr(station, 3)}"); | ||
+ | MessageDlg.Show(msg, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1); | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | {{ :developers:tutorial:alignmentedit:tutalgpkoffsettopos.png?nolink&600 |}} | ||
+ | |||
+ | Теперь необходимо сформировать наш файл .plugin. Заполните его следующим образом. | ||
+ | |||
+ | <code javascript> | ||
+ | { | ||
+ | "assemblies": { | ||
+ | "TutorialEditAlignment": { | ||
+ | "assembly": "TutorialEditAlignment.dll, TutorialEditAlignment.ModulePluginHost" | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | "actions": { | ||
+ | "id_define_stationing_at_point": { | ||
+ | "cmd": "define_stationing_at_point", | ||
+ | "title": "Определить пикетаж в точке" | ||
+ | }, | ||
+ | "id_define_point_at_stationing": { | ||
+ | "cmd": "define_point_at_stationing", | ||
+ | "title": "Определить координаты по пикетажу и смещению" | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | "menubars": { | ||
+ | "rbproj": { | ||
+ | "items": [ | ||
+ | { | ||
+ | "id": "tutorial_menu", | ||
+ | "title": "Tutorial", | ||
+ | "items": [ | ||
+ | "id_define_stationing_at_point", | ||
+ | "id_define_point_at_stationing" | ||
+ | ] | ||
+ | } | ||
+ | ] | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | Результатом запуска проекта будет появление в главном меню пункта «Tutorial», с подпунктами, которые будут работать в соответствии с описанными выше алгоритмами. | ||
+ | <note>[[developers:tutorial:tutorialcode|Исходный код]] примера расположен в проекте **"TutorialEditAlignment"**.</note> |