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

brick / geo / 13716844819

07 Mar 2025 08:35AM UTC coverage: 47.964% (+3.9%) from 44.086%
13716844819

push

github

BenMorel
Add TypeChecker for engines

8 of 21 new or added lines in 5 files covered. (38.1%)

98 existing lines in 18 files now uncovered.

1684 of 3511 relevant lines covered (47.96%)

944.32 hits per line

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

68.42
/src/CurvePolygon.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\EmptyGeometryException;
11
use Brick\Geo\Exception\NoSuchGeometryException;
12
use Brick\Geo\Projector\Projector;
13
use Override;
14

15
/**
16
 * A CurvePolygon is a planar Surface defined by 1 exterior boundary and 0 or more interior boundaries.
17
 *
18
 * A CurvePolygon instance differs from a Polygon instance in that a CurvePolygon instance may contain
19
 * the following circular arc segments: CircularString and CompoundCurve in addition to LineString.
20
 *
21
 * @template-implements \IteratorAggregate<Curve>
22
 * @final
23
 */
24
class CurvePolygon extends Surface implements \Countable, \IteratorAggregate
25
{
26
    /**
27
     * The rings that compose this CurvePolygon.
28
     *
29
     * The first one represents the exterior ring, and the
30
     * (optional) other ones represent the interior rings (holes) of the CurvePolygon.
31
     *
32
     * An empty CurvePolygon contains no rings.
33
     *
34
     * @var list<Curve>
35
     */
36
    protected array $rings = [];
37

38
    /**
39
     * The coordinate system of each of the rings must match the one of the CurvePolygon.
40
     *
41
     * @param CoordinateSystem $cs       The coordinate system of the CurvePolygon.
42
     * @param Curve            ...$rings The rings that compose the CurvePolygon.
43
     *
44
     * @throws CoordinateSystemException If different coordinate systems are used.
45
     */
46
    public function __construct(CoordinateSystem $cs, Curve ...$rings)
47
    {
48
        parent::__construct($cs, ! $rings);
1,729✔
49

50
        if (! $rings) {
1,729✔
51
            return;
798✔
52
        }
53

54
        CoordinateSystem::check($this, ...$rings);
945✔
55

56
        $this->rings = array_values($rings);
945✔
57
    }
58

59
    /**
60
     * Creates a non-empty CurvePolygon composed of the given rings.
61
     *
62
     * @param Curve    $exteriorRing  The exterior ring.
63
     * @param Curve ...$interiorRings The interior rings, if any.
64
     *
65
     * @throws CoordinateSystemException If the rings use different coordinate systems.
66
     */
67
    public static function of(Curve $exteriorRing, Curve ...$interiorRings) : CurvePolygon
68
    {
UNCOV
69
        return new static($exteriorRing->coordinateSystem(), $exteriorRing, ...$interiorRings);
×
70
    }
71

72
    /**
73
     * Returns the exterior ring of this CurvePolygon.
74
     *
75
     * @throws EmptyGeometryException
76
     */
77
    public function exteriorRing() : Curve
78
    {
79
        if ($this->isEmpty) {
140✔
80
            throw new EmptyGeometryException('An empty CurvePolygon has no exterior ring.');
28✔
81
        }
82

83
        return $this->rings[0];
112✔
84
    }
85

86
    /**
87
     * Returns the number of interior rings in this CurvePolygon.
88
     */
89
    public function numInteriorRings() : int
90
    {
91
        if ($this->isEmpty) {
63✔
92
            return 0;
28✔
93
        }
94

95
        return count($this->rings) - 1;
35✔
96
    }
97

98
    /**
99
     * Returns the specified interior ring N in this CurvePolygon.
100
     *
101
     * @param int $n The ring number, 1-based.
102
     *
103
     * @throws NoSuchGeometryException If there is no interior ring at this index.
104
     */
105
    public function interiorRingN(int $n) : Curve
106
    {
107
        if ($n === 0 || ! isset($this->rings[$n])) {
308✔
108
            throw new NoSuchGeometryException('There is no interior ring in this CurvePolygon at index ' . $n);
252✔
109
        }
110

111
        return $this->rings[$n];
56✔
112
    }
113

114
    /**
115
     * Returns the interior rings in this CurvePolygon.
116
     *
117
     * @return list<Curve>
118
     */
119
    public function interiorRings() : array
120
    {
121
        return array_slice($this->rings, 1);
70✔
122
    }
123

124
    #[NoProxy, Override]
125
    public function geometryType() : string
126
    {
127
        return 'CurvePolygon';
672✔
128
    }
129

130
    #[NoProxy, Override]
131
    public function geometryTypeBinary() : int
132
    {
133
        return Geometry::CURVEPOLYGON;
350✔
134
    }
135

136
    #[Override]
137
    public function getBoundingBox() : BoundingBox
138
    {
UNCOV
139
        $boundingBox = BoundingBox::new();
×
140

UNCOV
141
        foreach ($this->rings as $ring) {
×
142
            $boundingBox = $boundingBox->extendedWithBoundingBox($ring->getBoundingBox());
×
143
        }
144

UNCOV
145
        return $boundingBox;
×
146
    }
147

148
    #[Override]
149
    public function toArray() : array
150
    {
151
        return array_map(
224✔
152
            fn (Curve $ring) => $ring->toArray(),
224✔
153
            $this->rings,
224✔
154
        );
224✔
155
    }
156

157
    #[Override]
158
    public function project(Projector $projector): CurvePolygon
159
    {
UNCOV
160
        return new CurvePolygon(
×
161
            $projector->getTargetCoordinateSystem($this->coordinateSystem),
×
162
            ...array_map(
×
163
                fn (Curve $ring) => $ring->project($projector),
×
164
                $this->rings,
×
165
            ),
×
166
        );
×
167
    }
168

169
    /**
170
     * Returns the number of rings (exterior + interior) in this CurvePolygon.
171
     */
172
    #[Override]
173
    public function count() : int
174
    {
175
        return count($this->rings);
350✔
176
    }
177

178
    /**
179
     * Returns an iterator for the rings (exterior + interior) in this CurvePolygon.
180
     *
181
     * @return ArrayIterator<int<0, max>, Curve>
182
     */
183
    #[Override]
184
    public function getIterator() : ArrayIterator
185
    {
186
        return new ArrayIterator($this->rings);
742✔
187
    }
188

189
    /**
190
     * Returns a copy of this CurvePolygon, with the exterior ring replaced with the given one.
191
     */
192
    public function withExteriorRing(Curve $exteriorRing) : CurvePolygon
193
    {
194
        return new CurvePolygon($this->coordinateSystem, $exteriorRing, ...$this->interiorRings());
28✔
195
    }
196

197
    /**
198
     * Returns a copy of this CurvePolygon, with the interior rings replaced with the given ones.
199
     */
200
    public function withInteriorRings(Curve ...$interiorRings) : CurvePolygon
201
    {
202
        return new CurvePolygon($this->coordinateSystem, $this->exteriorRing(), ...$interiorRings);
42✔
203
    }
204

205
    /**
206
     * Returns a copy of this CurvePolygon, with the given interior rings added.
207
     */
208
    public function withAddedInteriorRings(Curve ...$interiorRings) : CurvePolygon
209
    {
210
        return new CurvePolygon($this->coordinateSystem, $this->exteriorRing(), ...$this->interiorRings(), ...$interiorRings);
42✔
211
    }
212
}
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