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

brick / geo / 13718840732

07 Mar 2025 10:33AM UTC coverage: 48.463%. Remained the same
13718840732

push

github

BenMorel
TEMP

1703 of 3514 relevant lines covered (48.46%)

553.41 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);
1,238✔
46

47
        if (! $curves) {
1,238✔
48
            return;
494✔
49
        }
50

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

53
        $previousCurve = null;
752✔
54

55
        foreach ($curves as $curve) {
752✔
56
            if ($previousCurve) {
752✔
57
                $endPoint = $previousCurve->endPoint();
696✔
58
                $startPoint = $curve->startPoint();
696✔
59

60
                if ($endPoint != $startPoint) { // on purpose by-value comparison!
696✔
61
                    throw new InvalidGeometryException('Incontinuous compound curve.');
4✔
62
                }
63
            }
64

65
            $previousCurve = $curve;
752✔
66
        }
67

68
        $this->curves = array_values($curves);
748✔
69
    }
70

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

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

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

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

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

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

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

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

129
        return $this->curves[$n - 1];
60✔
130
    }
131

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

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

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

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

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

163
        return $boundingBox;
×
164
    }
165

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

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

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

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

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