Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
developers:tutorial:dwpfields [2022/08/12 10:44] proxor [Алгоритм создания пользовательского тега] |
developers:tutorial:dwpfields [2023/07/31 08:46] (текущий) yulia |
||
---|---|---|---|
Строка 2: | Строка 2: | ||
- | В программном комплексе [[http://topomatic.ru/|Топоматик Робур]] чертежи профилей генерируются на основе шаблонов. Шаблон чертежа профиля представляет из себя файл в формате [[https://ru.wikipedia.org/wiki/DXF|DXF (Drawing eXchange Format)]]. При генерации чертежа используются специальные динамические объекты называемые [[road:commons_tasks:basic_codes_rail_subobject:start|тегами]]. Теги это элементы шаблона чертежа, которые представляют необходимую информацию о модели в требуемом графическом виде. | + | В программном комплексе [[http://topomatic.ru/|Топоматик Робур]] чертежи профилей генерируются на основе шаблонов. Шаблон чертежа профиля представляет из себя файл в формате [[https://ru.wikipedia.org/wiki/DXF|DXF (Drawing eXchange Format)]]. При генерации чертежа используются специальные динамические объекты называемые [[road:commons_tasks:archive_sections:format_template_drawing:basic_codes_rail_subobject:start|тегами]]. Теги это элементы [[road:commons_tasks:archive_sections:format_template_drawing_cross_profile:start|шаблона чертежа]], которые представляют необходимую информацию о модели в требуемом графическом виде. |
- | ==== Алгоритм создания пользовательского тега ==== | + | ==== Создания пользовательского тега ==== |
Для создания пользовательского тега необходимы следующие действия: | Для создания пользовательского тега необходимы следующие действия: | ||
- Создание класса тега, содержащего алгоритм отрисовки графической информации на чертеже | - Создание класса тега, содержащего алгоритм отрисовки графической информации на чертеже | ||
- Создание класса провайдера тега, отвечающего за регистрацию его в системе | - Создание класса провайдера тега, отвечающего за регистрацию его в системе | ||
- | - Добавление команды регистрирующей тег в теле пользовательского модуля | + | - Объявление команды регистрирующей тег и добавление таска для регистрации тега при инициализации пользовательского модуля |
- | - Добавление таска для регистрации тега при инициализации пользовательского модуля | + | |
- | - Создание в plugin файле action'a добавления тега в шаблон чертежа | + | <note>При необходимости, в plugin файле можно объявить action добавления тега в шаблон чертежа</note> |
Программно, тег является классом наследником от [[developers:references:topomatic.plt.templates.prf.prffield|PrfField]] для продольного профиля и [[developers:references:topomatic.plt.templates.crs.crsfield|CrsField]] для поперечного профиля. Оба эти класса, в свою очередь, являются наследниками класса [[developers:references:topomatic.plt.templates.common.templatefield|TemplateField]]. Класс тега содержит его свойства и описание алгоритмов построения графических примитивов. | Программно, тег является классом наследником от [[developers:references:topomatic.plt.templates.prf.prffield|PrfField]] для продольного профиля и [[developers:references:topomatic.plt.templates.crs.crsfield|CrsField]] для поперечного профиля. Оба эти класса, в свою очередь, являются наследниками класса [[developers:references:topomatic.plt.templates.common.templatefield|TemplateField]]. Класс тега содержит его свойства и описание алгоритмов построения графических примитивов. | ||
Строка 35: | Строка 35: | ||
==== Добавление графических примитивов ==== | ==== Добавление графических примитивов ==== | ||
- | Добавление графических примитивов в чертёж (Drawing) описано в главе руководства "Работа с примитивами чертежа". Доступ к чертежу (Drawing) осуществляется с помощью свойства Drawing унаследованного нашим классом от PrfField. | + | Добавление графических примитивов в чертёж ([[developers:references:topomatic.dwg.drawing|Drawing]]) описано в главе руководства "[[developers:tutorial:drawing|Работа с примитивами чертежа]]". Доступ к чертежу ([[developers:references:topomatic.dwg.drawing|Drawing]]) осуществляется с помощью свойства [[developers:references:topomatic.plt.templates.common.templatefield.drawing|Drawing]] унаследованного нашим классом от [[developers:references:topomatic.plt.templates.prf.prffield|PrfField]]. |
- | В программном комплексе Топоматик Робур реализован механизм динамических чертежей. Данный механизм позволяет изменять положение примитивов в макете чертежа, не теряя при этом связи с исходной моделью. Например, мы можем переместить группу примитивов объединённых одним ключом в макете чертежа. При изменении состояния исходной модели смещение ключа останется. | + | В программном комплексе [[http://topomatic.ru/|Топоматик Робур]] реализован механизм динамических чертежей. Данный механизм позволяет изменять положение примитивов в [[road:commons_tasks:general_information_layouts_drawings:start|макете чертежа]], не теряя при этом связи с исходной моделью. Например, мы можем переместить группу примитивов объединённых одним ключом в макете чертежа. При изменении состояния исходной модели смещение ключа останется. |
Например: | Например: | ||
- Исходное состояние | - Исходное состояние | ||
- | {{ :developers:tutorial:alignmentedit:tutdyndrawing1.png?nolink&600 |}} | + | {{ :developers:tutorial:alignmentedit:tutdyndrawing1.png?nolink&400 |}} |
- После изменения положения группы примитивов объединённых общим ключом | - После изменения положения группы примитивов объединённых общим ключом | ||
- | {{ :developers:tutorial:alignmentedit:tutdyndrawing2.png?nolink&600 |}} | + | {{ :developers:tutorial:alignmentedit:tutdyndrawing2.png?nolink&400 |}} |
- После изменения модели | - После изменения модели | ||
- | {{ :developers:tutorial:alignmentedit:tutdyndrawing3.png?nolink&600 |}} | + | {{ :developers:tutorial:alignmentedit:tutdyndrawing3.png?nolink&400 |}} |
Чтобы положение примитивов можно было изменять в пространстве макета, необходимо воспользоваться следующей конструкцией: | Чтобы положение примитивов можно было изменять в пространстве макета, необходимо воспользоваться следующей конструкцией: | ||
Строка 61: | Строка 61: | ||
</code> | </code> | ||
- | Так же можно воспользоваться методом DrawMockupText(), если необходимо создать текстовый примитив с возможностью изменять его местоположение в макете. | + | Так же можно воспользоваться методом [[developers:references:topomatic.plt.templates.common.templatefield.drawmockuptext|DrawMockupText()]], если необходимо создать текстовый примитив с возможностью изменять его местоположение в макете. |
==== Масштабирование координат ==== | ==== Масштабирование координат ==== | ||
Строка 70: | Строка 70: | ||
В классическом представлении, координатами продольного профиля являются высотная отметка (Y) и пикетажное положение (X). При моделировании трассы, пикетажное положение является значением производным от расстояния до начала трассы. Для преобразования координат продольного профиля следует пользоваться специальными методами: | В классическом представлении, координатами продольного профиля являются высотная отметка (Y) и пикетажное положение (X). При моделировании трассы, пикетажное положение является значением производным от расстояния до начала трассы. Для преобразования координат продольного профиля следует пользоваться специальными методами: | ||
- | * ScaleElevation() - пересчёт высотной отметки в соответствии с вертикальным масштабом чертежа | + | * [[developers:references:topomatic.plt.templates.prf.prffield.scaleelevation|ScaleElevation()]] - пересчёт высотной отметки в соответствии с вертикальным масштабом чертежа |
- | * ScaleStation() - пересчёт расстояния от начала пути в соответствии с горизонтальным масштабом чертежа | + | * [[developers:references:topomatic.plt.templates.prf.prffield.scalestation|ScaleStation()]] - пересчёт расстояния от начала пути в соответствии с горизонтальным масштабом чертежа |
=== Поперечный профиль === | === Поперечный профиль === | ||
Координатами поперечного профиля являются высотная отметка (Y) и величина смещения от оси базовой трассы (X). Для преобразования координат поперечного профиля следует пользоваться специальными методами: | Координатами поперечного профиля являются высотная отметка (Y) и величина смещения от оси базовой трассы (X). Для преобразования координат поперечного профиля следует пользоваться специальными методами: | ||
- | * ScaleElevation() - пересчёт высотной отметки в соответствии с вертикальным масштабом чертежа | + | * [[developers:references:topomatic.plt.templates.crs.crsfield.scaleelevation|ScaleElevation()]] - пересчёт высотной отметки в соответствии с вертикальным масштабом чертежа |
- | * ScaleOffset() - пересчёт горизонтального смещения в соответствии с горизонтальным масштабом чертежа | + | * [[developers:references:topomatic.plt.templates.crs.crsfield.scaleoffset|ScaleOffset()]] - пересчёт горизонтального смещения в соответствии с горизонтальным масштабом чертежа |
==== Пользовательский тег динамического чертежа продольного профиля ==== | ==== Пользовательский тег динамического чертежа продольного профиля ==== | ||
Строка 83: | Строка 83: | ||
В этом примере мы создадим тег для чертежа продольного профиля и зарегистрируем его. Тег будет отрисовывать отметки точек экстремума чёрного и красного профилей. | В этом примере мы создадим тег для чертежа продольного профиля и зарегистрируем его. Тег будет отрисовывать отметки точек экстремума чёрного и красного профилей. | ||
- | Создадим класс тега. Так как тег предназначен для продольного профиля, то наследовать наш класс мы будем от PrfField. Добавим нашему классу свойство Precision, которое будет определять количество знаков после запятой у отрисовываемых отметок. Свойство следует декорировать атрибутом DisplayNameAttribute или его наследником, для получения имени свойства из ресурсов нашей сборки. В нашем случае напишем свой класс наследник DisplayNameAttribute для удобства отладки. В конструкторе класса проинициализаруем свойство нужным значением. | + | Создадим класс тега. Так как тег предназначен для продольного профиля, то наследовать наш класс мы будем от [[developers:references:topomatic.plt.templates.prf.prffield|PrfField]]. Добавим нашему классу свойство **Precision**, которое будет определять количество знаков после запятой у отрисовываемых отметок. Свойство следует декорировать атрибутом [[https://docs.microsoft.com/ru-ru/dotnet/api/system.componentmodel.displaynameattribute?view=net-6.0|DisplayNameAttribute]] или его наследником, для получения имени свойства из ресурсов нашей сборки. В нашем случае напишем свой класс наследник [[https://docs.microsoft.com/ru-ru/dotnet/api/system.componentmodel.displaynameattribute?view=net-6.0|DisplayNameAttribute]] для удобства отладки. В конструкторе класса проинициализируем свойство нужным значением. |
- | Алгоритм отрисовки графических и текстовых примитивов описывается в методе OnDrawField(), который необходимо перекрыть. Вернём словарь данных нашего тега через свойство DataManager. С его помощью мы получим указатель на активный продольный профиль (Transition) по ключевому слову "ActiveTransition". Для нашей задачи потребуются линии черного и красного профилей, которые мы получим через свойства EgProfile и RedProfile соответветвенно у активного профиля. Подробнее о классе Transition можно узнать в разделе руководства "Редактирование плана и профиля" в подразделе Редактирование профиля. | + | Алгоритм отрисовки графических и текстовых примитивов описывается в методе [[developers:references:topomatic.plt.templates.prf.prffield.ondrawfield|OnDrawField()]], который необходимо перекрыть. Вернём словарь данных нашего тега через свойство [[developers:references:topomatic.plt.templates.common.templatefield.datamanager|DataManager]]. С его помощью мы получим указатель на активный продольный профиль ([[developers:references:topomatic.alg.prf.transition|Transition]]) по ключевому слову **"ActiveTransition"**. Для нашей задачи потребуются линии черного и красного профилей, которые мы получим через свойства [[developers:references:topomatic.alg.prf.transition.egprofile|EgProfile]] и [[developers:references:topomatic.alg.prf.transition.redprofile|RedProfile]] соответственно у активного профиля. Подробнее о классе [[developers:references:topomatic.alg.prf.transition|Transition]] можно узнать в разделе руководства "[[developers:tutorial:algedit|Редактирование плана и профиля]]" в подразделе **Редактирование профиля**. |
- | Отметку и расстояние узла профиля можно получить с помощью свойств Elevation и Station соответственно. | + | Отметку и расстояние узла профиля можно получить с помощью свойств [[developers:references:topomatic.alg.prf.profilenode.elevation|Elevation]] и [[developers:references:topomatic.alg.prf.profilenode.station|Station]] соответственно. |
- | В процессе вычислений, нам необходимо проверять, попадает ли текущий узел профиля в границы чертежа, чтобы тег не производил отрисовку примитивов за его вне границ и не тратил время на избыточные вычисления. Чтобы понять, находимся ли мы в границах чертежа, следует воспользоваться методом StationInLimits() статического класса AlignmentValueConverter. В качестве аргументов метод принимает проверяемое расстояние от начала пути, а так же расстояния начала и конца границы чертежа. Значение расстояний начала и конца границ чертежа можно получить с помощью свойств StartSta и EndSta унаследованных нашим классом от PrfField. | + | В процессе вычислений, нам необходимо проверять, попадает ли текущий узел профиля в границы чертежа, чтобы тег не производил отрисовку примитивов за его вне границ и не тратил время на избыточные вычисления. Чтобы понять, находимся ли мы в границах чертежа, следует воспользоваться методом [[developers:references:topomatic.alg.alignmentvalueconverter.stationinlimits_system.double_system.double_system.double_system.boolean_system.boolean|StationInLimits()]] статического класса [[developers:references:topomatic.alg.alignmentvalueconverter|AlignmentValueConverter]]. В качестве аргументов метод принимает проверяемое расстояние от начала пути, а так же расстояния начала и конца границы чертежа. Значение расстояний начала и конца границ чертежа можно получить с помощью свойств [[developers:references:topomatic.plt.templates.prf.prffield.startsta|StartSta]] и [[developers:references:topomatic.plt.templates.prf.prffield.endsta|EndSta]] унаследованных нашим классом от [[developers:references:topomatic.plt.templates.prf.prffield|PrfField]]. |
Добавьте в программу новый класс со следующим содержанием: | Добавьте в программу новый класс со следующим содержанием: | ||
Строка 224: | Строка 224: | ||
</code> | </code> | ||
- | Теперь необходимо создать провайдер, главной функцией которого будет регистрация нашего тега. Провайдер должен наследоваться от класса TemplateFieldProvider и перекрывать метод Provide(). Провайдер регистрирует тег с помощью метода RegisterFieldAlias() обработчика шаблонов (TemplateProcessor). Этот метод вернёт дескриптор зарегистрированного тега, в который следует добавить свойства, которые в последствии будут отборажаться на панели свойств во время редактирования шаблона чертежа. | + | Теперь необходимо создать провайдер, главной функцией которого будет регистрация нашего тега. Провайдер должен наследоваться от класса [[developers:references:topomatic.plt.templates.templatefieldprovider|TemplateFieldProvider]] и перекрывать метод [[developers:references:topomatic.plt.templates.templatefieldprovider.provide_topomatic.plt.templates.common.templateprocessor|Provide()]]. Провайдер регистрирует тег с помощью метода [[developers:references:topomatic.plt.templates.common.templateprocessor.registerfieldalias_system.string_system.string|RegisterFieldAlias()]] обработчика шаблонов ([[developers:references:topomatic.plt.templates.common.templateprocessor|TemplateProcessor]]). Этот метод вернёт дескриптор зарегистрированного тега, в который следует добавить свойства, которые в последствии будут отображаться на панели свойств во время редактирования шаблона чертежа. |
Добавьте в программу новый класс со следующим содержанием: | Добавьте в программу новый класс со следующим содержанием: | ||
Строка 250: | Строка 250: | ||
В этом примере мы создадим тег для чертежа поперечного профиля и зарегистрируем его. Конструктивно, создание тега поперечного профиля и тега продольного профиля во многом идентично. Аналогично примеру для продольного профиля, тег будет отрисовывать отметки точек экстремума контура сечения земли и контура проектной конструкции. | В этом примере мы создадим тег для чертежа поперечного профиля и зарегистрируем его. Конструктивно, создание тега поперечного профиля и тега продольного профиля во многом идентично. Аналогично примеру для продольного профиля, тег будет отрисовывать отметки точек экстремума контура сечения земли и контура проектной конструкции. | ||
- | Создадим класс тега. Так как тег предназначен для поперечного профиля, то наследовать наш класс мы будем от CrsField. Добавим нашему классу свойство Precision, которое будет определять количество знаков после запятой у отрисовываемых отметок. Свойство следует декорировать атрибутом DisplayNameAttribute или его наследником, для получения имени свойства из ресурсов нашей сборки. В нашем случае напишем свой класс наследник DisplayNameAttribute для удобства отладки. В конструкторе класса проинициализаруем свойство нужным значением. | + | Создадим класс тега. Так как тег предназначен для поперечного профиля, то наследовать наш класс мы будем от [[developers:references:topomatic.plt.templates.crs.crsfield|CrsField]]. Добавим нашему классу свойство **Precision**, которое будет определять количество знаков после запятой у отрисовываемых отметок. Свойство следует декорировать атрибутом [[https://docs.microsoft.com/ru-ru/dotnet/api/system.componentmodel.displaynameattribute?view=net-6.0|DisplayNameAttribute]] или его наследником, для получения имени свойства из ресурсов нашей сборки. В нашем случае напишем свой класс наследник [[https://docs.microsoft.com/ru-ru/dotnet/api/system.componentmodel.displaynameattribute?view=net-6.0|DisplayNameAttribute]] для удобства отладки. В конструкторе класса проинициализируем свойство нужным значением. |
- | Алгоритм отрисовки графических и текстовых примитивов описывается в методе OnDrawField(), который необходимо перекрыть. Вернём словарь данных нашего тега через свойство DataManager. С его помощью мы получим указатель на базовый подобъект (Alignment) по ключевому слову "Alignment". Для нашей задачи потребуются контур сечения земли и контур проектной конструкции, которые мы получим из контекста конструирования поперечного профиля (CrsDesignContext). Подробнее о классе CrsDesignContext и контурах поперечного профиля можно узнать в разделе руководства "Выбор объектов на поперечном профиле" в подразделе Контекст конструирования поперечного профиля. | + | Алгоритм отрисовки графических и текстовых примитивов описывается в методе [[developers:references:topomatic.plt.templates.prf.crsfield.ondrawfield|OnDrawField()]], который необходимо перекрыть. Вернём словарь данных нашего тега через свойство [[developers:references:topomatic.plt.templates.common.templatefield.datamanager|DataManager]]. С его помощью мы получим указатель на базовый подобъект ([[developers:references:topomatic.alg.alignment|Alignment]]) по ключевому слову **"Alignment"**. Для нашей задачи потребуются контур сечения земли и контур проектной конструкции, которые мы получим из контекста конструирования поперечного профиля ([[developers:references:topomatic.crs.templates.crsdesigncontext|CrsDesignContext]]). Подробнее о классе [[developers:references:topomatic.crs.templates.crsdesigncontext|CrsDesignContext]] и контурах поперечного профиля можно узнать в разделе руководства "[[developers:tutorial:crsselection|Выбор объектов на поперечном профиле]]" в подразделе **Контекст конструирования поперечного профиля**. |
- | Индекс поперечного профиля получается с помощью свойства SectionIndex унаследованного от CrsField. Получим контекст конструирования поперечного профиля по индексу поперечного профиля с помощью свойства Item[Int32] класса Corridor (подробнее о получении Corridor можно узнать из раздела руководства Выбор модели подобъекта и преобразование координат). | + | Индекс поперечного профиля получается с помощью свойства [[developers:references:topomatic.plt.templates.crs.crsfield.sectionindex|SectionIndex]] унаследованного от [[developers:references:topomatic.plt.templates.crs.crsfield|CrsField]]. Получим контекст конструирования поперечного профиля по индексу поперечного профиля с помощью свойства [[developers:references:topomatic.alg.crs.corridor.item_system.int32|Item[Int32]]] класса [[developers:references:topomatic.alg.crs.corridor|Corridor]] (подробнее о получении [[developers:references:topomatic.alg.crs.corridor|Corridor]] можно узнать из раздела руководства "[[developers:tutorial:algstationing|Выбор модели подобъекта и преобразование координат]]"). |
Добавьте в программу новый класс со следующим содержанием: | Добавьте в программу новый класс со следующим содержанием: | ||
Строка 437: | Строка 437: | ||
</code> | </code> | ||
- | Остаётся зарегистрировать соответствующие таски. Для этого в классе наследнике от PluginHostInitializator нашего модуля следует перекрыть метод Initialize() и добавить в него соответствующие инструкции. Пример такого класса будет выглядеть так: | + | Остаётся зарегистрировать соответствующие таски. Для этого в классе наследнике от [[developers:references:topomatic.applicationplatform.plugins.pluginhostinitializator|PluginHostInitializator]] нашего модуля следует перекрыть метод [[developers:references:topomatic.applicationplatform.plugins.pluginhostinitializator.initialize|Initialize()]] и добавить в него соответствующие инструкции. Пример такого класса будет выглядеть так: |
<code csharp> | <code csharp> | ||
... | ... | ||
Строка 463: | Строка 463: | ||
Редактировать шаблон чертежа можно изменяя содержимое текстовых примитивов посредством DXF-редактора, но более удобно воспользоваться редактором шаблонов программного комплекса Топоматик Робур. | Редактировать шаблон чертежа можно изменяя содержимое текстовых примитивов посредством DXF-редактора, но более удобно воспользоваться редактором шаблонов программного комплекса Топоматик Робур. | ||
- | Для добавление тега в редакторе шаблонов нужно создать новый action в plugin файле. Action должен вызывать команду в формате | + | Для добавление тега в редакторе шаблонов нужно создать новый **action** в **plugin** файле. **Action** должен вызывать команду в формате |
<code>"insert_template_field \"<Выравнивание> <Индекс_подобъекта> <Идентификатор_тега> <Атрибуты_через_пробел>\""</code> | <code>"insert_template_field \"<Выравнивание> <Индекс_подобъекта> <Идентификатор_тега> <Атрибуты_через_пробел>\""</code> | ||
- | В шаблоне чертежа тег является текстовым примитивом, содержание которого представлено в формате "$<Имя_тега>". Так же после имени тега, в тексте могут содержаться атрибуты разделённые пробелами. Атрибуты определяют значения свойств тега по порядку. Порядок свойств тега соответствует порядку свойств добавленных при регистрации тега. | + | В шаблоне чертежа тег является текстовым примитивом, содержание которого представлено в формате "**$<Имя_тега>**". Так же после имени тега, в тексте могут содержаться атрибуты разделённые пробелами. Атрибуты определяют значения свойств тега по порядку. Порядок свойств тега соответствует порядку свойств добавленных при регистрации тега. |
Механизм построения чертежа определяет все текстовые примитивы с вышеописанным содержанием. Далее эти примитивы заменяются на наборы примитивов, построенные подпрограммами соответствующих тегов. | Механизм построения чертежа определяет все текстовые примитивы с вышеописанным содержанием. Далее эти примитивы заменяются на наборы примитивов, построенные подпрограммами соответствующих тегов. | ||
- | Теперь необходимо сформировать наш файл .plugin. Добавим action'ы Заполните его следующим образом. | + | Теперь необходимо сформировать наш файл .plugin. Заполните его следующим образом. |
<code javascript> | <code javascript> |