Completed
Push — master ( 823036...442710 )
by Marcus
04:04
created

parseDecimalMinutesWithCardinalLetters()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 6
Ratio 30 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 6
loc 20
rs 8.8571
cc 6
eloc 10
nc 5
nop 2
1
<?php
2
/**
3
 * Coordinate Factory
4
 *
5
 * @author   Marcus Jaschen <[email protected]>
6
 * @license  https://opensource.org/licenses/GPL-3.0 GPL
7
 * @link     https://github.com/mjaschen/phpgeo
8
 */
9
10
namespace Location\Factory;
11
12
use Location\Coordinate;
13
use Location\Ellipsoid;
14
15
/**
16
 * Coordinate Factory
17
 *
18
 * @author   Marcus Jaschen <[email protected]>
19
 * @license  https://opensource.org/licenses/GPL-3.0 GPL
20
 * @link     https://github.com/mjaschen/phpgeo
21
 */
22
class CoordinateFactory implements GeometryFactoryInterface
23
{
24
    /**
25
     * Creates a Coordinate instance from the given string.
26
     *
27
     * The string is parsed by a regular expression for a known
28
     * format of geographical coordinates.
29
     *
30
     * @param string $string formatted geographical coordinate
31
     * @param \Location\Ellipsoid $ellipsoid
32
     *
33
     * @return \Location\Coordinate
34
     */
35
    public static function fromString($string, Ellipsoid $ellipsoid = null)
36
    {
37
        $result = static::parseDecimalMinutesWithoutCardinalLetters($string, $ellipsoid);
0 ignored issues
show
Bug introduced by
Since parseDecimalMinutesWithoutCardinalLetters() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of parseDecimalMinutesWithoutCardinalLetters() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
38
39
        if ($result instanceof Coordinate) {
40
            return $result;
41
        }
42
43
        $result = static::parseDecimalMinutesWithCardinalLetters($string, $ellipsoid);
0 ignored issues
show
Bug introduced by
Since parseDecimalMinutesWithCardinalLetters() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of parseDecimalMinutesWithCardinalLetters() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
44
45
        if ($result instanceof Coordinate) {
46
            return $result;
47
        }
48
49
        $result = static::parseDecimalDegreesWithoutCardinalLetters($string, $ellipsoid);
0 ignored issues
show
Bug introduced by
Since parseDecimalDegreesWithoutCardinalLetters() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of parseDecimalDegreesWithoutCardinalLetters() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
50
51
        if ($result instanceof Coordinate) {
52
            return $result;
53
        }
54
55
        $result = static::parseDecimalDegreesWithCardinalLetters($string, $ellipsoid);
0 ignored issues
show
Bug introduced by
Since parseDecimalDegreesWithCardinalLetters() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of parseDecimalDegreesWithCardinalLetters() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
56
57
        if ($result instanceof Coordinate) {
58
            return $result;
59
        }
60
61
        throw new \InvalidArgumentException("Format of coordinates was not recognized");
62
    }
63
64
    private static function parseDecimalMinutesWithoutCardinalLetters($string, $ellipsoid)
65
    {
66
        // Decimal minutes without cardinal letters, e. g. "52 12.345, 13 23.456",
67
        // "52° 12.345, 13° 23.456", "52° 12.345′, 13° 23.456′", "52 12.345 N, 13 23.456 E",
68
        // "N52° 12.345′ E13° 23.456′"
69
        if (preg_match('/(-?\d{1,2})°?\s+(\d{1,2}\.?\d*)[\'′]?[, ]\s*(-?\d{1,3})°?\s+(\d{1,2}\.?\d*)[\'′]?/ui', $string, $match)) {
70
            $latitude = $match[1] >= 0 ? $match[1] + $match[2] / 60 : $match[1] - $match[2] / 60;
71
            $longitude = $match[3] >= 0 ? $match[3] + $match[4] / 60 : $match[3] - $match[4] / 60;
72
73
            return new Coordinate($latitude, $longitude, $ellipsoid);
74
        }
75
76
        return null;
77
    }
78
79
    private static function parseDecimalMinutesWithCardinalLetters($string, $ellipsoid)
80
    {
81
        // Decimal minutes with cardinal letters, e. g. "52 12.345, 13 23.456",
82
        // "52° 12.345, 13° 23.456", "52° 12.345′, 13° 23.456′", "52 12.345 N, 13 23.456 E",
83
        // "N52° 12.345′ E13° 23.456′"
84
        if (preg_match('/([NS]?\s*)(\d{1,2})°?\s+(\d{1,2}\.?\d*)[\'′]?(\s*[NS]?)[, ]\s*([EW]?\s*)(\d{1,3})°?\s+(\d{1,2}\.?\d*)[\'′]?(\s*[EW]?)/ui', $string, $match)) {
85
            $latitude = $match[2] + $match[3] / 60;
86 View Code Duplication
            if (trim(strtoupper($match[1])) === 'S' || trim(strtoupper($match[4])) === 'S') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
                $latitude = - $latitude;
88
            }
89
            $longitude = $match[6] + $match[7] / 60;
90 View Code Duplication
            if (trim(strtoupper($match[5])) === 'W' || trim(strtoupper($match[8])) === 'W') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
                $longitude = - $longitude;
92
            }
93
94
            return new Coordinate($latitude, $longitude, $ellipsoid);
95
        }
96
97
        return null;
98
    }
99
100
    private static function parseDecimalDegreesWithoutCardinalLetters($string, $ellipsoid)
101
    {
102
        // The most simple format: decimal degrees without cardinal letters,
103
        // e. g. "52.5, 13.5" or "53.25732 14.24984"
104
        if (preg_match('/(-?\d{1,2}\.?\d*)°?[, ]\s*(-?\d{1,3}\.?\d*)°?/u', $string, $match)) {
105
            return new Coordinate($match[1], $match[2], $ellipsoid);
106
        }
107
108
        return null;
109
    }
110
111
    private static function parseDecimalDegreesWithCardinalLetters($string, $ellipsoid)
112
    {
113
        // Decimal degrees with cardinal letters, e. g. "N52.5, E13.5",
114
        // "40.2S, 135.3485W", or "56.234°N, 157.245°W"
115
        if (preg_match('/([NS]?\s*)(\d{1,2}\.?\d*)°?(\s*[NS]?)[, ]\s*([EW]?\s*)(\d{1,3}\.?\d*)°?(\s*[EW]?)/ui', $string, $match)) {
116
            $latitude = $match[2];
117 View Code Duplication
            if (trim(strtoupper($match[1])) === 'S' || trim(strtoupper($match[3])) === 'S') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
                $latitude = - $latitude;
119
            }
120
            $longitude = $match[5];
121 View Code Duplication
            if (trim(strtoupper($match[4])) === 'W' || trim(strtoupper($match[6])) === 'W') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
122
                $longitude = - $longitude;
123
            }
124
125
            return new Coordinate($latitude, $longitude, $ellipsoid);
126
        }
127
128
        return null;
129
    }
130
}
131