Haversine::getDistance()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Location\Distance;
6
7
use Location\Coordinate;
8
use Location\Exception\NotConvergingException;
9
use Location\Exception\NotMatchingEllipsoidException;
10
11
/**
12
 * Implementation of distance calculation with http://en.wikipedia.org/wiki/Law_of_haversines
13
 *
14
 * @see http://en.wikipedia.org/wiki/Law_of_haversines
15
 *
16
 * @author Marcus Jaschen <[email protected]>
17
 */
18
class Haversine implements DistanceInterface
19
{
20
    /**
21
     * @param Coordinate $point1
22
     * @param Coordinate $point2
23
     *
24
     * @throws NotMatchingEllipsoidException
25
     *
26
     * @return float
27
     */
28
    public function getDistance(Coordinate $point1, Coordinate $point2): float
29
    {
30
        if ($point1->getEllipsoid()->getName() !== $point2->getEllipsoid()->getName()) {
31
            throw new NotMatchingEllipsoidException('The ellipsoids for both coordinates must match');
32
        }
33
34
        $lat1 = deg2rad($point1->getLat());
35
        $lat2 = deg2rad($point2->getLat());
36
        $lng1 = deg2rad($point1->getLng());
37
        $lng2 = deg2rad($point2->getLng());
38
39
        $dLat = $lat2 - $lat1;
40
        $dLng = $lng2 - $lng1;
41
42
        $radius = $point1->getEllipsoid()->getArithmeticMeanRadius();
43
44
        $distance = 2 * $radius * asin(
45
            sqrt(
46
                (sin($dLat / 2) ** 2)
47
                + cos($lat1) * cos($lat2) * (sin($dLng / 2) ** 2)
48
            )
49
        );
50
51
        return round($distance, 3);
52
    }
53
}
54