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

brick / geo / 17456208570

04 Sep 2025 07:10AM UTC coverage: 50.432%. Remained the same
17456208570

push

github

BenMorel
Use @extends and @implements instead of @template-* variants

For consistency with the rest of the project.

1867 of 3702 relevant lines covered (50.43%)

1140.21 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
use function assert;
11
use function max;
12
use function min;
13

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

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

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

61
        $point = $point->withoutM();
40✔
62

63
        if ($this->cs === null) {
40✔
64
            $cs = $point->coordinateSystem();
40✔
65
        } else {
66
            $cs = $this->cs;
40✔
67
            if (! $cs->isEqualTo($point->coordinateSystem())) {
40✔
68
                throw CoordinateSystemException::dimensionalityMix($cs, $point->coordinateSystem());
16✔
69
            }
70
        }
71

72
        $x = $point->x();
40✔
73
        $y = $point->y();
40✔
74
        $z = $point->z();
40✔
75

76
        $swX = ($this->swX === null) ? $x : min($this->swX, $x);
40✔
77
        $swY = ($this->swY === null) ? $y : min($this->swY, $y);
40✔
78

79
        $neX = ($this->neX === null) ? $x : max($this->neX, $x);
40✔
80
        $neY = ($this->neY === null) ? $y : max($this->neY, $y);
40✔
81

82
        if ($z !== null) {
40✔
83
            $swZ = ($this->swZ === null) ? $z : min($this->swZ, $z);
8✔
84
            $neZ = ($this->neZ === null) ? $z : max($this->neZ, $z);
8✔
85
        } else {
86
            $swZ = null;
32✔
87
            $neZ = null;
32✔
88
        }
89

90
        if (
91
            $swX === $this->swX && $swY === $this->swY && $swZ === $this->swZ &&
40✔
92
            $neX === $this->neX && $neY === $this->neY && $neZ === $this->neZ
40✔
93
        ) {
94
            return $this;
16✔
95
        }
96

97
        return new BoundingBox(
40✔
98
            $cs,
40✔
99
            $swX,
40✔
100
            $swY,
40✔
101
            $swZ,
40✔
102
            $neX,
40✔
103
            $neY,
40✔
104
            $neZ,
40✔
105
        );
40✔
106
    }
107

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

119
        return $this
8✔
120
            ->extendedWithPoint($boundingBox->getSouthWest())
8✔
121
            ->extendedWithPoint($boundingBox->getNorthEast());
8✔
122
    }
123

124
    public function isEmpty(): bool
125
    {
126
        return $this->cs === null;
8✔
127
    }
128

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

140
        assert($this->swX !== null);
141
        assert($this->swY !== null);
142

143
        if ($this->cs->hasZ()) {
24✔
144
            assert($this->swZ !== null);
145
            $coords = [$this->swX, $this->swY, $this->swZ];
8✔
146
        } else {
147
            $coords = [$this->swX, $this->swY];
16✔
148
        }
149

150
        return new Point($this->cs, ...$coords);
24✔
151
    }
152

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

164
        if ($this->cs->hasZ()) {
24✔
165
            $coords = [$this->neX, $this->neY, $this->neZ];
8✔
166
        } else {
167
            $coords = [$this->neX, $this->neY];
16✔
168
        }
169

170
        /** @var list<float> $coords */
171
        return new Point($this->cs, ...$coords);
24✔
172
    }
173
}
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