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

brick / geo / 13687942239

05 Mar 2025 11:54PM UTC coverage: 84.507% (+0.07%) from 84.44%
13687942239

push

github

BenMorel
Remove Psalm-specific annotations

1560 of 1846 relevant lines covered (84.51%)

1977.43 hits per line

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

69.05
/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 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
    protected 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
        parent::__construct($cs, ! $points);
3,640✔
41

42
        if (! $points) {
3,640✔
43
            return;
804✔
44
        }
45

46
        CoordinateSystem::check($this, ...$points);
2,850✔
47

48
        $numPoints = count($points);
2,850✔
49

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

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

58
        $this->points = array_values($points);
2,815✔
59
    }
60

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

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

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

85
    #[Override]
86
    public function endPoint() : Point
87
    {
88
        if ($this->points === []) {
630✔
89
            throw new EmptyGeometryException('The CircularString is empty and has no end point.');
56✔
90
        }
91

92
        return end($this->points);
574✔
93
    }
94

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

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

116
        return $this->points[$n - 1];
91✔
117
    }
118

119
    /**
120
     * Returns the points that compose this CircularString.
121
     *
122
     * @return list<Point>
123
     */
124
    public function points() : array
125
    {
126
        return $this->points;
×
127
    }
128

129
    #[Override]
130
    public function geometryType() : string
131
    {
132
        return 'CircularString';
1,672✔
133
    }
134

135
    #[Override]
136
    public function geometryTypeBinary() : int
137
    {
138
        return Geometry::CIRCULARSTRING;
743✔
139
    }
140

141
    #[Override]
142
    public function getBoundingBox() : BoundingBox
143
    {
144
        $boundingBox = BoundingBox::new();
×
145

146
        foreach ($this->points as $point) {
×
147
            $boundingBox = $boundingBox->extendedWithPoint($point);
×
148
        }
149

150
        return $boundingBox;
×
151
    }
152

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

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

177
    /**
178
     * Returns the number of points in this CircularString.
179
     */
180
    #[Override]
181
    public function count() : int
182
    {
183
        return count($this->points);
750✔
184
    }
185

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

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