Выделение элементов поверхности

Нередко, при работе с поверхностью, пользователю требуется изменять или получать информацию из её элементов. В этой главе мы рассмотрим простые примеры по работе с элементами поверхности.

В качестве основного инструмента получения элементов поверхности рекомендуется пользоваться методами класса SurfaceLayer. Некоторые из них мы рассмотрим в следующих примерах. Сперва выберем необходимые нам объекты и начнём мы с выбора точек поверхности.

Выделение точек поверхности

В этом примере мы выберем точки поверхности на вкладке «План» и рассчитаем их среднюю отметку. Для этого воспользуемся методом SelectPoints() у слоя текущей поверхности (SurfaceLayer). Так как метод SelectPoints() предоставляет пользователю возможность выбора элементов контекстного меню, то возвращаемое значение будет иметь вид GetPointResult, которое укажет на то, какое именно действие было совершено пользователем.

Для того чтобы получить множество выбранных точек, будет необходимо воспользоваться методом GetSelectedPoints() у того же SurfaceLayer. Далее пройдёмся по выбранным точкам циклом foreach и применим необходимую логику для расчёта средней отметки.

Ниже представлен код примера, который мы оформим в качестве метода CalculateAverageElevation() с атрибутом [cmd(«calculate_average_elevation»)]. Данный метод мы поместим в класс Module для возможности последующего вызова этой команды из командной строки.

{ ... [cmd("calculate_average_elevation")] private void CalculateAverageElevation() { //Находим активный SurfaceLayer var cadview = CadView; var actSfcLayer = SurfaceLayer.GetSurfaceLayer(cadview); if (actSfcLayer == null) return; //Выбираем точки поверхности if (actSfcLayer.SelectedPointsCount == 0) { var res = actSfcLayer.SelectPoints(null, "Выберите точки поверхности:"); if (res == GetPointResult.Cancel) return; } if (actSfcLayer.SelectedPointsCount == 0) return; //Обращаемся к выбранным точкам и получаем сумму отметок var sfc = actSfcLayer.Surface; var sum = 0.0; foreach (var selectedPoint in actSfcLayer.GetSelectedPoints()) { var point = sfc.Points[selectedPoint]; sum += point.Vertex.Elevation; } //Вычисляем среднюю отметку и отображаем её в диалоговом окне var average = sum / actSfcLayer.SelectedPointsCount; MessageDlg.Show($"Средняя отметка: {average}"); } ... }

Выделение структурных линий

В данном примере мы попробуем рассчитать максимальный уклон среди всех сегментов структурной линии. Как и в предыдущем примере, для выбора структурной линии нам потребуется слой текущей поверхности (SurfaceLayer). Чтобы выбрать одну структурную линию, воспользуемся методом SelectOneStructureLine(). Здесь возвращаемым значением сразу же будет выступать выбранная структурная линия (StructureLine), поэтому никаких дополнительных действий выполнять не придется.

Воспользуемся циклом for, чтобы обратиться к узлам структурной линии и в каждой итерации будет обращаться к текущей точке цикла и к следующей, тем самым получая представление о сегменте структурной линии.

Для того чтобы мы не получили исключение в результате обращения к последующему узлу структурной линии в последней итерации, заведомо уменьшим количество итераций цикла на 1.
Важно помнить, что узел структурной линии всегда опирается на точку поверхности, индекс которой хранится в поле StructureLineNode.Index. Узел не несёт информации о его плановом положении, но при помощи индекса опорной точки, мы можем найти её в массиве точек поверхности и получить необходимые данные о расположении этого узла в пространстве.

В ходе цикла определяется уклон сегмента на текущей итерации и если он больше, чем предыдущее значение, то запоминаем его и, после выхода из цикла, выводим диалоговое окно с рассчитанными данными.

Ниже представлен код примера, который мы оформим в качестве метода DefineSteepestGrade() с атрибутом [cmd(«define_steepest_grade»)]. Данный метод мы поместим в класс Module для возможности последующего вызова этой команды из командной строки.

{ ... [cmd("define_steepest_grade")] private void DefineSteepestGrade() { //Находим активный SurfaceLayer var cadview = CadView; var actSfcLayer = SurfaceLayer.GetSurfaceLayer(cadview); if (actSfcLayer == null) return; //Выбираем структурную линию var strLine = actSfcLayer.SelectOneStructureLine(null, "Выберите структурную линию:"); if (strLine == null) return; //Обращаемся к узлам структурной линии, находим соответствующие им точки поверхности //и высчитываем уклоны сегментов по пути определяя максимальный уклон var sfc = actSfcLayer.Surface; var maxIncline = 0.0; for (var i = 0; i < strLine.Count - 1; i++) { var stPoint = sfc.Points[strLine[i].Index]; var endPoint = sfc.Points[strLine[i + 1].Index]; var delta = Math.Abs(stPoint.Vertex.Elevation - endPoint.Vertex.Elevation); var stPos = stPoint.Vertex.Pos; var endPos = endPoint.Vertex.Pos; var length = (endPos - stPos).Length; if (ValueConverter.CompValues(length, 0.0) != 0) { var incline = delta / length; if (incline > maxIncline) maxIncline = incline; } } MessageDlg.Show($"Максимальный уклон: {maxIncline}"); } ... }