• 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

70.45
/src/CircularString.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 CircularString is a Curve made of zero or more connected circular arc segments.
17
 *
18
 * A circular arc segment is a curved segment defined by three points in a two-dimensional plane;
19
 * the first point cannot be the same as the third point.
20
 *
21
 * @template-implements \IteratorAggregate<Point>
22
 */
23
final readonly class CircularString extends Curve implements \Countable, \IteratorAggregate
24
{
25
    /**
26
     * The Points that compose this CircularString.
27
     *
28
     * An empty CircularString contains no points.
29
     *
30
     * @var list<Point>
31
     */
32
    public array $points;
33

34
    /**
35
     * @throws InvalidGeometryException  If the number of points is invalid.
36
     * @throws CoordinateSystemException If different coordinate systems are used.
37
     */
38
    public function __construct(CoordinateSystem $cs, Point ...$points)
39
    {
40
        $numPoints = count($points);
3,640✔
41
        $isEmpty = ($numPoints === 0);
3,640✔
42

43
        parent::__construct($cs, $isEmpty);
3,640✔
44

45
        $this->points = array_values($points);
3,640✔
46

47
        if ($isEmpty) {
3,640✔
48
            return;
804✔
49
        }
50

51
        CoordinateSystem::check($this, ...$points);
2,850✔
52

53
        if ($numPoints < 3) {
2,850✔
54
            throw new InvalidGeometryException('A CircularString must be made of at least 3 points.');
21✔
55
        }
56

57
        if ($numPoints % 2 === 0) {
2,829✔
58
            throw new InvalidGeometryException('A CircularString must have an odd number of points.');
14✔
59
        }
60
    }
61

62
    /**
63
     * Creates a non-empty CircularString composed of the given points.
64
     *
65
     * @param Point    $point1 The first point.
66
     * @param Point ...$pointN The subsequent points.
67
     *
68
     * @throws InvalidGeometryException  If the number of points is invalid.
69
     * @throws CoordinateSystemException If the points use different coordinate systems.
70
     */
71
    public static function of(Point $point1, Point ...$pointN) : CircularString
72
    {
NEW
73
        return new CircularString($point1->coordinateSystem, $point1, ...$pointN);
×
74
    }
75

76
    #[Override]
77
    public function startPoint() : Point
78
    {
79
        if ($this->points === []) {
980✔
80
            throw new EmptyGeometryException('The CircularString is empty and has no start point.');
56✔
81
        }
82

83
        return $this->points[0];
924✔
84
    }
85

86
    #[Override]
87
    public function endPoint() : Point
88
    {
89
        $count = count($this->points);
630✔
90

91
        if ($count === 0) {
630✔
92
            throw new EmptyGeometryException('The CircularString is empty and has no end point.');
56✔
93
        }
94

95
        return $this->points[$count - 1];
574✔
96
    }
97

98
    /**
99
     * Returns the number of Points in this CircularString.
100
     */
101
    public function numPoints() : int
102
    {
103
        return count($this->points);
56✔
104
    }
105

106
    /**
107
     * Returns the specified Point N in this CircularString.
108
     *
109
     * @param int $n The point number, 1-based.
110
     *
111
     * @throws NoSuchGeometryException If there is no Point at this index.
112
     */
113
    public function pointN(int $n) : Point
114
    {
115
        if (! isset($this->points[$n - 1])) {
133✔
116
            throw new NoSuchGeometryException('There is no Point in this CircularString at index ' . $n);
42✔
117
        }
118

119
        return $this->points[$n - 1];
91✔
120
    }
121

122
    /**
123
     * Returns the points that compose this CircularString.
124
     *
125
     * @return list<Point>
126
     *
127
     * @deprecated Use $points property instead.
128
     */
129
    public function points() : array
130
    {
131
        return $this->points;
×
132
    }
133

134
    #[Override]
135
    public function geometryType() : string
136
    {
137
        return 'CircularString';
1,672✔
138
    }
139

140
    #[Override]
141
    public function geometryTypeBinary() : int
142
    {
143
        return Geometry::CIRCULARSTRING;
743✔
144
    }
145

146
    #[Override]
147
    public function getBoundingBox() : BoundingBox
148
    {
149
        $boundingBox = BoundingBox::new();
×
150

151
        foreach ($this->points as $point) {
×
152
            $boundingBox = $boundingBox->extendedWithPoint($point);
×
153
        }
154

155
        return $boundingBox;
×
156
    }
157

158
    /**
159
     * @return list<list<float>>
160
     */
161
    #[Override]
162
    public function toArray() : array
163
    {
164
        return array_map(
448✔
165
            fn (Point $point) => $point->toArray(),
448✔
166
            $this->points,
448✔
167
        );
448✔
168
    }
169

170
    #[Override]
171
    public function project(Projector $projector): static
172
    {
173
        return new CircularString(
×
174
            $projector->getTargetCoordinateSystem($this->coordinateSystem),
×
175
            ...array_map(
×
176
                fn (Point $point) => $point->project($projector),
×
177
                $this->points,
×
178
            ),
×
179
        );
×
180
    }
181

182
    /**
183
     * Returns the number of points in this CircularString.
184
     */
185
    #[Override]
186
    public function count() : int
187
    {
188
        return count($this->points);
750✔
189
    }
190

191
    /**
192
     * Returns an iterator for the points in this CircularString.
193
     *
194
     * @return ArrayIterator<int<0, max>, Point>
195
     */
196
    #[Override]
197
    public function getIterator() : ArrayIterator
198
    {
199
        return new ArrayIterator($this->points);
2,052✔
200
    }
201

202
    /**
203
     * Returns a copy of this CircularString, with the given points added.
204
     */
205
    public function withAddedPoints(Point ...$points): CircularString
206
    {
207
        return new CircularString($this->coordinateSystem, ...$this->points, ...$points);
42✔
208
    }
209
}
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