Passed
Push — master ( fd93b5...48e916 )
by Doug
40:26 queued 29:39
created

IGNESHeightGrid::init()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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