BEVHeightGrid   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 75
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

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

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 42 4
A getRecord() 0 11 1
A getValues() 0 5 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 array_unique;
16
use function end;
17
use function explode;
18
use function round;
19
use function sort;
20
use function trim;
21
use function assert;
22
23
class BEVHeightGrid extends GeographicGeoidHeightGrid
24
{
25
    use BilinearInterpolation;
26
27
    /**
28
     * @var SplFixedArray<float>
29
     */
30
    private SplFixedArray $data;
31
32
    public function __construct(string $filename)
33
    {
34
        $this->storageOrder = self::STORAGE_ORDER_INCREASING_LONGITUDE_INCREASING_LATIITUDE;
35
        $this->gridFile = new GridFile($filename);
36
37
        // these are not rectangular!!
38
        $xs = [];
39
        $ys = [];
40
        $this->gridFile->seek(1);
41
        while ($row = $this->gridFile->fgets()) {
42
            $data = explode(';', trim($row));
43
            $xs[] = (float) $data[1];
44
            $ys[] = (float) $data[0];
45
        }
46
        $xs = array_unique($xs);
47
        $ys = array_unique($ys);
48
        sort($xs);
49
        sort($ys);
50
51
        $this->startX = $xs[0];
52
        $this->startY = $ys[0];
53
        $this->endX = (float) end($xs);
54
        $this->endY = (float) end($ys);
55
        $this->columnGridInterval = round($xs[1] - $xs[0], 7);
56
        $this->rowGridInterval = round($ys[1] - $ys[0], 7);
57
        $this->numberOfColumns = (int) (string) (($this->endX - $this->startX) / $this->columnGridInterval) + 1;
58
        $this->numberOfRows = (int) (string) (($this->endY - $this->startY) / $this->rowGridInterval) + 1;
59
60
        // init with 0
61
        $this->data = new SplFixedArray($this->numberOfColumns * $this->numberOfRows);
62
        for ($i = 0, $numValues = $this->numberOfColumns * $this->numberOfRows; $i < $numValues; ++$i) {
63
            $this->data[$i] = 0.0;
64
        }
65
66
        // fill in with actual values
67
        $this->gridFile->seek(1);
68
        while ($row = $this->gridFile->fgets()) {
69
            /** @var float[] $rowData */
70
            $rowData = explode(';', trim($row));
71
72
            $index = (int) round((($rowData[0] - $this->startY) / $this->rowGridInterval) * $this->numberOfColumns + ($rowData[1] - $this->startX) / $this->columnGridInterval);
73
            $this->data[$index] = (float) $rowData[2];
74
        }
75
    }
76
77
    /**
78
     * @return Metre[]
79
     */
80
    public function getValues(float $x, float $y): array
81
    {
82
        $shift = $this->interpolate($x, $y)[0];
83
84
        return [new Metre($shift)];
85
    }
86
87
    protected function getRecord(int $longitudeIndex, int $latitudeIndex): GridValues
88
    {
89
        $recordId = $latitudeIndex * $this->numberOfColumns + $longitudeIndex;
90
91
        assert($this->data[$recordId] !== null);
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