• 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

80.77
/src/GeometryCollection.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Brick\Geo;
6

7
use ArrayIterator;
8
use Brick\Geo\Exception\CoordinateSystemException;
9
use Brick\Geo\Exception\NoSuchGeometryException;
10
use Brick\Geo\Exception\UnexpectedGeometryException;
11
use Brick\Geo\Projector\Projector;
12
use Override;
13

14
/**
15
 * A GeometryCollection is a geometric object that is a collection of some number of geometric objects.
16
 *
17
 * All the elements in a GeometryCollection shall be in the same Spatial Reference System. This is also the Spatial
18
 * Reference System for the GeometryCollection.
19
 *
20
 * GeometryCollection places no other constraints on its elements. Subclasses of GeometryCollection may restrict
21
 * membership based on dimension and may also place other constraints on the degree of spatial overlap between
22
 * elements.
23
 *
24
 * By the nature of digital representations, collections are inherently ordered by the underlying storage mechanism.
25
 * Two collections whose difference is only this order are spatially equal and will return equivalent results in any
26
 * geometric-defined operations.
27
 *
28
 * @template T of Geometry
29
 */
30
class GeometryCollection extends Geometry
31
{
32
    /**
33
     * The geometries that compose this GeometryCollection.
34
     *
35
     * This array can be empty.
36
     *
37
     * @psalm-var list<T>
38
     *
39
     * @var Geometry[]
40
     */
41
    protected array $geometries = [];
42

43
    /**
44
     * @psalm-param T ...$geometries
45
     *
46
     * @throws CoordinateSystemException   If different coordinate systems are used.
47
     * @throws UnexpectedGeometryException If a geometry is not a valid type for a subclass of GeometryCollection.
48
     */
49
    public function __construct(CoordinateSystem $cs, Geometry ...$geometries)
50
    {
51
        $isEmpty = true;
8,018✔
52

53
        foreach ($geometries as $geometry) {
8,018✔
54
            if (! $geometry->isEmpty()) {
5,011✔
55
                $isEmpty = false;
4,934✔
56
                break;
4,934✔
57
            }
58
        }
59

60
        parent::__construct($cs, $isEmpty);
8,018✔
61

62
        if (! $geometries) {
8,018✔
63
            return;
3,056✔
64
        }
65

66
        CoordinateSystem::check($this, ...$geometries);
5,011✔
67

68
        $containedGeometryType = $this->containedGeometryType();
5,011✔
69

70
        foreach ($geometries as $geometry) {
5,011✔
71
            if (! $geometry instanceof $containedGeometryType) {
5,011✔
72
                throw new UnexpectedGeometryException(sprintf(
×
73
                    '%s expects instance of %s, instance of %s given.',
×
74
                    static::class,
×
75
                    $containedGeometryType,
×
76
                    $geometry::class
×
77
                ));
×
78
            }
79
        }
80

81
        $this->geometries = array_values($geometries);
5,011✔
82
    }
83

84
    /**
85
     * Creates a non-empty GeometryCollection composed of the given geometries.
86
     *
87
     * @psalm-suppress UnsafeInstantiation
88
     *
89
     * @param Geometry    $geometry1 The first geometry.
90
     * @param Geometry ...$geometryN The subsequent geometries, if any.
91
     *
92
     * @return static
93
     *
94
     * @throws CoordinateSystemException   If the geometries use different coordinate systems.
95
     * @throws UnexpectedGeometryException If a geometry is not a valid type for a subclass of GeometryCollection.
96
     */
97
    public static function of(Geometry $geometry1, Geometry ...$geometryN) : GeometryCollection
98
    {
99
        return new static($geometry1->coordinateSystem(), $geometry1, ...$geometryN);
203✔
100
    }
101

102
    /**
103
     * Returns the number of geometries in this GeometryCollection.
104
     */
105
    public function numGeometries() : int
106
    {
107
        return count($this->geometries);
3,804✔
108
    }
109

110
    /**
111
     * Returns the specified geometry N in this GeometryCollection.
112
     *
113
     * @param int $n The geometry number, 1-based.
114
     *
115
     * @return T
116
     *
117
     * @throws NoSuchGeometryException If there is no Geometry at this index.
118
     */
119
    public function geometryN(int $n) : Geometry
120
    {
121
        if (! isset($this->geometries[$n - 1])) {
126✔
122
            throw new NoSuchGeometryException('There is no Geometry in this GeometryCollection at index ' . $n);
84✔
123
        }
124

125
        return $this->geometries[$n - 1];
42✔
126
    }
127

128
    /**
129
     * Returns the geometries that compose this GeometryCollection.
130
     *
131
     * @psalm-return list<T>
132
     *
133
     * @return Geometry[]
134
     */
135
    public function geometries() : array
136
    {
137
        return $this->geometries;
84✔
138
    }
139

140
    #[Override]
141
    public function geometryType() : string
142
    {
143
        return 'GeometryCollection';
953✔
144
    }
145

146
    #[Override]
147
    public function geometryTypeBinary() : int
148
    {
149
        return Geometry::GEOMETRYCOLLECTION;
336✔
150
    }
151

152
    #[Override]
153
    public function dimension() : int
154
    {
155
        $dimension = 0;
56✔
156

157
        foreach ($this->geometries as $geometry) {
56✔
158
            $dim = $geometry->dimension();
28✔
159

160
            if ($dim > $dimension) {
28✔
161
                $dimension = $dim;
21✔
162
            }
163
        }
164

165
        return $dimension;
56✔
166
    }
167

168
    #[Override]
169
    public function getBoundingBox() : BoundingBox
170
    {
NEW
171
        $boundingBox = BoundingBox::new();
×
172

UNCOV
173
        foreach ($this->geometries as $geometry) {
×
UNCOV
174
            $boundingBox = $boundingBox->extendedWithBoundingBox($geometry->getBoundingBox());
×
175
        }
176

UNCOV
177
        return $boundingBox;
×
178
    }
179

180
    #[Override]
181
    public function toArray() : array
182
    {
183
        $result = [];
1,624✔
184

185
        foreach ($this->geometries as $geometry) {
1,624✔
186
            $result[] = $geometry->toArray();
1,022✔
187
        }
188

189
        return $result;
1,624✔
190
    }
191

192
    #[Override]
193
    public function project(Projector $projector): GeometryCollection
194
    {
195
        return new GeometryCollection(
28✔
196
            $projector->getTargetCoordinateSystem($this->coordinateSystem),
28✔
197
            ...array_map(
28✔
198
                fn (Geometry $geometry) => $geometry->project($projector),
28✔
199
                $this->geometries,
28✔
200
            ),
28✔
201
        );
28✔
202
    }
203

204
    /**
205
     * Returns the number of geometries in this GeometryCollection.
206
     *
207
     * Required by interface Countable.
208
     */
209
    #[Override]
210
    public function count() : int
211
    {
212
        return count($this->geometries);
2,059✔
213
    }
214

215
    /**
216
     * Returns an iterator for the geometries in this GeometryCollection.
217
     *
218
     * Required by interface IteratorAggregate.
219
     *
220
     * @psalm-return ArrayIterator<int, T>
221
     */
222
    #[Override]
223
    public function getIterator() : ArrayIterator
224
    {
225
        return new ArrayIterator($this->geometries);
4,419✔
226
    }
227

228
    /**
229
     * Returns the FQCN of the contained Geometry type.
230
     *
231
     * @psalm-return class-string<T>
232
     */
233
    protected function containedGeometryType() : string
234
    {
235
        return Geometry::class;
1,103✔
236
    }
237

238
    /**
239
     * Returns a copy of this GeometryCollection, with the given geometries added.
240
     *
241
     * @psalm-suppress UnsafeInstantiation
242
     *
243
     * @param T ...$geometries
244
     *
245
     * @return GeometryCollection<T>
246
     */
247
    public function withAddedGeometries(Geometry ...$geometries): GeometryCollection
248
    {
249
        return new static($this->coordinateSystem, ...$this->geometries, ...$geometries);
147✔
250
    }
251
}
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