• 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

70.83
/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
readonly 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
        $isEmpty = (count($curves) === 0);
2,568✔
46
        parent::__construct($cs, $isEmpty);
2,568✔
47

48
        $this->curves = array_values($curves);
2,568✔
49

50
        if ($isEmpty) {
2,568✔
51
            return;
984✔
52
        }
53

54
        CoordinateSystem::check($this, ...$curves);
1,600✔
55

56
        $previousCurve = null;
1,600✔
57

58
        foreach ($curves as $curve) {
1,600✔
59
            if ($previousCurve) {
1,600✔
60
                $endPoint = $previousCurve->endPoint();
1,488✔
61
                $startPoint = $curve->startPoint();
1,488✔
62

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

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

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

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

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

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

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

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

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

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

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

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

155
    #[Override]
156
    public function getBoundingBox() : BoundingBox
157
    {
158
        return array_reduce(
×
159
            $this->curves,
×
160
            fn (BoundingBox $boundingBox, Curve $curve) => $boundingBox->extendedWithBoundingBox($curve->getBoundingBox()),
×
161
            BoundingBox::new(),
×
162
        );
×
163
    }
164

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

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

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

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

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