Инструменты пользователя

Инструменты сайта


Боковая панель

developers:tutorial:algstationing

Выбор модели подобъекта и преобразование координат

В терминологии программного комплекса Топоматик Робур подобъектами принято называть модели автомобильных и железных дорог, а также модели трасс.

Подобъекты являются наследниками класса AlignmentModel. Они содержат в себе информацию о плане линии, продольных и поперечных профилях и прочие данные присущие конкретному типу подобъекта.

При работе с подобъектами, подавляющее большинство операций производится посредством изменения состояния экземпляра класса Alignment, получаемого через свойство Alignment модели подобъекта.

Доступ к наиболее часто используемые данным подобъекта осуществляется через следующие свойства Alignment:

Подготовка модуля

Создайте и настройте новый модуль для подключения к программному комплексу Топоматик Робур.

С помощью диалогового окна Менеджер ссылок добавьте ссылки на следующие библиотеки:

Выбор подобъекта на экране осуществляется с помощью свойства SelectionSet класса CadView. Подробнее о выборе объектов на экране можно узнать в разделе руководства Выбор элемента и ввод через курсор. Для выбора подобъекта воспользуемся методом SelectObjectsAtScreen с соответствующим предикатом. Выбираемый объект должен реализовывать интерфейс IWrapped, а объект возвращаемый его свойством WrappedObject должен быть экземпляром класса Alignment.

Преобразование координат

В этом примере мы укажем точку на плане и определим соответствующие этой точке пикетаж, смещение от оси и расстояние от начала трассы.

Сперва необходимо получить геометрию плана линии. Для этого у Alignment'а получим значение свойства Plan. Далее у полученного плана линии (PlanLine) вернём значение свойства CompoundLine. Смещение и расстояние от начала трассы получается методом PosToStaOffset класса CompoundLine, которому передаётся указанная на плане точка.

Для преобразования расстояния от начала трассы в пикетаж получим пикетаж подобъекта через свойство Stationing у Alignment'а. Преобразование осуществляется методом StationToString класса AlgBaseStationing.

В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «define_stationing_at_point» предложит пользователю указать точку на плане и определит её пикетаж, расстояние от начала трассы и смещение от оси подобъекта.

...
    [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);
    }
...

Далее выполним обратную операцию преобразования. Определим точку на плане по пикетажу и смещению введёнными пользователем. Для этого потребуется преобразовать значение пикетажа в расстояние от начала трассы с помощью метода TryStringToStation класса AlgBaseStationing. Точка на плане определяется методом StaOffsetToPos класса CompoundLine, в который передаётся расстояние от начала трассы и смещение.

В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «define_point_at_stationing» предложит пользователю ввести пикетаж и смещение от оси подобъекта и определит координаты точки, а также расстояние от начала трассы для введённых параметров.

...
    [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);
    }
...

Теперь необходимо сформировать наш файл .plugin. Заполните его следующим образом.

{
  "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"
          ]
        }
      ]
    }
  }
}

Результатом запуска проекта будет появление в главном меню пункта «Tutorial», с подпунктами, которые будут работать в соответствии с описанными выше алгоритмами.

Исходный код примера расположен в проекте «TutorialEditAlignment».
developers/tutorial/algstationing.txt · Последние изменения: 2022/07/12 20:43 — proxor