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

BEVHeightGrid::__construct()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 41
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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