CardinalDirection   A
last analyzed

Complexity

Total Complexity 39

Size/Duplication

Total Lines 150
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 39
lcom 1
cbo 1
dl 0
loc 150
rs 9.28
c 0
b 0
f 0

13 Methods

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