PerpendicularDistance::getPerpendicularDistance()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 51
rs 9.069
c 0
b 0
f 0
cc 2
nc 2
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Location\Utility;
6
7
use Location\Coordinate;
8
use Location\Line;
9
10
/**
11
 * Calculate the perpendicular distance between a Line and a Point.
12
 *
13
 * @author Marcus Jaschen <[email protected]>
14
 */
15
class PerpendicularDistance
16
{
17
    /**
18
     * @param Coordinate $point
19
     * @param Line $line
20
     *
21
     * @return float
22
     */
23
    public function getPerpendicularDistance(Coordinate $point, Line $line): float
24
    {
25
        $ellipsoid = $point->getEllipsoid();
26
27
        $ellipsoidRadius = $ellipsoid->getArithmeticMeanRadius();
28
29
        $firstLinePointLat = $this->deg2radLatitude($line->getPoint1()->getLat());
30
        $firstLinePointLng = $this->deg2radLongitude($line->getPoint1()->getLng());
31
32
        $firstLinePointX = $ellipsoidRadius * cos($firstLinePointLng) * sin($firstLinePointLat);
33
        $firstLinePointY = $ellipsoidRadius * sin($firstLinePointLng) * sin($firstLinePointLat);
34
        $firstLinePointZ = $ellipsoidRadius * cos($firstLinePointLat);
35
36
        $secondLinePointLat = $this->deg2radLatitude($line->getPoint2()->getLat());
37
        $secondLinePointLng = $this->deg2radLongitude($line->getPoint2()->getLng());
38
39
        $secondLinePointX = $ellipsoidRadius * cos($secondLinePointLng) * sin($secondLinePointLat);
40
        $secondLinePointY = $ellipsoidRadius * sin($secondLinePointLng) * sin($secondLinePointLat);
41
        $secondLinePointZ = $ellipsoidRadius * cos($secondLinePointLat);
42
43
        $pointLat = $this->deg2radLatitude($point->getLat());
44
        $pointLng = $this->deg2radLongitude($point->getLng());
45
46
        $pointX = $ellipsoidRadius * cos($pointLng) * sin($pointLat);
47
        $pointY = $ellipsoidRadius * sin($pointLng) * sin($pointLat);
48
        $pointZ = $ellipsoidRadius * cos($pointLat);
49
50
        $normalizedX = $firstLinePointY * $secondLinePointZ - $firstLinePointZ * $secondLinePointY;
51
        $normalizedY = $firstLinePointZ * $secondLinePointX - $firstLinePointX * $secondLinePointZ;
52
        $normalizedZ = $firstLinePointX * $secondLinePointY - $firstLinePointY * $secondLinePointX;
53
54
        $length = sqrt($normalizedX * $normalizedX + $normalizedY * $normalizedY + $normalizedZ * $normalizedZ);
55
56
        if ($length == 0.0) {
57
            return 0;
58
        }
59
60
        $normalizedX /= $length;
61
        $normalizedY /= $length;
62
        $normalizedZ /= $length;
63
64
        $thetaPoint = $normalizedX * $pointX + $normalizedY * $pointY + $normalizedZ * $pointZ;
65
66
        $length = sqrt($pointX * $pointX + $pointY * $pointY + $pointZ * $pointZ);
67
68
        $thetaPoint /= $length;
69
70
        $distance = (float)abs((M_PI / 2) - acos($thetaPoint));
71
72
        return $distance * $ellipsoidRadius;
73
    }
74
75
    /**
76
     * @param float $latitude
77
     *
78
     * @return float
79
     */
80
    protected function deg2radLatitude(float $latitude): float
81
    {
82
        return deg2rad(90 - $latitude);
83
    }
84
85
    /**
86
     * @param float $longitude
87
     *
88
     * @return float
89
     */
90
    protected function deg2radLongitude(float $longitude): float
91
    {
92
        if ($longitude > 0) {
93
            return deg2rad($longitude);
94
        }
95
96
        return deg2rad($longitude + 360);
97
    }
98
}
99