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

IGNESHeightGrid   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

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

4 Methods

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