Добрый день. Столкнулся со следующей ситуацией. Есть слой с площадными объектами (домами), а так же есть слой с участками. Требуется на конце участка, который попал в площадной объект создать потребителя. Как создавать символьные объекты по координатам в VBS мне понятно, но не понятно как взять координаты начала или конца участка и можно ли вообще их как то получить?
Создать объект на конечной/начальной точке участка по условию пересечения с другим слоем, VBS, координаты
|
24.10.2024 15:15:06
|
|
|
|
|
|
24.10.2024 17:42:01
Function GetX(TopNum As Long) As Double TopNum - номер вершины ломаной (нумерация с единицы). Для получения первой точки TopNum указываем 1. Для последней используем свойство NumTops. |
|||||
|
|
|
|
24.10.2024 17:52:56
|
|||||||
|
|
|
|
25.10.2024 11:13:48
А можете подсказать? Вот есть метод IsPointInContour method (ZGeometry), который проверяет попадание точки в полигон. А как его применить, чтобы не перебирать каждый полигон в цикле по сисам в отдельности. А то получается, что идет прохождение в цикле по всем участкам, берется 1 точка, а потом еще и проверяет в цикле по всем полигонам, боюсь такое будет очень долго работать. Может быть можно как-то получить 1 единый полигон, со все площадных объектов? Или еще как то?
|
|
|
|
|
|
25.10.2024 12:44:15
Если -1, значит не попал, инчаче ID контура, в кого конец попал |
|||
|
|
|
|
25.10.2024 13:18:57
Да, это серьезно упростило дело. Спасибо. Все получилось.
|
|
|
|
|
|
25.10.2024 16:58:07
Увы, работало только на тестовом слое ~500 объектов нормально. На "боевом" почему-то из ~7600 объектов проставляет то 1059, то 1060, то 1063 символа. По разному пытался сделать, но никак. Вот стоят рядом 2 одинаковых дома, в один ставит в другой не ставит.
Вот сам макрос Sub create_obj_in_line Set Out = Zulu.OpenOutputChannel("Сообщения") Set L = CreateObject("ZuluLib.Layer") Set Line_ob = CreateObject("ZuluLib.PolyLine") Out.Clear L.Open "..." Set Keys_uch = L.ElementKeys.SelectByType(7,0) For i = 1 To Keys_uch.Count set Line_ob = L.Elements.getElement(Keys_uch.Item(i)).PolyLine Point_X = Line_ob.GetX(Line_ob.NumTops) Point_y = Line_ob.GetY(Line_ob.NumTops) sys_polygon = L.ElemIDByXY(Point_X, Point_y) If sys_polygon <> -1 and L.Elements.GetElement(sys_polygon).TypeID=5 Then L.AddSimpleSymbol Point_X, Point_y, 0, 1, 200, 0 Out.Put Cstr(sys_polygon) + CHR(10) end if Next Out.Put "Готово" End Sub Вот как это выглядит |
|
|
|
|
|
25.10.2024 17:24:11
Алексей Демин, Не уверен, но мне кажется что это из-за того что sys_polygon = L.ElemIDByXY(Point_X, Point_y) возвращает одно значение ID из слоя, при этом и здания и линия находятся в одном слое. Поскольку Точка лежит одновременно и на линии и на здании в некоторых случаях вы возвращаете ключ линии, который дальше по условию не проходит.
|
|
|
|
|
|
25.10.2024 18:25:25
Изначально пробовал в разных слоях - результат был тот же. Сейчас попробовал прибавлять к координатам небольшие значения, чтобы сместить точки - не помогло, результат не изменился. Посмотрел какие сисы он пишет в sys_polygon - действительно, пишет все подряд, не только полигоны, а что попало под 5 пикселей вокруг точки с учетом масштаба. Что делать с этим масштабом, где его указывать я не разобрался. За то нашел метод GetClosestElementByXY. С ним все работает как надо.
Изменено: - 25.10.2024 19:26:01
|
|
|
|
|
|
25.10.2024 19:30:06
Вернет коллекцию всех, кто в окрестность попал, в коллекции ищем объект типа полигон. |
|||
|
|
|
|
25.10.2024 19:44:51
Понял, спасибо!
|
|
|
|
|
|
25.10.2024 23:31:52
IntersectByRadius действительно оказался очень полезным. Часто бывает, что в площадном объекте лежит много маленьких участков, но этот метод как раз помогает, если добавить условие "если число объектов полностью попавших в радиус 2х метров <1 = истина". 2 метра радиус хорошо подходит. Ну это конечно, если в исходном слое есть узлы. В слое, где 8600 домов без метода IntersectByRadius, получалось 1800 домов, где были созданы лишние потребители, с этим методом их было меньше 20. Оставлю макрос на всякий случай.
|
|||
|
|
|
|
26.10.2024 09:55:38
Изменено: - 26.10.2024 09:57:47
|
|||||
|
|
|
||||