Completed
Push — master ( d63616...511dbe )
by Tobias
02:09
created

Vertex::setFrom()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 7.456

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 18
ccs 4
cts 10
cp 0.4
rs 9.2
cc 4
eloc 11
nc 3
nop 1
crap 7.456
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
        if ($this->to->getLatitude() !== $this->from->getLatitude()) {
56
            $this->gradient = ($this->to->getLongitude() - $this->from->getLongitude()) / ($this->to->getLatitude() - $this->from->getLatitude());
57
            $this->ordinateIntercept = $this->from->getLongitude() - $this->from->getLatitude() * $this->gradient;
58
        } else {
59
            $this->gradient = null;
60
            $this->ordinateIntercept = null;
61
        }
62
63
        return $this;
64
    }
65
66
    /**
67
     * {@inheritDoc}
68
     */
69 5
    public function getFrom()
70
    {
71 5
        return $this->from;
72
    }
73
74
    /**
75
     * {@inheritDoc}
76
     */
77 49
    public function setTo(CoordinateInterface $to)
78
    {
79 49
        $this->to = $to;
80
81 49
        if (empty($this->from) || ($this->to->getLatitude() - $this->from->getLatitude() === 0)) {
82 6
            return $this;
83
        }
84
85 43
        if ($this->to->getLatitude() !== $this->from->getLatitude()) {
86 43
            $this->gradient = ($this->to->getLongitude() - $this->from->getLongitude()) / ($this->to->getLatitude() - $this->from->getLatitude());
87 43
            $this->ordinateIntercept = $this->from->getLongitude() - $this->from->getLatitude() * $this->gradient;
88
        } else {
89
            $this->gradient = null;
90
            $this->ordinateIntercept = null;
91
        }
92
93 43
        return $this;
94
    }
95
96
    /**
97
     * {@inheritDoc}
98
     */
99 5
    public function getTo()
100
    {
101 5
        return $this->to;
102
    }
103
104
    /**
105
     * {@inheritDoc}
106
     */
107 5
    public function getGradient()
108
    {
109 5
        return $this->gradient;
110
    }
111
112
    /**
113
     * {@inheritDoc}
114
     */
115 2
    public function getOrdinateIntercept()
116
    {
117 2
        return $this->ordinateIntercept;
118
    }
119
120
    /**
121
     * @return integer
122
     */
123 5
    public function getPrecision()
124
    {
125 5
        return $this->precision;
126
    }
127
128
    /**
129
     * @param  integer $precision
130
     * @return $this
131
     */
132
    public function setPrecision($precision)
133
    {
134
        $this->precision = $precision;
135
136
        return $this;
137
    }
138
139
    /**
140
     * Returns the initial bearing from the origin coordinate
141
     * to the destination coordinate in degrees.
142
     *
143
     * @return float The initial bearing in degrees
144
     */
145 14
    public function initialBearing()
146
    {
147 14
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
148
149 14
        $latA = deg2rad($this->from->getLatitude());
150 14
        $latB = deg2rad($this->to->getLatitude());
151 14
        $dLng = deg2rad($this->to->getLongitude() - $this->from->getLongitude());
152
153 14
        $y = sin($dLng) * cos($latB);
154 14
        $x = cos($latA) * sin($latB) - sin($latA) * cos($latB) * cos($dLng);
155
156 14
        return (float) (rad2deg(atan2($y, $x)) + 360) % 360;
157
    }
158
159
    /**
160
     * Returns the final bearing from the origin coordinate
161
     * to the destination coordinate in degrees.
162
     *
163
     * @return float The final bearing in degrees
164
     */
165 14
    public function finalBearing()
166
    {
167 14
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
168
169 14
        $latA = deg2rad($this->to->getLatitude());
170 14
        $latB = deg2rad($this->from->getLatitude());
171 14
        $dLng = deg2rad($this->from->getLongitude() - $this->to->getLongitude());
172
173 14
        $y = sin($dLng) * cos($latB);
174 14
        $x = cos($latA) * sin($latB) - sin($latA) * cos($latB) * cos($dLng);
175
176 14
        return (float) ((rad2deg(atan2($y, $x)) + 360) % 360 + 180 ) % 360;
177
    }
178
179
    /**
180
     * Returns the initial cardinal point / direction from the origin coordinate to
181
     * the destination coordinate.
182
     * @see http://en.wikipedia.org/wiki/Cardinal_direction
183
     *
184
     * @return string The initial cardinal point / direction
185
     */
186 7
    public function initialCardinal()
187
    {
188 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
189
190 7
        return Geotools::$cardinalPoints[(integer) round($this->initialBearing() / 22.5)];
191
    }
192
193
    /**
194
     * Returns the final cardinal point / direction from the origin coordinate to
195
     * the destination coordinate.
196
     * @see http://en.wikipedia.org/wiki/Cardinal_direction
197
     *
198
     * @return string The final cardinal point / direction
199
     */
200 7
    public function finalCardinal()
201
    {
202 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
203
204 7
        return Geotools::$cardinalPoints[(integer) round($this->finalBearing() / 22.5)];
205
    }
206
207
    /**
208
     * Returns the half-way point / coordinate along a great circle
209
     * path between the origin and the destination coordinates.
210
     *
211
     * @return CoordinateInterface
212
     */
213 7
    public function middle()
214
    {
215 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
216
217 7
        $latA = deg2rad($this->from->getLatitude());
218 7
        $lngA = deg2rad($this->from->getLongitude());
219 7
        $latB = deg2rad($this->to->getLatitude());
220 7
        $lngB = deg2rad($this->to->getLongitude());
221
222 7
        $bx = cos($latB) * cos($lngB - $lngA);
223 7
        $by = cos($latB) * sin($lngB - $lngA);
224
225 7
        $lat3 = rad2deg(atan2(sin($latA) + sin($latB), sqrt((cos($latA) + $bx) * (cos($latA) + $bx) + $by * $by)));
226 7
        $lng3 = rad2deg($lngA + atan2($by, cos($latA) + $bx));
227
228 7
        return new Coordinate([$lat3, $lng3], $this->from->getEllipsoid());
229
    }
230
231
    /**
232
     * Returns the destination point with a given bearing in degrees travelling along a
233
     * (shortest distance) great circle arc and a distance in meters.
234
     *
235
     * @param integer $bearing  The bearing of the origin in degrees.
236
     * @param integer $distance The distance from the origin in meters.
237
     *
238
     * @return CoordinateInterface
239
     */
240 9
    public function destination($bearing, $distance)
241
    {
242 9
        $lat = deg2rad($this->from->getLatitude());
243 9
        $lng = deg2rad($this->from->getLongitude());
244
245 9
        $bearing = deg2rad($bearing);
246
247 9
        $endLat = asin(sin($lat) * cos($distance / $this->from->getEllipsoid()->getA()) + cos($lat) *
248 9
            sin($distance / $this->from->getEllipsoid()->getA()) * cos($bearing));
249 9
        $endLon = $lng + atan2(sin($bearing) * sin($distance / $this->from->getEllipsoid()->getA()) * cos($lat),
250 9
            cos($distance / $this->from->getEllipsoid()->getA()) - sin($lat) * sin($endLat));
251
252 9
        return new Coordinate([rad2deg($endLat), rad2deg($endLon)], $this->from->getEllipsoid());
253
    }
254
255
    /**
256
     * Returns true if the vertex passed on argument is on the same line as this object
257
     *
258
     * @param  Vertex  $vertex The vertex to compare
259
     * @return boolean
260
     */
261 5
    public function isOnSameLine(Vertex $vertex) {
262 5
        if (is_null($this->getGradient()) && is_null($vertex->getGradient()) && $this->from->getLongitude() == $vertex->getFrom()->getLongitude()) {
263
            return true;
264 5
        } elseif (!is_null($this->getGradient()) && !is_null($vertex->getGradient())) {
265
            return (
266 5
                bccomp($this->getGradient(), $vertex->getGradient(), $this->getPrecision()) === 0
267
                &&
268 5
                bccomp($this->getOrdinateIntercept(), $vertex->getOrdinateIntercept(), $this->getPrecision()) ===0
269
            );
270
        } else {
271
            return false;
272
        }
273
    }
274
275
    /**
276
     * Returns the other coordinate who is not the coordinate passed on argument
277
     * @param  CoordinateInterface $coordinate
278
     * @return null|Coordinate
279
     */
280 3
    public function getOtherCoordinate(CoordinateInterface $coordinate) {
281 3
        if ($coordinate->isEqual($this->from)) {
282 1
            return $this->to;
283 2
        } else if ($coordinate->isEqual($this->to)) {
284 1
            return $this->from;
285
        }
286 1
        return null;
287
    }
288
289
    /**
290
     * Returns the determinant value between $this (vertex) and another vertex.
291
     *
292
     * @param  Vertex $vertex [description]
293
     * @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...
294
     */
295 4
    public function getDeterminant(Vertex $vertex) {
296 4
        $abscissaVertexOne = $this->to->getLatitude() - $this->from->getLatitude();
297 4
        $ordinateVertexOne = $this->to->getLongitude() - $this->from->getLongitude();
298 4
        $abscissaVertexSecond = $vertex->getTo()->getLatitude() - $vertex->getFrom()->getLatitude();
299 4
        $ordinateVertexSecond = $vertex->getTo()->getLongitude() - $vertex->getFrom()->getLongitude();
300
301 4
        return bcsub(
302 4
            bcmul($abscissaVertexOne, $ordinateVertexSecond, $this->precision),
303 4
            bcmul($abscissaVertexSecond, $ordinateVertexOne, $this->precision),
304 4
            $this->precision
305
        );
306
    }
307
308
}
309