IGNESHeightGrid::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
/**
4
 * PHPCoord.
5
 *
6
 * @author Doug Wright
7
 */
8
declare(strict_types=1);
9
10
namespace PHPCoord\CoordinateOperation;
11
12
use Composer\Pcre\Preg;
13
use PHPCoord\UnitOfMeasure\Length\Metre;
14
use SplFixedArray;
15
16
use function explode;
17
use function strlen;
18
use function trim;
19
use function assert;
20
21
class IGNESHeightGrid extends GeographicGeoidHeightGrid
22
{
23
    use BilinearInterpolation;
24
25
    /**
26
     * @var SplFixedArray<array<float>>
27
     */
28
    private SplFixedArray $data;
29
30
    public function __construct(string $filename)
31
    {
32
        $this->gridFile = new GridFile($filename);
33
        $this->init();
34
    }
35
36
    /**
37
     * @return Metre[]
38
     */
39
    public function getValues(float $x, float $y): array
40
    {
41
        $shift = $this->interpolate($x, $y)[0];
42
43
        return [new Metre($shift)];
44
    }
45
46
    protected function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
47
    {
48
        $recordId = ($this->numberOfRows - $latitudeIndex - 1) * $this->numberOfColumns + $longitudeIndex;
49
50
        assert($this->data[$recordId] !== null);
51
        $record = $this->data[$recordId];
52
53
        $longitude = $longitudeIndex * $this->columnGridInterval + $this->startX;
54
        $latitude = $latitudeIndex * $this->rowGridInterval + $this->startY;
55
56
        return new GridValues($longitude, $latitude, $record);
57
    }
58
59
    private function init(): void
60
    {
61
        $headerRegexp = '^\s+(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)\s+(-?[\d.]+)\s+([\d.]+)\s+([\d.]+)';
62
        $header = $this->gridFile->fgets();
63
64
        Preg::match('/' . $headerRegexp . '/', $header, $headerParts);
65
66
        $this->columnGridInterval = (float) $headerParts[4] / 60;
67
        $this->rowGridInterval = (float) $headerParts[3] / 60;
68
        $this->numberOfColumns = (int) $headerParts[6];
69
        $this->numberOfRows = (int) $headerParts[5];
70
        $this->startX = (float) $headerParts[2];
71
        if ($this->startX > 180) {
72
            $this->startX -= 360;
73
        }
74
        $this->endX = $this->startX + ($this->numberOfColumns - 1) * $this->columnGridInterval;
75
        $this->endY = (float) $headerParts[1];
76
        $this->startY = $this->endY - ($this->numberOfRows - 1) * $this->rowGridInterval;
77
78
        // these files are not 1 record per line so direct file access is not possible. Read into memory instead :/
79
80
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
81
82
        $rawData = $this->gridFile->fread($this->gridFile->getSize() - strlen($header));
83
        $values = explode(' ', trim(Preg::replace('/\s+/', ' ', $rawData)));
84
85
        $cursor = 0;
86
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
87
            $rowData = [(float) $values[$cursor]];
88
            ++$cursor;
89
90
            $this->data[$i] = $rowData;
91
        }
92
    }
93
}
94