Test Failed
Push — master ( 0ba812...546388 )
by Mr
02:44
created

Geo::getCoordinatesWithinRadius()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 3
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace DrMVC\Helpers;
4
5
/**
6
 * Simple GeoPosition class based on below answer
7
 * @link http://stackoverflow.com/a/17286519/7977798
8
 * @package DrMVC\Helpers
9
 */
10
class Geo
11
{
12
13
    /**
14
     * Generate array of random coordinates for tests
15
     *
16
     * @param   int $count Count of results
17
     * @param   int $radius In kilometers
18
     * @return  array
19
     */
20
    public static function randomCoordinates($count = 1, $radius = 100): array
21
    {
22
        $result = [];
23
        // If count is set
24
        for ($i = 0; $i < $count; $i++) {
25
            // Random angle (from 0 bad idea)
26
            $angle = deg2rad(mt_rand(1, 359));
27
            // Random radius (from 0 bad idea)
28
            $pointRadius = mt_rand(1, $radius);
29
            // Result array
30
            $result[] = [
31
                // Latitude
32
                sin($angle) * $pointRadius,
33
                // Longitude
34
                cos($angle) * $pointRadius
35
            ];
36
        }
37
38
        return $result;
39
    }
40
41
    /**
42
     * The length of an arc of a unit circle is numerically equal to
43
     * the measurement in radians of the angle that it subtends.
44
     *
45
     * @link https://en.wikipedia.org/wiki/Radian
46
     * @param string $degree - The number needed to calculate radians
47
     * @return float|int
48
     */
49
    public static function radians($degree)
50
    {
51
        return $degree * M_PI / 180;
52
    }
53
54
    /**
55
     * Return array of coordinates within some radius
56
     *
57
     * @param array $coordinates - Multidimensional array of coordinates [[latitude,longitude],[latitude,longitude],[latitude,longitude]]
58
     * @param array $center - Simple array with coordinates [latitude,longitude]
59
     * @param string $radius - In kilometers or meters (1 - km, .1 - 100 meters)
60
     * @return array - Simple array with LAT,LON coordinates which are within the radius
61
     */
62
    public static function getCoordinatesWithinRadius($coordinates, $center, $radius)
63
    {
64
        $resultArray = [];
65
        list($lat1, $long1) = $center;
66
        foreach ($coordinates as $key => $value) {
67
            list($lat2, $long2) = $value;
68
            $distance = 3959 * acos(cos(self::radians($lat1)) * cos(self::radians($lat2)) * cos(self::radians($long2) - self::radians($long1)) + sin(self::radians($lat1)) * sin(self::radians($lat2)));
69
            if ($distance < $radius) {
70
                $resultArray[$key] = $value;
71
            }
72
        }
73
        return $resultArray;
74
    }
75
76
}
77