Passed
Push — master ( 0a16ff...1038d1 )
by Doug
28:57
created

BEVHeightGrid::getValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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