Completed
Pull Request — master (#53)
by
unknown
01:22
created

Polyline::getMiddlePoint()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.584
c 0
b 0
f 0
cc 3
nc 3
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Location;
5
6
use Location\Distance\DistanceInterface;
7
use Location\Formatter\Polyline\FormatterInterface;
8
9
/**
10
 * Polyline Implementation
11
 *
12
 * @author Marcus Jaschen <[email protected]>
13
 */
14
class Polyline implements GeometryInterface
15
{
16
    use GetBoundsTrait;
17
18
    /**
19
     * @var Coordinate[]
20
     */
21
    protected $points = [];
22
23
    /**
24
     * @param Coordinate $point
25
     *
26
     * @return void
27
     */
28
    public function addPoint(Coordinate $point)
29
    {
30
        $this->points[] = $point;
31
    }
32
33
    /**
34
     * Add unique point
35
     *
36
     * @param Coordinate $pointToAdd
37
     *
38
     * @return void
39
     */
40
    public function addUniquePoint(Coordinate $pointToAdd)
41
    {
42
        foreach($this->points as $point) {
43
            /* @var $point Coordinate */
44
            if(($pointToAdd->getLat() == $point->getLat()) && ($pointToAdd->getLng() == $point->getLng())) {
45
                return;
46
            }
47
        }
48
49
        $this->points[] = $pointToAdd;
50
    }
51
52
    /**
53
     * @return Coordinate[]
54
     */
55
    public function getPoints(): array
56
    {
57
        return $this->points;
58
    }
59
60
    /**
61
     * @return int
62
     */
63
    public function getNumberOfPoints(): int
64
    {
65
        return count($this->points);
66
    }
67
68
    /**
69
     * @param FormatterInterface $formatter
70
     *
71
     * @return string
72
     */
73
    public function format(FormatterInterface $formatter): string
74
    {
75
        return $formatter->format($this);
76
    }
77
78
    /**
79
     * @return Line[]
80
     */
81
    public function getSegments(): array
82
    {
83
        $length = count($this->points);
84
        $segments = [];
85
86
        if ($length <= 1) {
87
            return $segments;
88
        }
89
90
        for ($i = 1; $i < $length; $i++) {
91
            $segments[] = new Line($this->points[$i - 1], $this->points[$i]);
92
        }
93
94
        return $segments;
95
    }
96
97
    /**
98
     * Calculates the length of the polyline.
99
     *
100
     * @param DistanceInterface $calculator instance of distance calculation class
101
     *
102
     * @return float
103
     */
104
    public function getLength(DistanceInterface $calculator): float
105
    {
106
        $distance = 0.0;
107
108
        if (count($this->points) <= 1) {
109
            return $distance;
110
        }
111
112
        foreach ($this->getSegments() as $segment) {
113
            $distance += $segment->getLength($calculator);
114
        }
115
116
        return $distance;
117
    }
118
119
    /**
120
     * Create a new polyline with reversed order of points, i. e. reversed
121
     * polyline direction.
122
     *
123
     * @return Polyline
124
     */
125
    public function getReverse(): Polyline
126
    {
127
        $reversed = new static();
128
129
        foreach (array_reverse($this->points) as $point) {
130
            $reversed->addPoint($point);
131
        }
132
133
        return $reversed;
134
    }
135
136
    /**
137
     * @return Coordinate|null
138
     */
139
    public function getMiddlePoint(): ?Coordinate
140
    {
141
        $lat = 0.0;
142
        $lng = 0.0;
143
        $numberOfPoints = count($this->points);
144
145
        if($numberOfPoints < 1) {
146
            return null;
147
        }
148
149
        foreach($this->points as $point) {
150
            /* @var $point Coordinate */
151
            $lat += $point->getLat();
152
            $lng += $point->getLng();
153
        }
154
155
        $lat /= $numberOfPoints;
156
        $lng /= $numberOfPoints;
157
158
        return new Coordinate($lat, $lng);
159
    }
160
}
161