GUGiKHeightGrid   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 77
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 40
dl 0
loc 77
ccs 0
cts 40
cp 0
rs 10
c 1
b 0
f 0
wmc 8

3 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 44 6
A getValues() 0 5 1
A getRecord() 0 11 1
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 PHPCoord\UnitOfMeasure\Length\Metre;
13
use SplFixedArray;
14
15
use function explode;
16
use function max;
17
use function min;
18
use function round;
19
use function str_replace;
20
use function trim;
21
use function assert;
22
23
use const PHP_FLOAT_MAX;
24
use const PHP_FLOAT_MIN;
25
26
class GUGiKHeightGrid extends GeographicGeoidHeightGrid
27
{
28
    use BilinearInterpolation;
29
30
    /**
31
     * @var SplFixedArray<float>
32
     */
33
    private SplFixedArray $data;
34
35
    public function __construct(string $filename)
36
    {
37
        $this->storageOrder = self::STORAGE_ORDER_INCREASING_LONGITUDE_INCREASING_LATIITUDE;
38
        $this->gridFile = new GridFile($filename);
39
        $this->columnGridInterval = 0.01; // always
40
        $this->rowGridInterval = 0.01; // always
41
42
        // these files have variable length headers, and then are not rectangular!!
43
        do {
44
            $headerLine = str_replace(self::BOM, '', $this->gridFile->fgets());
45
        } while ($headerLine && $headerLine[0] === '#');
46
47
        $firstDataRowIndex = $this->gridFile->key() + 1;
48
49
        $startX = PHP_FLOAT_MAX;
50
        $endX = PHP_FLOAT_MIN;
51
        $startY = PHP_FLOAT_MAX;
52
        $endY = PHP_FLOAT_MIN;
53
        while ($row = $this->gridFile->fgets()) {
54
            $data = explode("\t", trim($row));
55
            $startX = min($startX, (float) $data[1]);
56
            $endX = max($endX, (float) $data[1]);
57
            $startY = min($startY, (float) $data[0]);
58
            $endY = max($endY, (float) $data[0]);
59
        }
60
61
        $this->startX = $startX;
62
        $this->startY = $startY;
63
        $this->numberOfColumns = (int) (string) (($endX - $startX) / $this->columnGridInterval) + 1;
64
        $this->numberOfRows = (int) (string) (($endY - $startY) / $this->rowGridInterval) + 1;
65
66
        // init with 0
67
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
68
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
69
            $this->data[$i] = 0.0;
70
        }
71
72
        // fill in with actual values
73
        $this->gridFile->seek($firstDataRowIndex);
74
        while ($row = $this->gridFile->fgets()) {
75
            $rowData = explode("\t", trim($row));
76
77
            $index = (int) round((((float) $rowData[0] - $this->startY) / $this->rowGridInterval) * $this->numberOfColumns + ((float) $rowData[1] - $this->startX) / $this->columnGridInterval);
78
            $this->data[$index] = (float) $rowData[2];
79
        }
80
    }
81
82
    /**
83
     * @return Metre[]
84
     */
85
    public function getValues(float $x, float $y): array
86
    {
87
        $shift = $this->interpolate($x, $y)[0];
88
89
        return [new Metre($shift)];
90
    }
91
92
    protected function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
93
    {
94
        $recordId = $latitudeIndex * $this->numberOfColumns + $longitudeIndex;
95
96
        assert($this->data[$recordId] !== null);
97
        $record = $this->data[$recordId];
98
99
        $longitude = $longitudeIndex * $this->columnGridInterval + $this->startX;
100
        $latitude = $latitudeIndex * $this->rowGridInterval + $this->startY;
101
102
        return new GridValues($longitude, $latitude, [$record]);
103
    }
104
}
105