Completed
Push — master ( cc13b1...a6c11a )
by Antoine
11:05 queued 06:16
created

Vertex::isOnSameLine()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 7.5375

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 13
ccs 7
cts 9
cp 0.7778
rs 8.2222
cc 7
eloc 10
nc 4
nop 1
crap 7.5375
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\AbstractGeotools;
15
use League\Geotools\Coordinate\Coordinate;
16
use League\Geotools\Coordinate\CoordinateInterface;
17
use League\Geotools\Coordinate\Ellipsoid;
18
19
/**
20
 * Vertex class
21
 *
22
 * @author Antoine Corcy <[email protected]>
23
 */
24
class Vertex extends AbstractGeotools implements VertexInterface
25
{
26
    /**
27
     * @var integer
28
     */
29
    protected $gradient;
30
31
    /**
32
     * @var integer
33
     */
34
    protected $ordinateIntercept;
35
36
    /**
37
     * @var integer
38
     */
39
    private $precision = 8;
40
41
    /**
42
     * {@inheritDoc}
43
     */
44 51
    public function setFrom(CoordinateInterface $from)
45
    {
46 51
        $this->from = $from;
47
48 51
        if (empty($this->to) || ($this->to->getLatitude() - $this->from->getLatitude() === 0)) {
49 51
            return $this;
50
        }
51
52
        $this->gradient = ($this->to->getLongitude() - $this->from->getLongitude()) / ($this->to->getLatitude() - $this->from->getLatitude());
0 ignored issues
show
Documentation Bug introduced by
The property $gradient was declared of type integer, but ($this->to->getLongitude...s->from->getLatitude()) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
53
        $this->ordinateIntercept = $this->from->getLongitude() - $this->from->getLatitude() * $this->gradient;
0 ignored issues
show
Documentation Bug introduced by
The property $ordinateIntercept was declared of type integer, but $this->from->getLongitud...ude() * $this->gradient is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
54
        return $this;
55
    }
56
57
    /**
58
     * {@inheritDoc}
59
     */
60 1
    public function getFrom()
61
    {
62 1
        return $this->from;
63
    }
64
65
    /**
66
     * {@inheritDoc}
67
     */
68 42
    public function setTo(CoordinateInterface $to)
69
    {
70 42
        $this->to = $to;
71
72 42
        if (empty($this->from) || ($this->to->getLatitude() - $this->from->getLatitude() === 0)) {
73 6
            return $this;
74
        }
75
76 36
        $this->gradient = ($this->to->getLongitude() - $this->from->getLongitude()) / ($this->to->getLatitude() - $this->from->getLatitude());
0 ignored issues
show
Documentation Bug introduced by
The property $gradient was declared of type integer, but ($this->to->getLongitude...s->from->getLatitude()) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
77
        // var_dump($this->gradient);
78 36
        $this->ordinateIntercept = $this->from->getLongitude() - $this->from->getLatitude() * $this->gradient;
0 ignored issues
show
Documentation Bug introduced by
The property $ordinateIntercept was declared of type integer, but $this->from->getLongitud...ude() * $this->gradient is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
79
        // var_dump($this->ordinateIntercept);
80 36
        return $this;
81
    }
82
83
    /**
84
     * {@inheritDoc}
85
     */
86 1
    public function getTo()
87
    {
88 1
        return $this->to;
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     */
94 5
    public function getGradient()
95
    {
96 5
        return $this->gradient;
97
    }
98
99
    /**
100
     * {@inheritDoc}
101
     */
102 2
    public function getOrdinateIntercept()
103
    {
104 2
        return $this->ordinateIntercept;
105
    }
106
107
    /**
108
     * @return integer
109
     */
110 5
    public function getPrecision()
111
    {
112 5
        return $this->precision;
113
    }
114
115
    /**
116
     * @param  integer $precision
117
     * @return $this
118
     */
119
    public function setPrecision($precision)
120
    {
121
        $this->precision = $precision;
122
123
        return $this;
124
    }
125
126
    /**
127
     * Returns the initial bearing from the origin coordinate
128
     * to the destination coordinate in degrees.
129
     *
130
     * @return float The initial bearing in degrees
131
     */
132 14
    public function initialBearing()
133
    {
134 14
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
135
136 14
        $latA = deg2rad($this->from->getLatitude());
137 14
        $latB = deg2rad($this->to->getLatitude());
138 14
        $dLng = deg2rad($this->to->getLongitude() - $this->from->getLongitude());
139
140 14
        $y = sin($dLng) * cos($latB);
141 14
        $x = cos($latA) * sin($latB) - sin($latA) * cos($latB) * cos($dLng);
142
143 14
        return (float) (rad2deg(atan2($y, $x)) + 360) % 360;
144
    }
145
146
    /**
147
     * Returns the final bearing from the origin coordinate
148
     * to the destination coordinate in degrees.
149
     *
150
     * @return float The final bearing in degrees
151
     */
152 14
    public function finalBearing()
153
    {
154 14
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
155
156 14
        $latA = deg2rad($this->to->getLatitude());
157 14
        $latB = deg2rad($this->from->getLatitude());
158 14
        $dLng = deg2rad($this->from->getLongitude() - $this->to->getLongitude());
159
160 14
        $y = sin($dLng) * cos($latB);
161 14
        $x = cos($latA) * sin($latB) - sin($latA) * cos($latB) * cos($dLng);
162
163 14
        return (float) ((rad2deg(atan2($y, $x)) + 360) % 360 + 180 ) % 360;
164
    }
165
166
    /**
167
     * Returns the initial cardinal point / direction from the origin coordinate to
168
     * the destination coordinate.
169
     * @see http://en.wikipedia.org/wiki/Cardinal_direction
170
     *
171
     * @return string The initial cardinal point / direction
172
     */
173 7
    public function initialCardinal()
174
    {
175 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
176
177 7
        return $this->cardinalPoints[(integer) round($this->initialBearing() / 22.5)];
178
    }
179
180
    /**
181
     * Returns the final cardinal point / direction from the origin coordinate to
182
     * the destination coordinate.
183
     * @see http://en.wikipedia.org/wiki/Cardinal_direction
184
     *
185
     * @return string The final cardinal point / direction
186
     */
187 7
    public function finalCardinal()
188
    {
189 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
190
191 7
        return $this->cardinalPoints[(integer) round($this->finalBearing() / 22.5)];
192
    }
193
194
    /**
195
     * Returns the half-way point / coordinate along a great circle
196
     * path between the origin and the destination coordinates.
197
     *
198
     * @return CoordinateInterface
199
     */
200 7
    public function middle()
201
    {
202 7
        Ellipsoid::checkCoordinatesEllipsoid($this->from, $this->to);
203
204 7
        $latA = deg2rad($this->from->getLatitude());
205 7
        $lngA = deg2rad($this->from->getLongitude());
206 7
        $latB = deg2rad($this->to->getLatitude());
207 7
        $lngB = deg2rad($this->to->getLongitude());
208
209 7
        $bx = cos($latB) * cos($lngB - $lngA);
210 7
        $by = cos($latB) * sin($lngB - $lngA);
211
212 7
        $lat3 = rad2deg(atan2(sin($latA) + sin($latB), sqrt((cos($latA) + $bx) * (cos($latA) + $bx) + $by * $by)));
213 7
        $lng3 = rad2deg($lngA + atan2($by, cos($latA) + $bx));
214
215 7
        return new Coordinate(array($lat3, $lng3), $this->from->getEllipsoid());
216
    }
217
218
    /**
219
     * Returns the destination point with a given bearing in degrees travelling along a
220
     * (shortest distance) great circle arc and a distance in meters.
221
     *
222
     * @param integer $bearing  The bearing of the origin in degrees.
223
     * @param integer $distance The distance from the origin in meters.
224
     *
225
     * @return CoordinateInterface
226
     */
227 9
    public function destination($bearing, $distance)
228
    {
229 9
        $lat = deg2rad($this->from->getLatitude());
230 9
        $lng = deg2rad($this->from->getLongitude());
231
232 9
        $bearing = deg2rad($bearing);
233
234 9
        $endLat = asin(sin($lat) * cos($distance / $this->from->getEllipsoid()->getA()) + cos($lat) *
235 9
            sin($distance / $this->from->getEllipsoid()->getA()) * cos($bearing));
236 9
        $endLon = $lng + atan2(sin($bearing) * sin($distance / $this->from->getEllipsoid()->getA()) * cos($lat),
237 9
            cos($distance / $this->from->getEllipsoid()->getA()) - sin($lat) * sin($endLat));
238
239 9
        return new Coordinate(array(rad2deg($endLat), rad2deg($endLon)), $this->from->getEllipsoid());
240
    }
241
242
    /**
243
     * Returns true if the vertex passed on argument is on the same line as this object
244
     *
245
     * @param  Vertex  $vertex The vertex to compare
246
     * @return boolean
247
     */
248 5
    public function isOnSameLine(Vertex $vertex) {
249 5
        if (is_null($this->getGradient()) && is_null($vertex->getGradient()) && $this->from->getLongitude() == $vertex->getFrom()->getLongitude()) {
250
            return true;
251 5
        } elseif (!is_null($this->getGradient()) && !is_null($vertex->getGradient())) {
252
            return (
253 5
                bccomp($this->getGradient(), $vertex->getGradient(), $this->getPrecision()) === 0
254 5
                &&
255 2
                bccomp($this->getOrdinateIntercept(), $vertex->getOrdinateIntercept(), $this->getPrecision()) ===0
256 5
            );
257
        } else {
258
            return false;
259
        }
260
    }
261
262
263
}
264

 

OSZAR »