Passed
Push — master ( 0a16ff...1038d1 )
by Doug
28:57
created

IGNFGrid::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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