Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
polygon.php
1<?php
2
4
5class Polygon extends Collection
6{
10 public function contains(BaseGeometry $geometry): ?bool
11 {
12 if (!$geometry instanceof Point)
13 {
14 return null;
15 }
16
17 if (!isset($this->components[0]))
18 {
19 return null;
20 }
21
23 $outerRing = $this->components[0];
24 if (!$this->isPointInsideClosedRing($outerRing, $geometry))
25 {
26 return false;
27 }
28
29 $innerRings = array_slice($this->components, 1);
30 foreach ($innerRings as $innerRing)
31 {
32 if ($this->isPointInsideClosedRing($innerRing, $geometry))
33 {
34 return false;
35 }
36 }
37
38 return true;
39 }
40
48 private function isPointInsideClosedRing(LineString $lineString, Point $point): bool
49 {
50 $polygonContainsPoint = false;
51
52 $componentsCount = $lineString->getComponentsCount();
53
54 $lineStringPoints = $lineString->getComponents();
55 $lineStringLats = [];
56 $lineStringLngs = [];
57
59 foreach ($lineStringPoints as $lineStringPoint)
60 {
61 $lineStringLats[] = $lineStringPoint->getLat();
62 $lineStringLngs[] = $lineStringPoint->getLng();
63 }
64
65 for ($node = 0, $altNode = $componentsCount - 1; $node < $componentsCount; $altNode = $node++)
66 {
67 $condition = ($lineStringLngs[$node] > $point->getLng()) !== ($lineStringLngs[$altNode] > $point->getLng())
68 && ($point->getLat() < ($lineStringLats[$altNode] - $lineStringLats[$node])
69 * ($point->getLng() - $lineStringLngs[$node])
70 / ($lineStringLngs[$altNode] - $lineStringLngs[$node]) + $lineStringLats[$node]);
71
72 if ($condition)
73 {
74 $polygonContainsPoint = !$polygonContainsPoint;
75 }
76 }
77
78 return $polygonContainsPoint;
79 }
80}