RUS  ENG 

Создать объект на конечной/начальной точке участка по условию пересечения с другим слоем

Страницы: 1
RSS
Создать объект на конечной/начальной точке участка по условию пересечения с другим слоем, VBS, координаты
 
Добрый день. Столкнулся со следующей ситуацией. Есть слой с площадными объектами (домами), а так же есть слой с участками. Требуется на конце участка, который попал в площадной объект создать потребителя. Как создавать символьные объекты по координатам в VBS мне понятно, но не понятно как взять координаты начала или конца участка и можно ли вообще их как то получить?
 
Цитата
написал:
Добрый день. Столкнулся со следующей ситуацией. Есть слой с площадными объектами (домами), а так же есть слой с участками. Требуется на конце участка, который попал в площадной объект создать потребителя. Как создавать символьные объекты по координатам в VBS мне понятно, но не понятно как взять координаты начала или конца участка и можно ли вообще их как то получить?
Добрый день. Element.Polyline https://politerm.com/zuludoc/zuluax/index.html#Element_PolyLine.html

А у Polyline GetX, GetY, первой и послдней точки
 
Цитата
написал:
Цитата
написал:
Добрый день. Столкнулся со следующей ситуацией. Есть слой с площадными объектами (домами), а так же есть слой с участками. Требуется на конце участка, который попал в площадной объект создать потребителя. Как создавать символьные объекты по координатам в VBS мне понятно, но не понятно как взять координаты начала или конца участка и можно ли вообще их как то получить?
Добрый день. Element.Polyline https://politerm.com/zuludoc/zuluax/index.html#Element_PolyLine.html

А у Polyline GetX, GetY, первой и послдней точки
Спасибо. Если я все верно понял

Function GetX(TopNum As Long) As Double

TopNum - номер вершины ломаной (нумерация с единицы).

Для получения первой точки TopNum указываем 1. Для последней используем свойство NumTops.

 
Цитата
написал:
Цитата
написал:
Цитата
написал:
Добрый день. Столкнулся со следующей ситуацией. Есть слой с площадными объектами (домами), а так же есть слой с участками. Требуется на конце участка, который попал в площадной объект создать потребителя. Как создавать символьные объекты по координатам в VBS мне понятно, но не понятно как взять координаты начала или конца участка и можно ли вообще их как то получить?
Добрый день. Element.Polyline https://politerm.com/zuludoc/zuluax/index.html#Element_PolyLine.html

А у Polyline GetX, GetY, первой и послдней точки
Спасибо. Если я все верно понял Function GetX (TopNum As Long) As Double TopNum - номер вершины ломаной (нумерация с единицы). Для получения первой точки TopNum указываем 1. Для последней используем свойство NumTops.
Да.
 
А можете подсказать? Вот есть метод IsPointInContour method (ZGeometry), который проверяет попадание точки в полигон. А как его применить, чтобы не перебирать каждый полигон в цикле по сисам в отдельности. А то получается, что идет прохождение в цикле по всем участкам, берется 1 точка, а потом еще и проверяет в цикле по всем полигонам, боюсь такое будет очень долго работать. Может быть можно как-то получить 1 единый полигон, со все площадных объектов? Или еще как то?
 
Цитата
написал:
А можете подсказать? Вот есть метод IsPointInContour method (ZGeometry), который проверяет попадание точки в полигон. А как его применить, чтобы не перебирать каждый полигон в цикле по сисам в отдельности. А то получается, что идет прохождение в цикле по всем участкам, берется 1 точка, а потом еще и проверяет в цикле по всем полигонам, боюсь такое будет очень долго работать. Может быть можно как-то получить 1 единый полигон, со все площадных объектов? Или еще как то?
Если нужно проверять попал конец участка в контур или нет, может идти по концам участков и для слоя контура вызывать ElemIDByXY
Если -1, значит не попал, инчаче ID контура, в кого конец попал
 
Да, это серьезно упростило дело. Спасибо. Все получилось.
 
Увы, работало только на тестовом слое ~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

Вот как это выглядит
 
Алексей Демин, Не уверен, но мне кажется что это из-за того что sys_polygon = L.ElemIDByXY(Point_X, Point_y) возвращает одно значение ID из слоя, при этом и здания и линия находятся в одном слое. Поскольку Точка лежит одновременно и на линии и на здании в некоторых случаях вы возвращаете ключ линии, который дальше по условию не проходит.
 
Изначально пробовал в разных слоях - результат был тот же. Сейчас попробовал прибавлять к координатам небольшие значения, чтобы сместить точки - не помогло, результат не изменился. Посмотрел какие сисы он пишет в sys_polygon - действительно, пишет все подряд, не только полигоны, а что попало под 5 пикселей вокруг точки с учетом масштаба. Что делать с этим масштабом, где его указывать я не разобрался. За то нашел метод GetClosestElementByXY. С ним все работает как надо.
Изменено: Алексей Демин - 25.10.2024 19:26:01
 
Цитата
написал:
Изначально пробовал в разных слоях - результат был тот же. Сейчас попробовал прибавлять к координатам небольшие значения, чтобы сместить точки - не помогло, результат не изменился. Посмотрел какие сисы он пишет в sys_polygon - действительно, пишет все подряд, не только полигоны, а что попала под 5 пикселей вокруг точки с учетом масштаба.
Можно попробовать IntersectByRadius с малым радиусом
https://politerm.com/zuludoc/zuluax/index.html#Layer_IntersectByRadius.html

Вернет коллекцию всех, кто в окрестность попал, в коллекции ищем объект типа полигон.
 
Понял, спасибо!
 
IntersectByRadius действительно оказался очень полезным. Часто бывает, что в площадном объекте лежит много маленьких участков, но этот метод как раз помогает, если добавить условие "если число объектов полностью попавших в радиус 2х метров <1 = истина". 2 метра радиус хорошо подходит. Ну это конечно, если в исходном слое есть узлы. В слое, где 8600 домов без метода IntersectByRadius, получалось 1800 домов, где были созданы лишние потребители, с этим методом их было меньше 20. Оставлю макрос на всякий случай.


Код
Sub create_obj_in_line

Set Out = Zulu.OpenOutputChannel("Сообщения")

Set L = CreateObject("ZuluLib.Layer")

Set Line_ob = CreateObject("ZuluLib.PolyLine")   
Set objz = CreateObject("ZuluLib.ZPoint")   
Out.Clear


L.Open "..."

Set Keys_uch = L.ElementKeys.SelectByType(7,0)

'L.StartSequentialWriteMode   

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.GetClosestElementByXY(Point_X+0.000002, Point_y, 0, False,objz)
If sys_polygon > 0 and L.Elements.GetElement(sys_polygon).TypeID=5 and L.IntersectByRadius(Point_X+0.000002,Point_y,0.00002,1,0).Count<1 Then
        L.AddSimpleSymbol Point_X+0.000002, Point_y, 0, 1, 300, 0
        'Out.Put Cstr(sys_polygon) + CHR(10)
        Out.Put Cstr(sys_polygon) + CHR(10)
end if


Next
    'L.FinishSequentialWriteMode

Out.Put "Готово"
End Sub
 
Цитата
написал:
IntersectByRadius действительно оказался очень полезным. Часто бывает, что в площадном объекте лежит много маленьких участков, но этот метод как раз помогает, если добавить условие "если число объектов полностью попавших в радиус 2х метров <1 = истина". 2 метра радиус хорошо подходит. Ну это конечно, если в исходном слое есть узлы. В слое, где 8600 домов без метода IntersectByRadius, получалось 1800 домов, где были созданы лишние потребители, с этим методом их было меньше 20. Оставлю макрос на всякий случай.
Можно сделать так:
Код
Sub create_obj_in_line

Set Out = Zulu.OpenOutputChannel("Сообщения")

Set L = zulu.ActiveMapDoc.Layers.Active

Set Line_ob = CreateObject("ZuluLib.PolyLine")   
Set objz = CreateObject("ZuluLib.ZPoint")   
Out.Clear

Set Keys_uch = L.ElementKeys.SelectByType(6,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)

Criterium = 1024 'eIntersects

'Получаем коллекцию тех, кого зацепила окрестность 2
Set Keys = L.IntersectByRadius(Point_X,Point_y, 2, Criterium, 0)

  'Перебираем всех, кого зацепила окрестность
  For j = 1 to Keys.Count
      
   Set El = L.Elements.GetElement(Keys(j))
      
   'Если находим полигон, то на конце участка ставим символ
    If El.GraphType = 5 Then  'eGraphTypePrimSquare
      
        L.AddSimpleSymbol Point_X, Point_y, 0, 25, 300, 0
                  
   Out.PutLine CStr(El.Key)
                     
   exit for
         
     End if
      
  Next 
         
Next

Out.Put "Готово"
End Sub
Изменено: Алексей Аширов - 26.10.2024 09:57:47
Страницы: 1