Degrees::toDegrees()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 8
nop 3
dl 0
loc 11
ccs 9
cts 9
cp 1
crap 4
rs 10
1
<?php
2
3
namespace kalanis\kw_coordinates\Codecs;
4
5
6
use kalanis\kw_coordinates\CoordinatesException;
7
use kalanis\kw_coordinates\Interfaces;
8
use kalanis\kw_coordinates\Support;
9
10
11
/**
12
 * Class Degrees
13
 * @package kalanis\kw_coordinates\Codecs
14
 * Format data from and into degrees, minutes and seconds
15
 */
16
class Degrees implements Interfaces\ICodecs
17
{
18
    protected Interfaces\INumbers $pos;
19
    protected Interfaces\IFormatted $out;
20
21 9
    public function __construct(?Interfaces\INumbers $position = null, ?Interfaces\IFormatted $output = null)
22
    {
23 9
        $this->pos = $position ?: new Support\Position();
24 9
        $this->out = $output ?: new Support\DegreesObject();
25 9
    }
26
27 4
    public function fromLonLat(Interfaces\INumbers $position, array $params): Interfaces\IFormatted
28
    {
29 4
        return (clone $this->out)->setData(
30 4
            $this->positiveNegative($this->toDegrees($position->getLongitude(), 360, 180), 'W', 'E'),
31 4
            $this->positiveNegative($this->toDegrees($position->getLatitude(), 180, 90), 'S', 'N'),
32 4
            $position->getAltitude()
33
        );
34
    }
35
36 4
    protected function toDegrees(float $number, int $upperLimit, int $halfLimit): string
37
    {
38 4
        $subs = abs($number) - intval(abs($number));
39 4
        $part = $number % $upperLimit;
40 4
        $part = 0 < $part ? $part + $subs : $part - $subs;
41 4
        $part = $part > $halfLimit ? ($part - $upperLimit) : (($part < -$halfLimit) ? ($part + $upperLimit) : $part);
42
43 4
        $min = abs($part - intval($part)) * 60;
44 4
        $sec = ($min - intval($min)) * 60;
45 4
        $dec = $part;
46 4
        return sprintf('%d°%d\'%01.5f"', $dec, intval($min), $sec);
47
    }
48
49 4
    protected function positiveNegative(string $number, string $forNegative, string $forPositive): string
50
    {
51 4
        return (('-' == $number[0]) ? substr($number, 1) . $forNegative : $number . $forPositive);
52
    }
53
54 5
    public function toLonLat(Interfaces\IFormatted $source, array $params): Interfaces\INumbers
55
    {
56 5
        return (clone $this->pos)->setData(
57 5
            $this->fromDegrees(strval($source->getLongitude()),360, 180, 'W', 'E'),
58 4
            $this->fromDegrees(strval($source->getLatitude()), 180, 90, 'S', 'N'),
59 4
            floatval(strval($source->getAltitude()))
60
        );
61
    }
62
63
    /**
64
     * @param string $value
65
     * @param int $upperLimit
66
     * @param int $halfLimit
67
     * @param string $forNegative
68
     * @param string $forPositive
69
     * @throws CoordinatesException
70
     * @return float
71
     */
72 5
    protected function fromDegrees(string $value, int $upperLimit, int $halfLimit, string $forNegative, string $forPositive): float
73
    {
74 5
        $format = '#([0-9\.]+)[^0-9\.]*(([0-9\.]+)[^0-9\.]*(([0-9\.]+)[^0-9\.]*)?)?#isu';
75 5
        if (!preg_match($format, $value, $matches)) {
76 1
            throw new CoordinatesException(sprintf('Malformed content value *%s*', $value));
77
        }
78 4
        $result = 0.0;
79 4
        if (isset($matches[1])) {
80 4
            $result += floatval($matches[1]);
81
        }
82 4
        if (isset($matches[3])) {
83 4
            $result += (floatval($matches[3]) / 60);
84
        }
85 4
        if (isset($matches[5])) {
86 4
            $result += (floatval($matches[5]) / (60 * 60));
87
        }
88 4
        $result *= $this->plusMinus($value, $forNegative, $forPositive);
89
90 4
        $subs = abs($result) - intval(abs($result));
91 4
        $part = $result % $upperLimit;
92 4
        $part = 0 < $part ? $part + $subs : $part - $subs;
93 4
        $part = $part > $halfLimit ? ($part - $upperLimit) : (($part < -$halfLimit) ? ($part + $upperLimit) : $part);
94
95 4
        return $part;
96
    }
97
98 4
    protected function plusMinus(string $input, string $forNegative, string $forPositive): float
0 ignored issues
show
Unused Code introduced by
The parameter $forPositive is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

98
    protected function plusMinus(string $input, string $forNegative, /** @scrutinizer ignore-unused */ string $forPositive): float

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
99
    {
100 4
        return (false !== strpos($input, $forNegative)) ? -1 : 1 ;
101
    }
102
}
103