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

brick / geo / 13971277707

20 Mar 2025 02:05PM UTC coverage: 65.568% (+0.1%) from 65.472%
13971277707

push

github

BenMorel
Accept $prettyPrint in AbstractWktWriter constructor

1889 of 2881 relevant lines covered (65.57%)

1480.09 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\Attribute\NoProxy;
9
use Brick\Geo\Exception\CoordinateSystemException;
10
use Brick\Geo\Exception\NoSuchGeometryException;
11
use Brick\Geo\Exception\UnexpectedGeometryException;
12
use Brick\Geo\Projector\Projector;
13
use Override;
14

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

43
    /**
44
     * @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,938✔
52

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

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

62
        $this->geometries = array_values($geometries);
8,938✔
63

64
        if (! $geometries) {
8,938✔
65
            return;
3,241✔
66
        }
67

68
        CoordinateSystem::check($this, ...$geometries);
5,753✔
69

70
        $containedGeometryType = $this->containedGeometryType();
5,753✔
71

72
        foreach ($geometries as $geometry) {
5,753✔
73
            /**
74
             * @psalm-suppress DocblockTypeContradiction We do want to enforce this in code, as not everyone uses static analysis!
75
             * @psalm-suppress MixedArgument It looks like due to this check, Psalm considers that $geometry no longer has a type.
76
             */
77
            if (! $geometry instanceof $containedGeometryType) {
5,753✔
78
                throw new UnexpectedGeometryException(sprintf(
×
79
                    '%s expects instance of %s, instance of %s given.',
×
80
                    static::class,
×
81
                    $containedGeometryType,
×
82
                    $geometry::class
×
83
                ));
×
84
            }
85
        }
86
    }
87

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

106
    /**
107
     * Returns the number of geometries in this GeometryCollection.
108
     */
109
    public function numGeometries() : int
110
    {
111
        return count($this->geometries);
4,025✔
112
    }
113

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

129
        return $this->geometries[$n - 1];
48✔
130
    }
131

132
    /**
133
     * Returns the geometries that compose this GeometryCollection.
134
     *
135
     * @return list<T>
136
     */
137
    public function geometries() : array
138
    {
139
        return $this->geometries;
96✔
140
    }
141

142
    #[NoProxy, Override]
143
    public function geometryType() : string
144
    {
145
        return 'GeometryCollection';
974✔
146
    }
147

148
    #[NoProxy, Override]
149
    public function geometryTypeBinary() : int
150
    {
151
        return Geometry::GEOMETRYCOLLECTION;
454✔
152
    }
153

154
    #[Override]
155
    public function dimension() : int
156
    {
157
        $dimension = 0;
64✔
158

159
        foreach ($this->geometries as $geometry) {
64✔
160
            $dim = $geometry->dimension();
32✔
161

162
            if ($dim > $dimension) {
32✔
163
                $dimension = $dim;
24✔
164
            }
165
        }
166

167
        return $dimension;
64✔
168
    }
169

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

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

179
        return $boundingBox;
×
180
    }
181

182
    #[Override]
183
    public function toArray() : array
184
    {
185
        return array_map(
400✔
186
            fn (Geometry $geometry) => $geometry->toArray(),
400✔
187
            $this->geometries,
400✔
188
        );
400✔
189
    }
190

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

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

212
    /**
213
     * Returns an iterator for the geometries in this GeometryCollection.
214
     *
215
     * @return ArrayIterator<int<0, max>, T>
216
     */
217
    #[Override]
218
    public function getIterator() : ArrayIterator
219
    {
220
        return new ArrayIterator($this->geometries);
5,044✔
221
    }
222

223
    /**
224
     * Returns the FQCN of the contained Geometry type.
225
     *
226
     * @return class-string<T>
227
     */
228
    protected function containedGeometryType() : string
229
    {
230
        return Geometry::class;
1,276✔
231
    }
232

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