Passed
Push — master ( 2c19f0...d4552d )
by Doug
46:35
created

IGNFGrid   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 124
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 74
dl 0
loc 124
ccs 77
cts 77
cp 1
rs 10
c 1
b 0
f 0
wmc 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A initTxt() 0 33 2
B initMntOrTac() 0 56 6
A getRecord() 0 13 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 SplFileObject;
12
use SplFixedArray;
13
14
use function array_map;
15
use function array_slice;
16
use function assert;
17
use function count;
18
use function explode;
19
use function max;
20
use function min;
21
use function preg_match;
22
use function preg_replace;
23
use function str_repeat;
24
use function str_replace;
25
use function strlen;
26
use function trim;
27
28
trait IGNFGrid
29
{
30
    use BilinearInterpolation;
31
32
    private int $valuesPerCoordinate;
33
34
    private SplFixedArray $data;
35
36 5
    public function __construct($filename)
37
    {
38 5
        $this->gridFile = new SplFileObject($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...
39
40 5
        match ($this->gridFile->getExtension()) {
41 5
            '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...
42 5
            '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...
43 5
        };
44
    }
45
46 5
    protected function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
47
    {
48 5
        $recordId = match ($this->storageOrder) {
49 5
            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...
50 5
            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...
51 5
        };
52
53 5
        $record = $this->data[$recordId];
54
55 5
        $longitude = $longitudeIndex * $this->columnGridInterval + $this->startX;
56 5
        $latitude = $latitudeIndex * $this->rowGridInterval + $this->startY;
57
58 5
        return new GridValues($longitude, $latitude, $record);
59
    }
60
61 2
    private function initTxt(): void
62
    {
63 2
        $this->valuesPerCoordinate = 3;
64
65 2
        $header0 = $this->gridFile->fgets();
0 ignored issues
show
Unused Code introduced by
The assignment to $header0 is dead and can be removed.
Loading history...
66 2
        $header1 = $this->gridFile->fgets();
67 2
        $header2 = $this->gridFile->fgets();
68 2
        $header3 = $this->gridFile->fgets();
0 ignored issues
show
Unused Code introduced by
The assignment to $header3 is dead and can be removed.
Loading history...
69
70 2
        $interpolationMethod = trim(str_replace('GR3D2', '', $header2));
71 2
        assert($interpolationMethod === 'INTERPOLATION BILINEAIRE');
72
73 2
        $gridDimensions = explode(' ', trim(preg_replace('/ +/', ' ', str_replace('GR3D1', '', $header1))));
74 2
        $this->startX = (float) $gridDimensions[0];
75 2
        $this->endX = (float) $gridDimensions[1];
76 2
        $this->startY = (float) $gridDimensions[2];
77 2
        $this->endY = (float) $gridDimensions[3];
78 2
        $this->columnGridInterval = (float) $gridDimensions[4];
79 2
        $this->rowGridInterval = (float) $gridDimensions[5];
80 2
        $this->numberOfColumns = (int) (string) (($this->endX - $this->startX) / $this->columnGridInterval) + 1;
81 2
        $this->numberOfRows = (int) (string) (($this->endY - $this->startY) / $this->rowGridInterval) + 1;
82 2
        $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...
83
84 2
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
85 2
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
86 2
            $rowData = explode(' ', trim(preg_replace('/ +/', ' ', $this->gridFile->fgets())));
87 2
            $wantedData = array_slice($rowData, 3, 3); // ignore weird first fixed value, coordinates, precision and map sheet
88 2
            $wantedData = array_map(static fn (string $value) => (float) $value, $wantedData);
89 2
            $this->data[$i] = $wantedData;
90
        }
91
92 2
        $this->gridFile->fgets();
93 2
        assert($this->gridFile->eof());
94
    }
95
96 3
    private function initMntOrTac(): void
97
    {
98 3
        $fixedHeaderRegexp = '^(-?[\d.]+) (-?[\d.]+) (-?[\d.]+) (-?[\d.]+) ([\d.]+) ([\d.]+) ([1-4]) ([01]) (\d) ([01]) ';
99 3
        $header = $this->gridFile->fgets();
100
101 3
        preg_match('/' . $fixedHeaderRegexp . '/', $header, $fixedHeaderParts);
102
103 3
        $this->startX = min((float) $fixedHeaderParts[1], (float) $fixedHeaderParts[2]);
104 3
        $this->endX = max((float) $fixedHeaderParts[1], (float) $fixedHeaderParts[2]);
105 3
        $this->startY = min((float) $fixedHeaderParts[3], (float) $fixedHeaderParts[4]);
106 3
        $this->endY = max((float) $fixedHeaderParts[3], (float) $fixedHeaderParts[4]);
107 3
        $this->columnGridInterval = (float) $fixedHeaderParts[5];
108 3
        $this->rowGridInterval = (float) $fixedHeaderParts[6];
109 3
        $this->numberOfColumns = (int) (string) (($this->endX - $this->startX) / $this->columnGridInterval) + 1;
110 3
        $this->numberOfRows = (int) (string) (($this->endY - $this->startY) / $this->rowGridInterval) + 1;
111 3
        $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...
112 3
        $coordinatesIncludedInData = (bool) $fixedHeaderParts[8];
113 3
        $this->valuesPerCoordinate = (int) $fixedHeaderParts[9];
114 3
        $precisionIncluded = (bool) $fixedHeaderParts[10];
115
116 3
        preg_match('/' . $fixedHeaderRegexp . str_repeat('(-?[\d.]+) ', $this->valuesPerCoordinate) . '(.*)$/', $header, $fullHeaderParts);
117
118 3
        $baseAdjustments = array_slice($fullHeaderParts, count($fullHeaderParts) - $this->valuesPerCoordinate - 1, $this->valuesPerCoordinate);
119 3
        foreach ($baseAdjustments as $baseAdjustment) {
120 3
            assert((float) $baseAdjustment === 0.0);
121
        }
122
123
        // these files are not always 1 record per line (sometimes blank lines, sometimes multiple records per row)
124
        // so direct file access is not possible. Read into memory instead :/
125
126 3
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
127
128 3
        $rawData = $this->gridFile->fread($this->gridFile->getSize() - strlen($header));
129 3
        $values = explode(' ', trim(preg_replace('/\s+/', ' ', $rawData)));
130
131 3
        $cursor = 0;
132 3
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
133 3
            if ($coordinatesIncludedInData) {
134 2
                $cursor += 2;
135
            }
136
137 3
            $rowData = [];
138 3
            for ($j = 0; $j < $this->valuesPerCoordinate; ++$j) {
139 3
                $rowData[] = (float) $values[$cursor];
140 3
                ++$cursor;
141
            }
142
143 3
            $this->data[$i] = $rowData;
144
145 3
            if ($precisionIncluded) {
146 3
                ++$cursor;
147
            }
148
        }
149
150 3
        $this->gridFile->fgets();
151 3
        assert($this->gridFile->eof());
152
    }
153
}
154