• 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

93.1
/src/LineString.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 LineString is a Curve with linear interpolation between Points.
18
 *
19
 * Each consecutive pair of Points defines a line segment.
20
 *
21
 * @template-implements \IteratorAggregate<int<0, max>, Point>
22
 * @final
23
 */
24
readonly class LineString extends Curve implements \Countable, \IteratorAggregate
25
{
26
    /**
27
     * The Points that compose this LineString.
28
     *
29
     * An empty LineString contains no points.
30
     * A non-empty LineString contains a minimum of 2 points.
31
     *
32
     * @var list<Point>
33
     */
34
    protected array $points;
35

36
    /**
37
     * A LineString must be composed of 2 points or more, or 0 points for an empty LineString.
38
     * A LineString with exactly 1 point is not allowed.
39
     *
40
     * The coordinate system of each of the points must match the one of the LineString.
41
     *
42
     * @param CoordinateSystem $cs        The coordinate system of the LineString.
43
     * @param Point            ...$points The points that compose the LineString.
44
     *
45
     * @throws InvalidGeometryException  If only one point was given.
46
     * @throws CoordinateSystemException If different coordinate systems are used.
47
     */
48
    public function __construct(CoordinateSystem $cs, Point ...$points)
49
    {
50
        $isEmpty = (count($points) === 0);
14,687✔
51
        parent::__construct($cs, $isEmpty);
14,687✔
52

53
        $this->points = array_values($points);
14,687✔
54

55
        if ($isEmpty) {
14,687✔
56
            return;
1,052✔
57
        }
58

59
        CoordinateSystem::check($this, ...$points);
13,650✔
60

61
        if (count($points) < 2) {
13,650✔
62
            throw new InvalidGeometryException('A LineString must be composed of at least 2 points.');
8✔
63
        }
64
    }
65

66
    /**
67
     * Creates a non-empty LineString composed of the given points.
68
     *
69
     * @param Point    $point1 The first point.
70
     * @param Point ...$pointN The subsequent points.
71
     *
72
     * @throws InvalidGeometryException  If only one point was given.
73
     * @throws CoordinateSystemException If the points use different coordinate systems.
74
     */
75
    public static function of(Point $point1, Point ...$pointN) : LineString
76
    {
77
        return new LineString($point1->coordinateSystem(), $point1, ...$pointN);
×
78
    }
79

80
    /**
81
     * Creates a rectangle out of two 2D corner points.
82
     *
83
     * The result is a linear ring (closed and simple).
84
     *
85
     * @psalm-suppress PossiblyNullArgument
86
     *
87
     * @throws EmptyGeometryException    If any of the points is empty.
88
     * @throws CoordinateSystemException If the points use different coordinate systems, or are not 2D.
89
     */
90
    public static function rectangle(Point $a, Point $b) : LineString
91
    {
92
        $cs = $a->coordinateSystem();
56✔
93

94
        if (! $cs->isEqualTo($b->coordinateSystem())) {
56✔
95
            throw CoordinateSystemException::dimensionalityMix($cs, $b->coordinateSystem());
32✔
96
        }
97

98
        if ($cs->coordinateDimension() !== 2) {
24✔
99
            throw new CoordinateSystemException(__METHOD__ . ' expects 2D points.');
×
100
        }
101

102
        if ($a->isEmpty() || $b->isEmpty()) {
24✔
103
            throw new EmptyGeometryException('Points cannot be empty.');
×
104
        }
105

106
        $x1 = min($a->x(), $b->x());
24✔
107
        $x2 = max($a->x(), $b->x());
24✔
108

109
        $y1 = min($a->y(), $b->y());
24✔
110
        $y2 = max($a->y(), $b->y());
24✔
111

112
        $p1 = new Point($cs, $x1, $y1);
24✔
113
        $p2 = new Point($cs, $x2, $y1);
24✔
114
        $p3 = new Point($cs, $x2, $y2);
24✔
115
        $p4 = new Point($cs, $x1, $y2);
24✔
116

117
        return new LineString($cs, $p1, $p2, $p3, $p4, $p1);
24✔
118
    }
119

120
    #[Override]
121
    public function startPoint() : Point
122
    {
123
        if (count($this->points) === 0) {
648✔
124
            throw new EmptyGeometryException('The LineString is empty and has no start point.');
32✔
125
        }
126

127
        return $this->points[0];
616✔
128
    }
129

130
    #[Override]
131
    public function endPoint() : Point
132
    {
133
        $count = count($this->points);
1,064✔
134

135
        if ($count === 0) {
1,064✔
136
            throw new EmptyGeometryException('The LineString is empty and has no end point.');
32✔
137
        }
138

139
        return $this->points[$count - 1];
1,032✔
140
    }
141

142
    /**
143
     * Returns the number of Points in this LineString.
144
     */
145
    public function numPoints() : int
146
    {
147
        return count($this->points);
1,464✔
148
    }
149

150
    /**
151
     * Returns the specified Point N in this LineString.
152
     *
153
     * @param int $n The point number, 1-based.
154
     *
155
     * @throws NoSuchGeometryException If there is no Point at this index.
156
     */
157
    public function pointN(int $n) : Point
158
    {
159
        if (! isset($this->points[$n - 1])) {
176✔
160
            throw new NoSuchGeometryException('There is no Point in this LineString at index ' . $n);
64✔
161
        }
162

163
        return $this->points[$n - 1];
112✔
164
    }
165

166
    /**
167
     * Returns the points that compose this LineString.
168
     *
169
     * @return list<Point>
170
     */
171
    public function points() : array
172
    {
173
        return $this->points;
×
174
    }
175

176
    #[NoProxy, Override]
177
    public function geometryType() : string
178
    {
179
        return 'LineString';
1,938✔
180
    }
181

182
    #[NoProxy, Override]
183
    public function geometryTypeBinary() : int
184
    {
185
        return Geometry::LINESTRING;
2,295✔
186
    }
187

188
    #[Override]
189
    public function getBoundingBox() : BoundingBox
190
    {
191
        return array_reduce(
8✔
192
            $this->points,
8✔
193
            fn (BoundingBox $boundingBox, Point $point) => $boundingBox->extendedWithPoint($point),
8✔
194
            BoundingBox::new()
8✔
195
        );
8✔
196
    }
197

198
    /**
199
     * @return list<list<float>>
200
     */
201
    #[Override]
202
    public function toArray() : array
203
    {
204
        return array_map(
2,512✔
205
            fn (Point $point) => $point->toArray(),
2,512✔
206
            $this->points,
2,512✔
207
        );
2,512✔
208
    }
209

210
    #[Override]
211
    public function project(Projector $projector): LineString
212
    {
213
        return new LineString(
176✔
214
            $projector->getTargetCoordinateSystem($this->coordinateSystem),
176✔
215
            ...array_map(
176✔
216
                fn (Point $point) => $point->project($projector),
176✔
217
                $this->points,
176✔
218
            ),
176✔
219
        );
176✔
220
    }
221

222
    /**
223
     * Returns the number of points in this LineString.
224
     */
225
    #[Override]
226
    public function count() : int
227
    {
228
        return count($this->points);
4,144✔
229
    }
230

231
    /**
232
     * Returns an iterator for the points in this LineString.
233
     *
234
     * @return ArrayIterator<int<0, max>, Point>
235
     */
236
    #[Override]
237
    public function getIterator() : ArrayIterator
238
    {
239
        return new ArrayIterator($this->points);
9,929✔
240
    }
241

242
    /**
243
     * Returns a copy of this LineString, with the given points added.
244
     */
245
    public function withAddedPoints(Point ...$points): LineString
246
    {
247
        return new LineString($this->coordinateSystem, ...$this->points, ...$points);
40✔
248
    }
249
}
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