• 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

71.74
/src/CompoundCurve.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\InvalidGeometryException;
12
use Brick\Geo\Exception\NoSuchGeometryException;
13
use Brick\Geo\Projector\Projector;
14
use Override;
15

16
/**
17
 * A CompoundCurve is a collection of zero or more continuous CircularString or LineString instances.
18
 *
19
 * @template-implements \IteratorAggregate<int<0, max>, LineString|CircularString>
20
 * @final
21
 */
22
class CompoundCurve extends Curve implements \Countable, \IteratorAggregate
23
{
24
    /**
25
     * The Curves that compose this CompoundCurve.
26
     *
27
     * This array can be empty.
28
     *
29
     * @var list<LineString|CircularString>
30
     */
31
    protected array $curves = [];
32

33
    /**
34
     * The coordinate system of each of the curves must match the one of the CompoundCurve.
35
     *
36
     * @param CoordinateSystem             $cs     The coordinate system of the CompoundCurve.
37
     * @param LineString|CircularString ...$curves The curves that compose the CompoundCurve.
38
     *
39
     * @throws EmptyGeometryException    If any of the input curves is empty.
40
     * @throws InvalidGeometryException  If the compound curve is not continuous.
41
     * @throws CoordinateSystemException If different coordinate systems are used.
42
     */
43
    public function __construct(CoordinateSystem $cs, LineString|CircularString ...$curves)
44
    {
45
        parent::__construct($cs, ! $curves);
2,162✔
46

47
        if (! $curves) {
2,162✔
48
            return;
860✔
49
        }
50

51
        CoordinateSystem::check($this, ...$curves);
1,316✔
52

53
        /** @var Curve|null $previousCurve */
54
        $previousCurve = null;
1,316✔
55

56
        foreach ($curves as $curve) {
1,316✔
57
            if ($previousCurve) {
1,316✔
58
                $endPoint = $previousCurve->endPoint();
1,218✔
59
                $startPoint = $curve->startPoint();
1,218✔
60

61
                if ($endPoint != $startPoint) { // on purpose by-value comparison!
1,218✔
62
                    throw new InvalidGeometryException('Incontinuous compound curve.');
7✔
63
                }
64
            }
65

66
            $previousCurve = $curve;
1,316✔
67
        }
68

69
        $this->curves = array_values($curves);
1,309✔
70
    }
71

72
    /**
73
     * Creates a non-empty CompoundCurve composed of the given curves.
74
     *
75
     * @param LineString|CircularString    $curve1 The first curve.
76
     * @param LineString|CircularString ...$curveN The subsequent curves, if any.
77
     *
78
     * @throws EmptyGeometryException    If any of the input curves is empty.
79
     * @throws InvalidGeometryException  If the compound curve is not continuous.
80
     * @throws CoordinateSystemException If the curves use different coordinate systems.
81
     */
82
    public static function of(LineString|CircularString $curve1, LineString|CircularString ...$curveN) : CompoundCurve
83
    {
UNCOV
84
        return new CompoundCurve($curve1->coordinateSystem(), $curve1, ...$curveN);
×
85
    }
86

87
    #[Override]
88
    public function startPoint() : Point
89
    {
90
        if (count($this->curves) === 0) {
112✔
91
            throw new EmptyGeometryException('The CompoundCurve is empty and has no start point.');
56✔
92
        }
93

94
        return $this->curves[0]->startPoint();
56✔
95
    }
96

97
    #[Override]
98
    public function endPoint() : Point
99
    {
100
        $count = count($this->curves);
112✔
101

102
        if ($count === 0) {
112✔
103
            throw new EmptyGeometryException('The CompoundCurve is empty and has no end point.');
56✔
104
        }
105

106
        return $this->curves[$count - 1]->endPoint();
56✔
107
    }
108

109
    /**
110
     * Returns the number of Curves in this CompoundCurve.
111
     */
112
    public function numCurves() : int
113
    {
114
        return count($this->curves);
56✔
115
    }
116

117
    /**
118
     * Returns the specified Curve N in this CompoundCurve.
119
     *
120
     * @param int $n The curve number, 1-based.
121
     *
122
     * @throws NoSuchGeometryException If there is no Curve at this index.
123
     */
124
    public function curveN(int $n) : LineString|CircularString
125
    {
126
        if (! isset($this->curves[$n - 1])) {
329✔
127
            throw new NoSuchGeometryException('There is no Curve in this CompoundCurve at index ' . $n);
224✔
128
        }
129

130
        return $this->curves[$n - 1];
105✔
131
    }
132

133
    /**
134
     * Returns the curves that compose this CompoundCurve.
135
     *
136
     * @return list<LineString|CircularString>
137
     */
138
    public function curves() : array
139
    {
UNCOV
140
        return $this->curves;
×
141
    }
142

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

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

155
    #[Override]
156
    public function getBoundingBox() : BoundingBox
157
    {
UNCOV
158
        $boundingBox = BoundingBox::new();
×
159

160
        foreach ($this->curves as $curve) {
×
UNCOV
161
            $boundingBox = $boundingBox->extendedWithBoundingBox($curve->getBoundingBox());
×
162
        }
163

UNCOV
164
        return $boundingBox;
×
165
    }
166

167
    /**
168
     * @return list<list<list<float>>>
169
     */
170
    #[Override]
171
    public function toArray() : array
172
    {
173
        return array_map(
252✔
174
            fn (Curve $curve) => $curve->toArray(),
252✔
175
            $this->curves,
252✔
176
        );
252✔
177
    }
178

179
    #[Override]
180
    public function project(Projector $projector): CompoundCurve
181
    {
182
        return new CompoundCurve(
×
183
            $projector->getTargetCoordinateSystem($this->coordinateSystem),
×
184
            ...array_map(
×
185
                fn (Curve $curve) => $curve->project($projector),
×
186
                $this->curves,
×
187
            ),
×
UNCOV
188
        );
×
189
    }
190

191
    /**
192
     * Returns the number of curves in this CompoundCurve.
193
     */
194
    #[Override]
195
    public function count() : int
196
    {
197
        return count($this->curves);
455✔
198
    }
199

200
    /**
201
     * Returns an iterator for the curves in this CompoundCurve.
202
     *
203
     * @return ArrayIterator<int<0, max>, LineString|CircularString>
204
     */
205
    #[Override]
206
    public function getIterator() : ArrayIterator
207
    {
208
        return new ArrayIterator($this->curves);
952✔
209
    }
210

211
    /**
212
     * Returns a copy of this CompoundCurve, with the given curves added.
213
     */
214
    public function withAddedCurves(LineString|CircularString ...$curves): CompoundCurve
215
    {
216
        return new CompoundCurve($this->coordinateSystem, ...$this->curves, ...$curves);
56✔
217
    }
218
}
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