Passed
Push — master ( 0baa7a...f13449 )
by Doug
50:51
created

IGNFGrid   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 130
Duplicated Lines 0 %

Test Coverage

Coverage 62.5%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 77
dl 0
loc 130
ccs 50
cts 80
cp 0.625
rs 10
c 1
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A initTxt() 0 33 2
B initMntOrTac() 0 56 6
A getRecord() 0 15 1
1
<?php
2
/**
3
 * PHPCoord.
4
 *
5
 * @author Doug Wright
6
 */
7
declare(strict_types=1);
8
9
namespace PHPCoord\CoordinateOperation;
10
11
use Composer\Pcre\Preg;
12
use PHPCoord\Exception\UnknownConversionException;
13
use SplFixedArray;
14
15
use function array_map;
16
use function array_slice;
17
use function assert;
18
use function count;
19
use function explode;
20
use function max;
21
use function min;
22
use function str_repeat;
23
use function str_replace;
24
use function strlen;
25
use function trim;
26
27
trait IGNFGrid
28
{
29
    use BilinearInterpolation;
30
31
    private int $valuesPerCoordinate;
32
33
    /**
34
     * @var SplFixedArray<array<float>>
35
     */
36
    private SplFixedArray $data;
37
38 2
    public function __construct(string $filename)
39
    {
40 2
        $this->gridFile = new GridFile($filename);
0 ignored issues
show
Bug Best Practice introduced by
The property gridFile does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
41
42 2
        match ($this->gridFile->getExtension()) {
43
            'txt' => $this->initTxt(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->initTxt() targeting PHPCoord\CoordinateOperation\IGNFGrid::initTxt() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
44 2
            'mnt', 'tac' => $this->initMntOrTac(),
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->initMntOrTac() targeting PHPCoord\CoordinateOpera...GNFGrid::initMntOrTac() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
45
            default => throw new UnknownConversionException('Unable to determine file type of file: ' . $this->gridFile->getFilename())
46 2
        };
47
    }
48
49 2
    protected function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
50
    {
51 2
        $recordId = match ($this->storageOrder) {
52 2
            self::STORAGE_ORDER_INCREASING_LATITUDE_INCREASING_LONGITUDE => ($longitudeIndex * $this->numberOfRows + $latitudeIndex),
0 ignored issues
show
Bug introduced by
The constant PHPCoord\CoordinateOpera...DE_INCREASING_LONGITUDE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
53
            self::STORAGE_ORDER_INCREASING_LONGITUDE_DECREASING_LATIITUDE => ($this->numberOfRows - $latitudeIndex - 1) * $this->numberOfColumns + $longitudeIndex,
0 ignored issues
show
Bug introduced by
The constant PHPCoord\CoordinateOpera...DE_DECREASING_LATIITUDE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
54
            default => throw new UnknownConversionException('Unknown storage order for file: ' . $this->gridFile->getFilename())
55 2
        };
56
57 2
        assert($this->data[$recordId] !== null);
58 2
        $record = $this->data[$recordId];
59
60 2
        $longitude = $longitudeIndex * $this->columnGridInterval + $this->startX;
61 2
        $latitude = $latitudeIndex * $this->rowGridInterval + $this->startY;
62
63 2
        return new GridValues($longitude, $latitude, $record);
64
    }
65
66
    private function initTxt(): void
67
    {
68
        $this->valuesPerCoordinate = 3;
69
70
        $header0 = $this->gridFile->fgets();
0 ignored issues
show
Unused Code introduced by
The assignment to $header0 is dead and can be removed.
Loading history...
71
        $header1 = $this->gridFile->fgets();
72
        $header2 = $this->gridFile->fgets();
73
        $header3 = $this->gridFile->fgets();
0 ignored issues
show
Unused Code introduced by
The assignment to $header3 is dead and can be removed.
Loading history...
74
75
        $interpolationMethod = trim(str_replace('GR3D2', '', $header2));
76
        assert($interpolationMethod === 'INTERPOLATION BILINEAIRE');
77
78
        $gridDimensions = explode(' ', trim(Preg::replace('/ +/', ' ', str_replace('GR3D1', '', $header1))));
79
        $this->startX = (float) $gridDimensions[0];
80
        $this->endX = (float) $gridDimensions[1];
81
        $this->startY = (float) $gridDimensions[2];
82
        $this->endY = (float) $gridDimensions[3];
83
        $this->columnGridInterval = (float) $gridDimensions[4];
84
        $this->rowGridInterval = (float) $gridDimensions[5];
85
        $this->numberOfColumns = (int) (string) (($this->endX - $this->startX) / $this->columnGridInterval) + 1;
86
        $this->numberOfRows = (int) (string) (($this->endY - $this->startY) / $this->rowGridInterval) + 1;
87
        $this->storageOrder = self::STORAGE_ORDER_INCREASING_LATITUDE_INCREASING_LONGITUDE;
0 ignored issues
show
Bug Best Practice introduced by
The property storageOrder does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
The constant PHPCoord\CoordinateOpera...DE_INCREASING_LONGITUDE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
88
89
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
90
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
91
            $rowData = explode(' ', trim(Preg::replace('/ +/', ' ', $this->gridFile->fgets())));
92
            $wantedData = array_slice($rowData, 3, 3); // ignore weird first fixed value, coordinates, precision and map sheet
93
            $wantedData = array_map(static fn (string $value) => (float) $value, $wantedData);
94
            $this->data[$i] = $wantedData;
95
        }
96
97
        $this->gridFile->fgets();
98
        assert($this->gridFile->eof());
99
    }
100
101 2
    private function initMntOrTac(): void
102
    {
103 2
        $fixedHeaderRegexp = '^(-?[\d.]+) (-?[\d.]+) (-?[\d.]+) (-?[\d.]+) ([\d.]+) ([\d.]+) ([1-4]) ([01]) (\d) ([01]) ';
104 2
        $header = $this->gridFile->fgets();
105
106 2
        Preg::match('/' . $fixedHeaderRegexp . '/', $header, $fixedHeaderParts);
107
108 2
        $this->startX = min((float) $fixedHeaderParts[1], (float) $fixedHeaderParts[2]);
109 2
        $this->endX = max((float) $fixedHeaderParts[1], (float) $fixedHeaderParts[2]);
110 2
        $this->startY = min((float) $fixedHeaderParts[3], (float) $fixedHeaderParts[4]);
111 2
        $this->endY = max((float) $fixedHeaderParts[3], (float) $fixedHeaderParts[4]);
112 2
        $this->columnGridInterval = (float) $fixedHeaderParts[5];
113 2
        $this->rowGridInterval = (float) $fixedHeaderParts[6];
114 2
        $this->numberOfColumns = (int) (string) (($this->endX - $this->startX) / $this->columnGridInterval) + 1;
115 2
        $this->numberOfRows = (int) (string) (($this->endY - $this->startY) / $this->rowGridInterval) + 1;
116 2
        $this->storageOrder = (int) $fixedHeaderParts[7];
0 ignored issues
show
Bug Best Practice introduced by
The property storageOrder does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
117 2
        $coordinatesIncludedInData = (bool) $fixedHeaderParts[8];
118 2
        $this->valuesPerCoordinate = (int) $fixedHeaderParts[9];
119 2
        $precisionIncluded = (bool) $fixedHeaderParts[10];
120
121 2
        Preg::match('/' . $fixedHeaderRegexp . str_repeat('(-?[\d.]+) ', $this->valuesPerCoordinate) . '(.*)$/', $header, $fullHeaderParts);
122
123 2
        $baseAdjustments = array_slice($fullHeaderParts, count($fullHeaderParts) - $this->valuesPerCoordinate - 1, $this->valuesPerCoordinate);
124 2
        foreach ($baseAdjustments as $baseAdjustment) {
125 2
            assert((float) $baseAdjustment === 0.0);
126
        }
127
128
        // these files are not always 1 record per line (sometimes blank lines, sometimes multiple records per row)
129
        // so direct file access is not possible. Read into memory instead :/
130
131 2
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
132
133 2
        $rawData = $this->gridFile->fread($this->gridFile->getSize() - strlen($header));
134 2
        $values = explode(' ', trim(Preg::replace('/\s+/', ' ', $rawData)));
135
136 2
        $cursor = 0;
137 2
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
138 2
            if ($coordinatesIncludedInData) {
139 2
                $cursor += 2;
140
            }
141
142 2
            $rowData = [];
143 2
            for ($j = 0; $j < $this->valuesPerCoordinate; ++$j) {
144 2
                $rowData[] = (float) $values[$cursor];
145 2
                ++$cursor;
146
            }
147
148 2
            $this->data[$i] = $rowData;
149
150 2
            if ($precisionIncluded) {
151 2
                ++$cursor;
152
            }
153
        }
154
155 2
        $this->gridFile->fgets();
156 2
        assert($this->gridFile->eof());
157
    }
158
}
159