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

IGNESHeightGrid::getValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
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 explode;
12
13
use PHPCoord\UnitOfMeasure\Length\Metre;
14
15
use function preg_match;
16
use function preg_replace;
17
18
use SplFileObject;
19
use SplFixedArray;
20
21
use function strlen;
22
use function trim;
23
24
class IGNESHeightGrid extends GeographicGeoidHeightGrid
25
{
26
    use BilinearInterpolation;
27
28
    private const ITERATION_CONVERGENCE = 0.0001;
29
30
    private bool $coordinatesIncludedInData;
0 ignored issues
show
introduced by
The private property $coordinatesIncludedInData is not used, and could be removed.
Loading history...
31
32
    private int $valuesPerCoordinate;
0 ignored issues
show
introduced by
The private property $valuesPerCoordinate is not used, and could be removed.
Loading history...
33
34
    private bool $precisionIncluded;
0 ignored issues
show
introduced by
The private property $precisionIncluded is not used, and could be removed.
Loading history...
35
36
    private SplFixedArray $data;
37
38 3
    public function __construct($filename)
39
    {
40 3
        $this->gridFile = new SplFileObject($filename);
41 3
        $this->init();
42
    }
43
44
    /**
45
     * @return Metre[]
46
     */
47 3
    public function getValues(float $x, float $y): array
48
    {
49 3
        $shift = $this->interpolate($x, $y)[0];
50
51 3
        return [new Metre($shift)];
52
    }
53
54 3
    protected function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
55
    {
56 3
        $recordId = ($this->numberOfRows - $latitudeIndex - 1) * $this->numberOfColumns + $longitudeIndex;
57
58 3
        $record = $this->data[$recordId];
59
60 3
        $longitude = $longitudeIndex * $this->columnGridInterval + $this->startX;
61 3
        $latitude = $latitudeIndex * $this->rowGridInterval + $this->startY;
62
63 3
        return new GridValues($longitude, $latitude, $record);
64
    }
65
66 3
    private function init(): void
67
    {
68 3
        $headerRegexp = '^\s+(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)\s+([\d.]+)\s+([\d.]+)';
69 3
        $header = $this->gridFile->fgets();
70
71 3
        preg_match('/' . $headerRegexp . '/', $header, $headerParts);
72
73 3
        $this->columnGridInterval = $headerParts[4] / 60;
74 3
        $this->rowGridInterval = $headerParts[3] / 60;
75 3
        $this->numberOfColumns = (int) $headerParts[6];
76 3
        $this->numberOfRows = (int) $headerParts[5];
77 3
        $this->startX = (float) $headerParts[2];
78 3
        if ($this->startX > 180) {
79 3
            $this->startX -= 360;
80
        }
81 3
        $this->endX = $this->startX + ($this->numberOfColumns - 1) * $this->columnGridInterval;
82 3
        $this->endY = (float) $headerParts[1];
83 3
        $this->startY = $this->endY - ($this->numberOfRows - 1) * $this->rowGridInterval;
84
85
        // these files are not 1 record per line so direct file access is not possible. Read into memory instead :/
86
87 3
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
88
89 3
        $rawData = $this->gridFile->fread($this->gridFile->getSize() - strlen($header));
90 3
        $values = explode(' ', trim(preg_replace('/\s+/', ' ', $rawData)));
91
92 3
        $cursor = 0;
93 3
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
94 3
            $rowData = [(float) $values[$cursor]];
95 3
            ++$cursor;
96
97 3
            $this->data[$i] = $rowData;
98
        }
99
    }
100
}
101