Работаю с картами, яндекса. Задача следующая, есть перечень домов городов с указанием географических координат, есть города с делением на сектора так называемыми полигонами, тоже с определенными координатами.
Сама суть задачи, что у каждого сектора есть номер и необходимо каждый географический объект на карте входящий в область полигона привязать к этому конкретному сектору присвоив номер сектора.
Для примера: Polygon71(обозначается списком точек на карте, каждая точка имеет конкретные географические координаты, также хочу обратить внимание, что полигон - это замкнутая фигура т.е. первая точка фигуры и последняя абсолютно идентичны): [39.151389078016365,51.714599123029885],[39.153878167982192,51.714652439476161],[39.152633622999275,51.711879900494196],[39.15001578700074,51.711639961204391],[39.146711305494392,51.711826580762583],[39.14430804621707,51.712812985570132],[39.143664316053489,51.7141192721704],[39.143578485365019,51.714679097675599],[39.145810083265403,51.71643850391682],[39.149887040968032,51.71913079541693],[39.157354310865507,51.724221718119331],[39.162289575452895,51.725527673485658],[39.164993242139907,51.72624726534076],[39.16602321040164,51.726647033618768],[39.167568162794204,51.726060705594961],[39.163877443189705,51.724141760436439],[39.161045030469985,51.722675844393059],[39.157483056898215,51.721023299933378],[39.155423120374785,51.71987714473422],[39.153320268507088,51.719770524161284],[39.149500802869902,51.717478120720109],[39.149887040968032,51.716358532398445],[39.147355035657966,51.714172589185274],[39.146153406019316,51.713426145227615],[39.14795585047731,51.712626370102868],[39.150530771131606,51.712679688886773],[39.151389078016365,51.714599123029885]] данному polygon принадлежит адрес - Воронеж, Победы бульвар 50б с координатами (39.147206,51.712429) принадлежащими данному полигону. Соответственно эти данные находятся в файле с координатами по каждому дому и отдельно лежат данные по polygon отмеченным в яндекс картах.
Возможно ли написать обработку позволяющую работать данным массивом присваивая каждому геообъекту принадлежность к конкретному полигону?
PS самая большая сложность, что полигоны не имеют правильной геометрической формы и могут выглядеть абсолютно по разному
Для яркости образа: первая картинка - тот самый полигон
Почти готовая функция. Если сами не сможете завтра посмотрю, был у меня когда-то стыренный вариант без учёта направления обхода (по часовой или против описания вершин). Что-то в вашем файле и намёка кода нет - хотя бы для преобразования записи полигона в массив точек. Или это типа - "я только начинаю изучать VBA"?
'функция разбивки строки координат многоугольника на массив строк,
'каждый чётный элемент содержит долготу, каждый нечётный широту
'пара i, i + 1 задаёт координату вершины многоугольника, при i mod 2 = 0
Public Function strArray(ByVal this As String) As String()
Dim pReg As Object
Set pReg = CreateObject("VBScript.RegExp"): pReg.Global = True
pReg.Pattern = "[\[\]]"
strArray = VBA.Split(pReg.Replace(this, ""), ",")
End Function
далее создаём массив координат типа Double в формате по описанию функции проверки нахождения точки в многоугольнике (или преобразовываем функцию для работы с таким массивом строк-координат.
Код
'ФУНКЦИЯ: определение вложености точки в многоугольник, заданный своими координатами
'положение точки на линии многоугольника считается отсутствием вложености.
'xy() - массив координат вершин многоугольника, где координаты 1-ой = последней.
'первый индекс массива: 1 - координата X, 2 - координата Y
'второй индекс массива: номер точки в массиве
'Xo, Yo - координаты исследуемой точки
Function InPoligon(xy() As Double, Xo As Double, Yo As Double) As Boolean
Dim dXnext As Double, dYnext As Double, Yb As Double
Dim dXprev As Double, dYprev As Double, Resault As Integer
Dim nextZone As Integer, prevZone As Integer, dZone As Integer, k As Integer
Resault = 0
For k = LBound(xy, 2) To UBound(xy, 2)
dXnext = xy(1, k) - Xo: dYnext = xy(2, k) - Yo
'проверка четверти плоскости
nextZone = 0
If (dXnext >= 0) And (dYnext > 0) Then nextZone = 1
If (dXnext < 0) And (dYnext >= 0) Then nextZone = 2
If (dXnext <= 0) And (dYnext < 0) Then nextZone = 3
If (dXnext > 0) And (dYnext <= 0) Then nextZone = 4
'If nextZone = 0 Then InPoligon = -100: Exit Function - на линии
If nextZone = 0 Then InPoligon = False: Exit Function
'
If k > LBound(xy, 2) Then 'проверка перехода
If nextZone <> prevZone Then 'переход в другую четверть
dZone = nextZone - prevZone
If dZone = 3 Then dZone = -1
If dZone = -3 Then dZone = 1
If (dZone = 2) Or (dZone = -2) Then 'переход через 2 четверти
'If dXnext = dXprev Then InPoligon = -100: Exit Function - на линии
Yb = (dYnext * dXprev - dYprev * dXnext) / (dXprev - dXnext)
'If Yb = 0 Then InPoligon = -100: Exit Function - на линии
If Yb = 0 Then InPoligon = False: Exit Function
dZone = dZone * Sgn(Yb)
If (prevZone = 2) Or (prevZone = 4) Then dZone = -dZone
End If '(dZone = 2) Or (dZone = -2)
Resault = Resault + dZone
End If 'nextZone <> prevZone
End If 'k > 1
dXprev = dXnext: dYprev = dYnext: prevZone = nextZone
Next k
If Abs(Resault) = 4 Then
InPoligon = True
Else
InPoligon = False
End If
End Function 'InPoligon