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