Completed
Push — master ( 8fc0c6...6df544 )
by Antoine
05:05 queued 03:25
created

Vertex::getDeterminant()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 12
ccs 9
cts 9
cp 1
rs 9.4285
cc 1
eloc 9
nc 1
nop 1
crap 1
1
<?php
2
3
/*
4
 * This file is part of the Geotools library.
5
 *
6
 * (c) Antoine Corcy <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace League\Geotools\Vertex;
13
14
use League\Geotools\Coordinate\Coordinate;
15
use League\Geotools\Coordinate\CoordinateInterface;
16
use League\Geotools\Coordinate\Ellipsoid;
17
use League\Geotools\CoordinateCouple;
18
use League\Geotools\Geotools;
19
20
/**
21
 * Vertex class
22
 *
23
 * @author Antoine Corcy <[email protected]>
24
 */
25
class Vertex implements VertexInterface
26
{
27
    use CoordinateCouple;
28
29
    /**
30
     * @var double
31
     */
32
    protected $gradient;
33
34
    /**
35
     * @var double
36
     */
37
    protected $ordinateIntercept;
38
39
    /**
40
     * @var integer
41
     */
42
    private $precision = 8;
43
44
    /**
45
     * {@inheritDoc}
46
     */
47 58
    public function setFrom(CoordinateInterface $from)
48
    {
49 58
        $this->from = $from;
50
51 58
        if (empty($this->to) || ($this->to->getLatitude() - $this->from->getLatitude() === 0)) {
52 58
            return $this;
53
        }
54
55
        $this->gradient = ($this->to->getLongitude() - $this->from->getLongitude()) / ($this->to->getLatitude() - $this->from->getLatitude());
56
        $this->ordinateIntercept = $this->from->getLongitude() - $this->from->getLatitude() * $this->gradient;
57
        return $this;
58
    }
59
60
    /**
61
     * {@inheritDoc}
62
     */
63 5
    public function getFrom()
64
    {
65 5
        return $this->from;
66
    }
67
68
    /**
69
     * {@inheritDoc}
70
     */
71 49
    public function setTo(CoordinateInterface $to)
72
    {
73 49
        $this->to = $to;
74
75 49
        if (empty($this->from) || ($this->to->getLatitude() - $this->from->getLatitude() === 0)) {
76 6
            return $this;
77
        }
78
79 43
        $this->gradient = ($this->to->getLongitude() - $this->from->getLongitude()) / ($this->to->getLatitude() - $this->from->getLatitude());
80 43
        $this->ordinateIntercept = $this->from->getLongitude() - $this->from->getLatitude() * $this->gradient;
81
82 43
        return $this;
83
    }
84
85
    /**
86
     * {@inheritDoc}
87
     */
88 5
    public function getTo()
89
    {
90 5
        return $this->to;
91
    }
92
93
    /**
94
     * {@inheritDoc}
95
     */
96 5
    public function getGradient()
97
    {
98 5
        return $this->gradient;
99
    }
100
101
    /**
102
     * {@inheritDoc}
103
     */
104 2
    public function getOrdinateIntercept()
105
    {
106 2
        return $this->ordinateIntercept;
107
    }
108
109
    /**
110
     * @return integer
111
     */
112 5
    public function getPrecision()
113
    {
114 5
        return $this->precision;
115
    }
116
117
    /**
118
     * @param  integer $precision
119
     * @return $this
120
     */
121
    public function setPrecision($precision)
122
    {
123
        $this->precision = $precision;
124
125
        return $this;
126
    }
127
128
    /**
129
     * Returns the initial bearing from the origin coordinate
130
     * to the destination coordinate in degrees.
131
     *
132
     * @return float The initial bearing in degrees
133
     */
134 14
    public function initialBearing()
135
    {
136 14
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
137
138 14
        $latA = deg2rad($this->from->getLatitude());
139 14
        $latB = deg2rad($this->to->getLatitude());
140 14
        $dLng = deg2rad($this->to->getLongitude() - $this->from->getLongitude());
141
142 14
        $y = sin($dLng) * cos($latB);
143 14
        $x = cos($latA) * sin($latB) - sin($latA) * cos($latB) * cos($dLng);
144
145 14
        return (float) (rad2deg(atan2($y, $x)) + 360) % 360;
146
    }
147
148
    /**
149
     * Returns the final bearing from the origin coordinate
150
     * to the destination coordinate in degrees.
151
     *
152
     * @return float The final bearing in degrees
153
     */
154 14
    public function finalBearing()
155
    {
156 14
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
157
158 14
        $latA = deg2rad($this->to->getLatitude());
159 14
        $latB = deg2rad($this->from->getLatitude());
160 14
        $dLng = deg2rad($this->from->getLongitude() - $this->to->getLongitude());
161
162 14
        $y = sin($dLng) * cos($latB);
163 14
        $x = cos($latA) * sin($latB) - sin($latA) * cos($latB) * cos($dLng);
164
165 14
        return (float) ((rad2deg(atan2($y, $x)) + 360) % 360 + 180 ) % 360;
166
    }
167
168
    /**
169
     * Returns the initial cardinal point / direction from the origin coordinate to
170
     * the destination coordinate.
171
     * @see http://en.wikipedia.org/wiki/Cardinal_direction
172
     *
173
     * @return string The initial cardinal point / direction
174
     */
175 7
    public function initialCardinal()
176
    {
177 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
178
179 7
        return Geotools::$cardinalPoints[(integer) round($this->initialBearing() / 22.5)];
180
    }
181
182
    /**
183
     * Returns the final cardinal point / direction from the origin coordinate to
184
     * the destination coordinate.
185
     * @see http://en.wikipedia.org/wiki/Cardinal_direction
186
     *
187
     * @return string The final cardinal point / direction
188
     */
189 7
    public function finalCardinal()
190
    {
191 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
192
193 7
        return Geotools::$cardinalPoints[(integer) round($this->finalBearing() / 22.5)];
194
    }
195
196
    /**
197
     * Returns the half-way point / coordinate along a great circle
198
     * path between the origin and the destination coordinates.
199
     *
200
     * @return CoordinateInterface
201
     */
202 7
    public function middle()
203
    {
204 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
205
206 7
        $latA = deg2rad($this->from->getLatitude());
207 7
        $lngA = deg2rad($this->from->getLongitude());
208 7
        $latB = deg2rad($this->to->getLatitude());
209 7
        $lngB = deg2rad($this->to->getLongitude());
210
211 7
        $bx = cos($latB) * cos($lngB - $lngA);
212 7
        $by = cos($latB) * sin($lngB - $lngA);
213
214 7
        $lat3 = rad2deg(atan2(sin($latA) + sin($latB), sqrt((cos($latA) + $bx) * (cos($latA) + $bx) + $by * $by)));
215 7
        $lng3 = rad2deg($lngA + atan2($by, cos($latA) + $bx));
216
217 7
        return new Coordinate([$lat3, $lng3], $this->from->getEllipsoid());
218
    }
219
220
    /**
221
     * Returns the destination point with a given bearing in degrees travelling along a
222
     * (shortest distance) great circle arc and a distance in meters.
223
     *
224
     * @param integer $bearing  The bearing of the origin in degrees.
225
     * @param integer $distance The distance from the origin in meters.
226
     *
227
     * @return CoordinateInterface
228
     */
229 9
    public function destination($bearing, $distance)
230
    {
231 9
        $lat = deg2rad($this->from->getLatitude());
232 9
        $lng = deg2rad($this->from->getLongitude());
233
234 9
        $bearing = deg2rad($bearing);
235
236 9
        $endLat = asin(sin($lat) * cos($distance / $this->from->getEllipsoid()->getA()) + cos($lat) *
237 9
            sin($distance / $this->from->getEllipsoid()->getA()) * cos($bearing));
238 9
        $endLon = $lng + atan2(sin($bearing) * sin($distance / $this->from->getEllipsoid()->getA()) * cos($lat),
239 9
            cos($distance / $this->from->getEllipsoid()->getA()) - sin($lat) * sin($endLat));
240
241 9
        return new Coordinate([rad2deg($endLat), rad2deg($endLon)], $this->from->getEllipsoid());
242
    }
243
244
    /**
245
     * Returns true if the vertex passed on argument is on the same line as this object
246
     *
247
     * @param  Vertex  $vertex The vertex to compare
248
     * @return boolean
249
     */
250 5
    public function isOnSameLine(Vertex $vertex) {
251 5
        if (is_null($this->getGradient()) && is_null($vertex->getGradient()) && $this->from->getLongitude() == $vertex->getFrom()->getLongitude()) {
252
            return true;
253 5
        } elseif (!is_null($this->getGradient()) && !is_null($vertex->getGradient())) {
254
            return (
255 5
                bccomp($this->getGradient(), $vertex->getGradient(), $this->getPrecision()) === 0
256
                &&
257 5
                bccomp($this->getOrdinateIntercept(), $vertex->getOrdinateIntercept(), $this->getPrecision()) ===0
258
            );
259
        } else {
260
            return false;
261
        }
262
    }
263
264
    /**
265
     * Returns the other coordinate who is not the coordinate passed on argument
266
     * @param  CoordinateInterface $coordinate
267
     * @return null|Coordinate
268
     */
269 3
    public function getOtherCoordinate(CoordinateInterface $coordinate) {
270 3
        if ($coordinate->isEqual($this->from)) {
271 1
            return $this->to;
272 2
        } else if ($coordinate->isEqual($this->to)) {
273 1
            return $this->from;
274
        }
275 1
        return null;
276
    }
277
278
    /**
279
     * Returns the determinant value between $this (vertex) and another vertex.
280
     *
281
     * @param  Vertex $vertex [description]
282
     * @return [type]         [description]
0 ignored issues
show
Documentation introduced by
The doc-type [type] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
283
     */
284 4
    public function getDeterminant(Vertex $vertex) {
285 4
        $abscissaVertexOne = $this->to->getLatitude() - $this->from->getLatitude();
286 4
        $ordinateVertexOne = $this->to->getLongitude() - $this->from->getLongitude();
287 4
        $abscissaVertexSecond = $vertex->getTo()->getLatitude() - $vertex->getFrom()->getLatitude();
288 4
        $ordinateVertexSecond = $vertex->getTo()->getLongitude() - $vertex->getFrom()->getLongitude();
289
290 4
        return bcsub(
291 4
            bcmul($abscissaVertexOne, $ordinateVertexSecond, $this->precision),
292 4
            bcmul($abscissaVertexSecond, $ordinateVertexOne, $this->precision),
293 4
            $this->precision
294
        );
295
    }
296
297
}
298