Completed
Pull Request — master (#74)
by
unknown
01:42
created

CardinalDirection::isNorthFrom()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace Location\CardinalDirection;
4
5
use Location\Coordinate;
6
7
/** @psalm-immutable */
8
class CardinalDirection
9
{
10
    public const CARDINAL_DIRECTION_NONE = 'none';
11
    public const CARDINAL_DIRECTION_NORTH = 'north';
12
    public const CARDINAL_DIRECTION_EAST = 'east';
13
    public const CARDINAL_DIRECTION_SOUTH = 'south';
14
    public const CARDINAL_DIRECTION_WEST = 'west';
15
    public const CARDINAL_DIRECTION_NORTHEAST = 'north-east';
16
    public const CARDINAL_DIRECTION_NORTHWEST = 'north-west';
17
    public const CARDINAL_DIRECTION_SOUTHEAST = 'south-east';
18
    public const CARDINAL_DIRECTION_SOUTHWEST = 'south-west';
19
20
    public function getCardinalDirection(Coordinate $point1, Coordinate $point2): string
21
    {
22
        $directionFunctionMapping = [
23
            self::CARDINAL_DIRECTION_NORTH => function (Coordinate $point1, Coordinate $point2): bool {
24
                return $this->isOnlyNorth($point1, $point2);
25
            },
26
            self::CARDINAL_DIRECTION_EAST => function (Coordinate $point1, Coordinate $point2): bool {
27
                return $this->isOnlyEast($point1, $point2);
28
            },
29
            self::CARDINAL_DIRECTION_SOUTH => function (Coordinate $point1, Coordinate $point2): bool {
30
                return $this->isOnlySouth($point1, $point2);
31
            },
32
            self::CARDINAL_DIRECTION_WEST => function (Coordinate $point1, Coordinate $point2): bool {
33
                return $this->isOnlyWest($point1, $point2);
34
            },
35
            self::CARDINAL_DIRECTION_NORTHEAST => function (Coordinate $point1, Coordinate $point2): bool {
36
                return $this->isNorthEast($point1, $point2);
37
            },
38
            self::CARDINAL_DIRECTION_SOUTHEAST => function (Coordinate $point1, Coordinate $point2): bool {
39
                return $this->isSouthEast($point1, $point2);
40
            },
41
            self::CARDINAL_DIRECTION_SOUTHWEST => function (Coordinate $point1, Coordinate $point2): bool {
42
                return $this->isSouthWest($point1, $point2);
43
            },
44
            self::CARDINAL_DIRECTION_NORTHWEST => function (Coordinate $point1, Coordinate $point2): bool {
45
                return $this->isNorthWest($point1, $point2);
46
            },
47
        ];
48
49
        foreach ($directionFunctionMapping as $direction => $function) {
50
            if (call_user_func($function, $point1, $point2)) {
51
                return $direction;
52
            }
53
        }
54
55
        return self::CARDINAL_DIRECTION_NONE;
56
    }
57
58
    private function isOnlyNorth(Coordinate $point1, Coordinate $point2): bool
59
    {
60
        return (
61
            !$this->isEastFrom($point1, $point2)
62
            && !$this->isSouthFrom($point1, $point2)
63
            && !$this->isWestFrom($point1, $point2)
64
            && $this->isNorthFrom($point1, $point2)
65
        );
66
    }
67
68
    private function isOnlyEast(Coordinate $point1, Coordinate $point2): bool
69
    {
70
        return (
71
            $this->isEastFrom($point1, $point2)
72
            && !$this->isSouthFrom($point1, $point2)
73
            && !$this->isWestFrom($point1, $point2)
74
            && !$this->isNorthFrom($point1, $point2)
75
        );
76
    }
77
78
    private function isOnlySouth(Coordinate $point1, Coordinate $point2): bool
79
    {
80
        return (
81
            !$this->isEastFrom($point1, $point2)
82
            && $this->isSouthFrom($point1, $point2)
83
            && !$this->isWestFrom($point1, $point2)
84
            && !$this->isNorthFrom($point1, $point2)
85
        );
86
    }
87
88
    private function isOnlyWest(Coordinate $point1, Coordinate $point2): bool
89
    {
90
        return (
91
            !$this->isEastFrom($point1, $point2)
92
            && !$this->isSouthFrom($point1, $point2)
93
            && $this->isWestFrom($point1, $point2)
94
            && !$this->isNorthFrom($point1, $point2)
95
        );
96
    }
97
98
    private function isNorthEast(Coordinate $point1, Coordinate $point2): bool
99
    {
100
        return (
101
            $this->isEastFrom($point1, $point2)
102
            && !$this->isSouthFrom($point1, $point2)
103
            && !$this->isWestFrom($point1, $point2)
104
            && $this->isNorthFrom($point1, $point2)
105
        );
106
    }
107
108
    private function isSouthEast(Coordinate $point1, Coordinate $point2): bool
109
    {
110
        return (
111
            $this->isEastFrom($point1, $point2)
112
            && $this->isSouthFrom($point1, $point2)
113
            && !$this->isWestFrom($point1, $point2)
114
            && !$this->isNorthFrom($point1, $point2)
115
        );
116
    }
117
118
    private function isSouthWest(Coordinate $point1, Coordinate $point2): bool
119
    {
120
        return (
121
            !$this->isEastFrom($point1, $point2)
122
            && $this->isSouthFrom($point1, $point2)
123
            && $this->isWestFrom($point1, $point2)
124
            && !$this->isNorthFrom($point1, $point2)
125
        );
126
    }
127
128
    private function isNorthWest(Coordinate $point1, Coordinate $point2): bool
129
    {
130
        return (
131
            !$this->isEastFrom($point1, $point2)
132
            && !$this->isSouthFrom($point1, $point2)
133
            && $this->isWestFrom($point1, $point2)
134
            && $this->isNorthFrom($point1, $point2)
135
        );
136
    }
137
138
    private function isNorthFrom(Coordinate $point1, Coordinate $point2): bool
139
    {
140
        return $point1->getLat() > $point2->getLat();
141
    }
142
143
    private function isSouthFrom(Coordinate $point1, Coordinate $point2): bool
144
    {
145
        return $point1->getLat() < $point2->getLat();
146
    }
147
148
    private function isEastFrom(Coordinate $point1, Coordinate $point2): bool
149
    {
150
        return $point1->getLng() > $point2->getLng();
151
    }
152
153
    private function isWestFrom(Coordinate $point1, Coordinate $point2): bool
154
    {
155
        return $point1->getLng() < $point2->getLng();
156
    }
157
}
158