Здесь показаны различия между двумя версиями данной страницы.
Предыдущая версия справа и слева Предыдущая версия Следующая версия | Предыдущая версия | ||
developers:tutorial:sfcselection [2022/03/15 17:27] proxor [Выделение элементов поверхности] |
developers:tutorial:sfcselection [2022/04/09 18:55] proxor [Выделение горизонталей] |
||
---|---|---|---|
Строка 55: | Строка 55: | ||
Для этого воспользуемся методом ''SelectPoints()'' у слоя текущей поверхности (''SurfaceLayer''). Так как метод ''SelectPoints()'' предоставляет пользователю возможность выбора элементов контекстного меню, то возвращаемое значение будет иметь вид ''GetPointResult'', которое укажет на то, какое именно действие было совершено пользователем. | Для этого воспользуемся методом ''SelectPoints()'' у слоя текущей поверхности (''SurfaceLayer''). Так как метод ''SelectPoints()'' предоставляет пользователю возможность выбора элементов контекстного меню, то возвращаемое значение будет иметь вид ''GetPointResult'', которое укажет на то, какое именно действие было совершено пользователем. | ||
- | Для того чтобы получить множество выбранных точек, будет необходимо воспользоваться методом ''GetSelectedPoints()'' у того же ''SurfaceLayer''. Далее пройдёмся по выбранным точкам циклом ''foreach'' и применим необходимую логику для расчёта средней отметки. | + | Для того чтобы получить множество выбранных точек, будет необходимо воспользоваться методом ''GetSelectedPoints()'' у того же ''SurfaceLayer''. |
- | {{ :developers:tutorial:surfaceelementsselect:tutselpoints.png?nolink&600 |}} | + | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда "calculate_average_elevation" предложит пользователю выбрать точки поверхности и посчитает их среднюю отметку. |
- | + | ||
- | Ниже представлен код примера, который мы оформим в качестве метода ''CalculateAverageElevation()'' с атрибутом ''[cmd("calculate_average_elevation")]''. Данный метод мы поместим в класс ''Module'' для возможности последующего вызова этой команды из командной строки. | + | |
<code csharp> | <code csharp> | ||
Строка 97: | Строка 95: | ||
</code> | </code> | ||
+ | {{ :developers:tutorial:surfaceelementsselect:tutselpoints.png?nolink&600 |}} | ||
Строка 102: | Строка 101: | ||
===== Выделение структурных линий ===== | ===== Выделение структурных линий ===== | ||
- | В данном примере мы попробуем рассчитать максимальный уклон среди всех сегментов структурной линии. | + | В данном примере мы рассчитаем максимальный уклон среди всех сегментов структурной линии. |
- | Как и в предыдущем примере, для выбора структурной линии нам потребуется слой текущей поверхности (''SurfaceLayer''). Чтобы выбрать одну структурную линию, воспользуемся методом ''SelectOneStructureLine()''. Здесь возвращаемым значением сразу же будет выступать выбранная структурная линия (''StructureLine''), поэтому никаких дополнительных действий выполнять не придется. | + | Как и в предыдущем примере, для выбора структурной линии нам потребуется слой текущей поверхности (''SurfaceLayer''). Чтобы выбрать одну структурную линию, воспользуемся методом ''SelectOneStructureLine()''. Здесь возвращаемым значением сразу же будет выбранная [[developers:references:topomatic.sfc.structureline|структурная линия]], поэтому никаких дополнительных действий выполнять не придется. |
- | Воспользуемся циклом ''for'', чтобы обратиться к узлам структурной линии и в каждой итерации будет обращаться к текущей точке цикла и к следующей, тем самым получая представление о сегменте структурной линии. | + | <note>Важно помнить, что [[developers:references:topomatic.sfc.structurelinenode|узел структурной линии]] всегда опирается на [[developers:references:topomatic.sfc.surfacepoint|точку поверхности]], индекс которой хранится в поле [[developers:references:topomatic.sfc.structurelinenode.index|StructureLineNode.Index]]. Узел не несёт информации о его плановом положении, но при помощи индекса опорной точки, мы можем найти её в [[developers:references:topomatic.sfc.surfacepointarray|массиве точек поверхности]] и получить необходимые данные о расположении этого узла в пространстве.</note> |
- | <note>Для того чтобы мы не получили исключение в результате обращения к последующему узлу структурной линии в последней итерации, заведомо уменьшим количество итераций цикла на 1.</note> | + | |
- | <note>Важно помнить, что узел структурной линии всегда опирается на точку поверхности, индекс которой хранится в поле ''StructureLineNode.Index''. Узел не несёт информации о его плановом положении, но при помощи индекса опорной точки, мы можем найти её в массиве точек поверхности и получить необходимые данные о расположении этого узла в пространстве.</note> | + | |
- | В ходе цикла определяется уклон сегмента на текущей итерации и если он больше, чем предыдущее значение, то запоминаем его и, после выхода из цикла, выводим диалоговое окно с рассчитанными данными. | + | |
- | {{ :developers:tutorial:surfaceelementsselect:tutselstrline.png?nolink&600 |}} | + | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда «define_steepest_grade» предложит пользователю выбрать структурную линию и определит максимальный уклон среди всех её сегментов. |
- | + | ||
- | Ниже представлен код примера, который мы оформим в качестве метода ''DefineSteepestGrade()'' с атрибутом ''[cmd(«define_steepest_grade»)]''. Данный метод мы поместим в класс Module для возможности последующего вызова этой команды из командной строки. | + | |
<code csharp> | <code csharp> | ||
Строка 156: | Строка 150: | ||
</code> | </code> | ||
+ | {{ :developers:tutorial:surfaceelementsselect:tutselstrline.png?nolink&600 |}} | ||
===== Выделение горизонталей ===== | ===== Выделение горизонталей ===== | ||
+ | По умолчанию, в программном комплексе [[http://topomatic.ru|Топоматик Робур]], выделение горизонталей отключено. Чтобы включить выделение горизонталей нужно изменить значение статического свойства ''SurfaceLayer.SurfaceSelectionSet.IsHorizontalSelectable'' на ''true''. Взаимодействовать с объектами горизонталей напрямую нельзя, но горизонтали реализуют интерфейс [[developers:references:topomatic.cad.foundation.ilinearobject|ILinearObject]], поэтому мы можем получить [[developers:references:topomatic.cad.foundation.polyline3d|трёхмерную полилинию]] описывающую положение горизонтали, воспользовавшись методом [[developers:references:topomatic.cad.foundation.ilinearobject.getpolyline_topomatic.cad.foundation.ipolyline3d|GetPolyline()]]. Для получения площади [[developers:references:topomatic.cad.foundation.polyline3d|трёхмерной полилинии]] воспользуемся методом расширения [[developers:references:topomatic.cad.foundation.polylineextentions.getarea2d_topomatic.cad.foundation.ipolyline3d|PolylineExtentions.GetArea2D(IPolyline3D)]] | ||
+ | |||
+ | В теле программного модуля объявите команду, и декорируйте её атрибутом «cmd». Команда "get_horizontal_line_area" предложит пользователю выбрать замкнутую горизонталь и определит её площадь. | ||
+ | |||
+ | <code csharp> | ||
+ | ... | ||
+ | [cmd("get_horizontal_line_area")] | ||
+ | private void GetHorizontalLineArea() | ||
+ | { | ||
+ | //Находим активный SurfaceLayer | ||
+ | var cadview = CadView; | ||
+ | var actSfcLayer = SurfaceLayer.GetSurfaceLayer(cadview); | ||
+ | if (actSfcLayer == null) return; | ||
+ | |||
+ | //Включаем возможность выбор горизонталей | ||
+ | var initSelectState = SurfaceLayer.SurfaceSelectionSet.IsHorizontalSelectable; | ||
+ | SurfaceLayer.SurfaceSelectionSet.IsHorizontalSelectable = true; | ||
+ | |||
+ | //Получаем указатель на текущий набор объектов | ||
+ | var ss = actSfcLayer.SelectionSet; | ||
+ | |||
+ | //Получаем указатель на слой горизонталей | ||
+ | var layer = actSfcLayer.Surface.Style.HorizontalsStyle.GetLayer(); | ||
+ | |||
+ | //Выбираем горизонталь на плане | ||
+ | var linear_object = ss.PickOneObjectAtScreen(obj => | ||
+ | { | ||
+ | if (obj is SurfaceObjectWrapper layered_object) | ||
+ | { | ||
+ | return layered_object.LayerID == layer.ObjectID; | ||
+ | } | ||
+ | return false; | ||
+ | }, "Выберите замкнутую горизонталь") as ILinearObject; | ||
+ | |||
+ | //Восстанавливаем состояние флага возможности выбора горизонталей | ||
+ | SurfaceLayer.SurfaceSelectionSet.IsHorizontalSelectable = initSelectState; | ||
+ | if (linear_object == null) return; | ||
+ | |||
+ | //Извлекаем полилинию из горизонтали и получаем её площадь | ||
+ | var poly = new Polyline3D(); | ||
+ | linear_object.GetPolyline(poly); | ||
+ | |||
+ | //Проверяем замкнута ли горизонталь | ||
+ | var startVec = poly[0]; | ||
+ | var endVec = poly[poly.Count - 1]; | ||
+ | if (startVec.EqualEps(endVec)) | ||
+ | { | ||
+ | var area = poly.GetArea2D(); | ||
+ | MessageDlg.Show($"Площадь горизонтали: {area}"); | ||
+ | } | ||
+ | else MessageDlg.Show($"Горизонталь не замкнута."); | ||
+ | } | ||
+ | ... | ||
+ | </code> | ||
+ | |||
+ | {{ :developers:tutorial:surfaceelementsselect:tutselhorizontal.png?nolink&600 |}} | ||
+ | |||
+ | |||
+ | |||
+ | Теперь необходимо сформировать наш файл .plugin. Заполните его следующим образом. | ||
+ | |||
+ | <code javascript> | ||
+ | { | ||
+ | "assemblies": { | ||
+ | "TutorialSelectSurfaceElements": { | ||
+ | "assembly": "TutorialSelectSurfaceElements.dll, TutorialSelectSurfaceElements.ModulePluginHost" | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | "actions": { | ||
+ | "id_calculate_average_elevation": { | ||
+ | "cmd": "calculate_average_elevation", | ||
+ | "title": "Рассчитать среднюю отметку" | ||
+ | }, | ||
+ | "id_define_steepest_grade": { | ||
+ | "cmd": "define_steepest_grade", | ||
+ | "title": "Рассчитать наибольший уклон" | ||
+ | }, | ||
+ | "id_get_horizontal_line_area": { | ||
+ | "cmd": "get_horizontal_line_area", | ||
+ | "title": "Получить площадь горизонтали" | ||
+ | } | ||
+ | }, | ||
+ | |||
+ | "menubars": { | ||
+ | "rbproj": { | ||
+ | "items": [ | ||
+ | { | ||
+ | "id": "tutorial_menu", | ||
+ | "title": "Tutorial", | ||
+ | "items": [ | ||
+ | "id_calculate_average_elevation", | ||
+ | "id_define_steepest_grade", | ||
+ | "id_get_horizontal_line_area" | ||
+ | ] | ||
+ | } | ||
+ | ] | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Результатом запуска проекта будет появление в главном меню пункта «Tutorial», с подпунктами, которые будут работать в соответствии с описанными выше алгоритмами. | ||
- | /// | + | <note>[[developers:tutorial:tutorialcode|Исходный код]] примера расположен в проекте **"TutorialSelectSurfaceElements"**.</note> |