---- ===== Разработка правила оформления плана ===== ==== Введение ==== Программный комплекс [[http://topomatic.ru|Топоматик Робур]] предоставляет пользователю возможность генерировать плоские чертежи топографических планов в популярных обменных форматах. Генерация примитивов на чертеже плана происходит по принципу **[[https://ru.wikipedia.org/wiki/WYSIWYG|What You See Is What You Get]]** («что видишь, то и получишь»). Другими словами, экспортированный чертёж будет максимально похож на визуальное представление плана в окне Робура. Часто исполнителю необходимо дорабатывать чертёж в соответствии с требованиями к оформлению плана предъявленными заказчиком. Например, требуется заменить типы линий, разбить вставки блоков, изменить цвет определённых примитивов и т.д. Для того, чтобы чертёж экспортировался в соответствии с уникальным требованиями, в программном комплексе Топоматик Робур предусмотрена возможность использования **правил оформления плана**. **Правила оформления плана** применяются при **создании чертежа**. **Правило оформления плана** - это текстовый файл с расширением **".py"**, который содержит инструкции на диалекте **[[https://ironpython.net/|IronPython]]** языка программирования **[[https://www.python.org/|Python]]**. Особенностью диалекта **IronPython** является возможность взаимодействия с **библиотеками классов** платформы **.Net** используемыми в программном комплексе **Топоматик Робур**. Более подробную документацию **IronPython** можно изучить пройдя по **[[https://ironpython.net/documentation/|ссылке]]**. В текущей статье мы рассмотрим только те инструкции **IronPython**, которые необходимые для написания **правила оформления плана**. ==== Создание и редактирование правила оформления плана ==== Для создания и редактирования **правила оформления плана** можно воспользоваться любым удобным для вас текстовым редактором, но лучше всего использовать редакторы способные подсвечивать синтаксис кода на языке **Python**, например **[[https://code.visualstudio.com/|VS Code]]** или **[[https://www.sublimetext.com/|Sublime]]**. ==== Применение правила оформления плана ==== Вставьте рамку листа на план с помощью пункта меню "Рисовать" -> "Планшет" -> "Добавить лист". {{ :developers:tutorial:plan_export_rules:tut_plan_decoration_rule_1.png?nolink |}} {{ :developers:tutorial:plan_export_rules:tut_plan_decoration_rule_2.png?nolink |}} Выберите пункт меню "Проект" -> "Создать чертёж" -> "План..." {{ :developers:tutorial:plan_export_rules:tut_plan_decoration_rule_3.png?nolink |}} Программа предложит вам выбрать на плане лист для формирования чертежа. Выберите лист и подтвердите выбор нажатием клавиши **Enter**. После выбора листа, на экране отобразится мастер **"Создания чертежа планшета"**. {{ :developers:tutorial:plan_export_rules:tut_plan_decoration_rule_4.png?nolink |}} В нижней части окна мастера вы увидите флажок **"Применить правило оформления"**. Установив этот флаг, станут активными список используемых **правил оформления плана** и кнопки **Добавить** и **Удалить**. По умолчанию, в списке правил уже присутствует **правило оформления плана** **"gugk.py"**, изменяющее чертёж плана в соответствии с требованиями кодификатора условных знаков **ГУГК** (Главное Управление Геодезии и Картографии). Правило "**gugk.py**" разработано сотрудниками Топоматик и входит в стандартный пакет установки программных продуктов Робур. {{ :developers:tutorial:plan_export_rules:tut_plan_decoration_rule_5.png?nolink |}} С помощью кнопки **Добавить** вы можете добавить одно или несколько правил оформления плана. После нажатия кнопки **ОК** правила оформления будут применены к экспортируемому чертежу. Правила оформления будут выполняться по очереди, в том порядке, в котором они расположены в списке сверху вниз. ==== Разработка правила оформления плана ==== === Импорт библиотек классов .Net === Создайте текстовый файл с расширением **".py"**. По умолчанию, **правила оформления плана** располагаются в директории ''c:\ProgramData\Topomatic\Robur \16.0\Support\''. Пользовательские правила рекомендуется располагать там, но вы можете расположить их в любом другом доступном месте. **[[https://learn.microsoft.com/ru-ru/dotnet/standard/class-libraries|Библиотеки классов .Net (DLL сборки)]]** - бинарные файлы с расширением **".dll"**, содержащие описание классов объектов, их состояния и методов взаимодействия с ними. Для подгрузки **DLL сборок** в **IronPython** служит модуль **clr** . Его необходимо импортировать с помощью команды ''import''. В теле правила оформления добавьте следующую строку. import clr После того как модуль загружен, можно приступить к подгрузке **DLL сборок**. Для этого воспользуемся методом ''clr.AddReference(assembly_name)'' и передадим в него имя сборки без расширения. Предположим, в процессе работы правила вам потребуется прочитать **XML-файл**. Для этого подгрузим сборку **"System.Xml.dll"**. Так же подгрузим сборку **"Topomatic.Dwg.dll"** для работы с примитивами чертежа. Добавьте следующие строки в файл правила. clr.AddReference("System.Xml") clr.AddReference("Topomatic.Dwg") === Отладка кода === Для отладки кода правила оформления, можно отправлять сообщения в окно командной строки: # Подгрузка библиотеки для доступа к командной строке clr.AddReference("Topomatic.Cad.View") # Текст сообщения msg = "I'm here" # Отправка сообщения в окно командной строки Topomatic.Cad.View.ConsoleListner.Current.WriteLine(msg) === Глобальные переменные === При создании чертежа плана, в среде выполнения **Python** будут проинициализированы переменные, используя которые мы получим доступ к экспортируемому чертежу для последующего изменения его состояния: ^ Переменная ^ Тип ^ Значение ^ | ''__model'' | DwgBlock | Блок пространства модели (Model Space). Основной блок чертежа, содержит примитивы чертежа и ссылки на другие блоки | | ''__path'' | Строка | Путь к файлу исполняемого в текущий момент **правила оформления плана** | | ''__scale'' | Вещественное | Масштаб листа, где 1.0 это М1:1000 | === Коллекции чертежа === Доступ к основным коллекциям элементов чертежа осуществляется с помощью следующих свойств: # Получение чертежа (Drawing) drawing = __model.Drawing # Коллекция примитивов (DwgEntities) entities = __model.Entities # Коллекция блоков (DwgBlocks) blocks = drawing.Blocks # Коллекция размерных стилей (DwgDimensionStyles) dimension_styles = drawing.DimensionStyles # Коллекция слоёв (DwgLayers) layers = drawing.Layers # Коллекция типов линий (DwgLinetypes) linetypes = drawing.Linetypes # Коллекция текстовых стилей (DwgStyles) text_styles = drawing.Styles Подробнее о работе с чертежом можно узнать в разделе руководства **[[developers:tutorial:drawing|Работа с примитивами чертежа]]**. === Пример правила оформления === Рассмотрим пример правила оформления чертежа плана. В примере выполним следующие действия: * Импортируем модуль загрузки библиотек .Net и укажем ссылки на необходимые библиотеки * Импортируем необходимые библиотеки .Net * В коллекцию текстовых стилей чертежа добавим пользовательский текстовый стиль * Всем текстовым примитивам чертежа назначим пользовательский текстовый стиль * В коллекцию слоёв чертежа добавим пользовательский слой * Изменим слой всех примитивов красного цвета на пользовательский и назначим им цвет "По слою" * Выведем информацию о ходе выполнения правила оформления в окно командной строки * Уведомим пользователя о завершении работы правила оформления # coding: windows-1251 # Импорт модуля подгрузки библиотек .Net import clr import dlr # Добавление ссылок на библиотеки .Net clr.AddReference("System.Windows.Forms") clr.AddReference("Topomatic.Cad.Foundation") clr.AddReference("Topomatic.Cad.View") clr.AddReference("Topomatic.Dwg") # В качестве примера взаимодействия с системный библиотеками Windows # добавим библиотеку Windows Forms и для удобства назначим ей псевдоним import System.Windows.Forms as win_forms # Импорт пространств имён начинающихся с Topomatic import Topomatic # Импорт перечисления Topomatic.Cad.Foundation.CadColor # с указанным псевдонимом для удобного доступа в цветовой палитре import Topomatic.Cad.Foundation.CadColor as cad_colors # Инициализация переменных custom_text_style_name = "Custom Text Style" custom_text_style_font_name = "Arial.ttf" custom_layer_name = "Custom Layer" # Определение метода для упрощения процесса отладки @dlr.params(str) def report(msg): """ Отправка сообщения в окно командной строки. Аргументы: msg - строка (str) """ Topomatic.Cad.View.ConsoleListner.Current.WriteLine(msg) # Определение основного метода правила оформления @dlr.params(Topomatic.Dwg.DwgBlock, str, float) def execute(model, path, scale): """ Основной метод правила. Аргументы: model -- Основной блок чертежа (Topomatic.Dwg.DwgBlock), path -- Путь к файлу исполняемого в текущий момент правила оформления плана (str), scale -- Масштаб листа (float) """ # Отправляем в командную строку сообщение о начале выполнения правила report("Начало выполнения правила") # Получаем чертёж необходимые коллекции его элементов drawing = model.Drawing entities = model.Entities # Примитивы layers = drawing.Layers # Слои text_styles = drawing.Styles # Текстовые стили # Получаем пользовательский текстовый стиль text_style = get_or_create_custom_text_style(text_styles) # Меняем текстовый стиль текстовых примитивов на пользовательский if text_style is not None: change_entity_text_style(entities, text_style) # Получаем пользовательский слой layer = get_or_create_custom_layer(layers) # Меняем слой у всех примитивов красного цвета на пользовательский # и устанавливаем им цвет "По слою" if layer is not None: change_entity_layer(entities, layer) # Сообщаем о завершении работы правила с помощью # диалогового окна системной библиотеки Windows Forms win_forms.MessageBox.Show("Правило успешно применено", "Правило оформления чертежа плана", win_forms.MessageBoxButtons.OK, win_forms.MessageBoxIcon.Information) # Определение метода для получения пользовательского текстового стиля @dlr.params(Topomatic.Dwg.DwgStyles) def get_or_create_custom_text_style(text_styles): """ Получение пользовательского текстового стиля. Аргументы: text_styles - Коллекция текстовых стилей (Topomatic.Dwg.DwgStyles) """ # Отправляем в командную строку сообщение о начале получения текстового стиля report("Получение пользовательского текстового стиля") # Получение текстового стиля по имени из коллекции # Если стиль не обнаружен, то добавляем его и устанавливаем # значения необходимых параметров style = text_styles[custom_text_style_name] if style == None: style = text_styles.Add(custom_text_style_name, custom_text_style_font_name) style.Height = 3 style.Ratio = 0.8 # Возвращаем пользовательский текстовый стиль return style # Определение метода для изменения текстового стиля текстовых примитивов @dlr.params(Topomatic.Dwg.DwgEntities, Topomatic.Dwg.DwgStyle) def change_entity_text_style(entities, text_style): """ Изменение текстового стиля текстовых примитивов. Аргументы: entities - Коллекция примитивов (Topomatic.Dwg.DwgEntities) text_style - Текстовый стиль (Topomatic.Dwg.DwgStyle) """ # Отправляем в командную строку сообщение о начале получения текстового стиля report("Изменение текстового стиля текстовых примитивов") # Проходим по коллекции примитивов и если примитив это # Текст (DwgText) или Мультитекст (DwgMText), # то меняем его текстовый стиль на пользовательский for i in xrange(0, entities.Count - 1): entity = entities[i] if (isinstance(entity, Topomatic.Dwg.Entities.DwgText)) or (isinstance(entity, Topomatic.Dwg.Entities.DwgMText)): entity.Style = text_style # Определение метода для получения пользовательского слоя @dlr.params(Topomatic.Dwg.DwgLayers) def get_or_create_custom_layer(layers): """ Получение пользовательского слоя. Аргументы: layers - Коллекция слоёв (Topomatic.Dwg.DwgLayers) """ # Отправляем в командную строку сообщение о начале получения слоя report("Получение пользовательского слоя") # Получение слоя по имени из коллекции # Если слой не обнаружен, то добавляем его и устанавливаем # значения красный цвета слоя используя псевдоним cad_colors layer = layers[custom_layer_name] if layer == None: layer = layers.Add(custom_layer_name) layer.Color = cad_colors.Red # Возвращаем пользовательский слой return layer # Определение метода для изменения слоя у примитивов красного цвета @dlr.params(Topomatic.Dwg.DwgEntities, Topomatic.Dwg.DwgLayer) def change_entity_layer(entities, layer): """ Изменение слоя примитивов красного цвета на пользовательский и назначение им цвета "По слою". Аргументы: entities - Коллекция примитивов (Topomatic.Dwg.DwgEntities) layer - Слой (Topomatic.Dwg.DwgLayer) """ # Отправляем в командную строку сообщение о начале изменения слоя примитивов красного цвета report("Изменение слоя примитивов красного цвета и назначение им цвета \"По слою\"") # Проходим по коллекции примитивов и если примитив это # Текст (DwgText) или Мультитекст (DwgMText), то меняем его текстовый стиль for i in xrange(0, entities.Count - 1): entity = entities[i] if (entity.Color == cad_colors.Red): entity.Layer = layer entity.Color = cad_colors.ByLayer # Точка входа. # Если переменная '__model' проинициализирована, # то изменяем чертёж if (__model != None): execute(__model, __path, __scale) else: raise AssertionError("\"__model\" variable is not defined")