Passed
Push — master ( 6be4bd...2c19f0 )
by Doug
51:47
created

GUGiKHeightGrid   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 73
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

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

3 Methods

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