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

brick / geo / 13715719367

06 Mar 2025 02:18PM UTC coverage: 84.117%. First build
13715719367

push

github

BenMorel
Public properties

71 of 77 new or added lines in 23 files covered. (92.21%)

1557 of 1851 relevant lines covered (84.12%)

1887.21 hits per line

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

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

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

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

46
        $this->curves = array_values($curves);
2,302✔
47

48
        if ($isEmpty) {
2,302✔
49
            return;
916✔
50
        }
51

52
        CoordinateSystem::check($this, ...$curves);
1,400✔
53

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

57
        foreach ($curves as $curve) {
1,400✔
58
            if ($previousCurve) {
1,400✔
59
                $endPoint = $previousCurve->endPoint();
1,302✔
60
                $startPoint = $curve->startPoint();
1,302✔
61

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

67
            $previousCurve = $curve;
1,400✔
68
        }
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
    {
NEW
83
        return new CompoundCurve($curve1->coordinateSystem, $curve1, ...$curveN);
×
84
    }
85

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

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

96
    #[Override]
97
    public function endPoint() : Point
98
    {
99
        if ($this->curves === []) {
112✔
100
            throw new EmptyGeometryException('The CompoundCurve is empty and has no end point.');
56✔
101
        }
102

103
        $count = count($this->curves);
56✔
104

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

108
    /**
109
     * Returns the number of Curves in this CompoundCurve.
110
     */
111
    public function numCurves() : int
112
    {
113
        return count($this->curves);
56✔
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])) {
329✔
126
            throw new NoSuchGeometryException('There is no Curve in this CompoundCurve at index ' . $n);
224✔
127
        }
128

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

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

144
    #[Override]
145
    public function geometryType() : string
146
    {
147
        return 'CompoundCurve';
951✔
148
    }
149

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

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

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

165
        return $boundingBox;
×
166
    }
167

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

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

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

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

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