• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

brick / geo / 13633473181

03 Mar 2025 02:25PM UTC coverage: 83.61% (+0.2%) from 83.425%
13633473181

push

github

BenMorel
BoundingBox: readonly + promoted properties

21 of 28 new or added lines in 10 files covered. (75.0%)

41 existing lines in 5 files now uncovered.

1561 of 1867 relevant lines covered (83.61%)

1882.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.67
/src/BoundingBox.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Brick\Geo;
6

7
use Brick\Geo\Exception\CoordinateSystemException;
8
use Brick\Geo\Exception\EmptyGeometryException;
9

10
/**
11
 * Represents a 2D or 3D bounding box calculated from a set of points. M coordinates are ignored.
12
 * This class is immutable.
13
 */
14
final readonly class BoundingBox
15
{
16
    /**
17
     * Private constructor.
18
     * Use the BoundingBox::new() factory method to obtain an instance.
19
     */
20
    private function __construct(
21
        public ?CoordinateSystem $cs,
22
        public ?float $swX,
23
        public ?float $swY,
24
        public ?float $swZ,
25
        public ?float $neX,
26
        public ?float $neY,
27
        public ?float $neZ,
28
    ) {
29
    }
49✔
30

31
    /**
32
     * Creates an empty BoundingBox instance.
33
     */
34
    public static function new(): BoundingBox
35
    {
36
        return new BoundingBox(
49✔
37
            null,
49✔
38
            null,
49✔
39
            null,
49✔
40
            null,
49✔
41
            null,
49✔
42
            null,
49✔
43
            null,
49✔
44
        );
49✔
45
    }
46

47
    /**
48
     * Returns a copy of this BoundingBox extended with the given Point.
49
     *
50
     * @throws CoordinateSystemException
51
     */
52
    public function extendedWithPoint(Point $point) : BoundingBox
53
    {
54
        if ($point->isEmpty()) {
35✔
UNCOV
55
            return $this;
×
56
        }
57

58
        $point = $point->withoutM();
35✔
59

60
        if ($this->cs === null) {
35✔
61
            $cs = $point->coordinateSystem();
35✔
62
        } else {
63
            $cs = $this->cs;
35✔
64
            if (! $cs->isEqualTo($point->coordinateSystem())) {
35✔
65
                throw CoordinateSystemException::dimensionalityMix($cs, $point->coordinateSystem());
14✔
66
            }
67
        }
68

69
        $x = $point->x();
35✔
70
        $y = $point->y();
35✔
71
        $z = $point->z();
35✔
72

73
        $swX = ($this->swX === null) ? $x : min($this->swX, $x);
35✔
74
        $swY = ($this->swY === null) ? $y : min($this->swY, $y);
35✔
75

76
        $neX = ($this->neX === null) ? $x : max($this->neX, $x);
35✔
77
        $neY = ($this->neY === null) ? $y : max($this->neY, $y);
35✔
78

79
        if ($z !== null) {
35✔
80
            $swZ = ($this->swZ === null) ? $z : min($this->swZ, $z);
7✔
81
            $neZ = ($this->neZ === null) ? $z : max($this->neZ, $z);
7✔
82
        } else {
83
            $swZ = null;
28✔
84
            $neZ = null;
28✔
85
        }
86

87
        if (
88
            $swX === $this->swX && $swY === $this->swY && $swZ === $this->swZ &&
35✔
89
            $neX === $this->neX && $neY === $this->neY && $neZ === $this->neZ
35✔
90
        ) {
91
            return $this;
14✔
92
        }
93

94
        return new BoundingBox(
35✔
95
            $cs,
35✔
96
            $swX,
35✔
97
            $swY,
35✔
98
            $swZ,
35✔
99
            $neX,
35✔
100
            $neY,
35✔
101
            $neZ,
35✔
102
        );
35✔
103
    }
104

105
    /**
106
     * Returns a copy of this BoundingBox extended with the given BoundingBox.
107
     *
108
     * @throws CoordinateSystemException
109
     */
110
    public function extendedWithBoundingBox(BoundingBox $boundingBox) : BoundingBox
111
    {
112
        if ($boundingBox->isEmpty()) {
7✔
UNCOV
113
            return $this;
×
114
        }
115

116
        return $this
7✔
117
            ->extendedWithPoint($boundingBox->getSouthWest())
7✔
118
            ->extendedWithPoint($boundingBox->getNorthEast());
7✔
119
    }
120

121
    public function isEmpty() : bool
122
    {
123
        return $this->cs === null;
7✔
124
    }
125

126
    /**
127
     * Returns the south-west XY or XYZ point.
128
     *
129
     * @throws EmptyGeometryException
130
     */
131
    public function getSouthWest() : Point
132
    {
133
        if ($this->cs === null) {
28✔
134
            throw new EmptyGeometryException('The bounding box is empty.');
7✔
135
        }
136

137
        assert($this->swX !== null);
138
        assert($this->swY !== null);
139

140
        if ($this->cs->hasZ()) {
21✔
141
            assert($this->swZ !== null);
142
            $coords = [$this->swX, $this->swY, $this->swZ];
7✔
143
        } else {
144
            $coords = [$this->swX, $this->swY];
14✔
145
        }
146

147
        return new Point($this->cs, ...$coords);
21✔
148
    }
149

150
    /**
151
     * Returns the north-east XY or XYZ point.
152
     *
153
     * @throws EmptyGeometryException
154
     */
155
    public function getNorthEast() : Point
156
    {
157
        if ($this->cs === null) {
28✔
158
            throw new EmptyGeometryException('The bounding box is empty.');
7✔
159
        }
160

161
        if ($this->cs->hasZ()) {
21✔
162
            $coords = [$this->neX, $this->neY, $this->neZ];
7✔
163
        } else {
164
            $coords = [$this->neX, $this->neY];
14✔
165
        }
166

167
        /** @var list<float> $coords */
168
        return new Point($this->cs, ...$coords);
21✔
169
    }
170
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc