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

brick / geo / 13753277563

09 Mar 2025 10:43PM UTC coverage: 49.787% (+2.5%) from 47.295%
13753277563

push

github

BenMorel
Prepare for release

1749 of 3513 relevant lines covered (49.79%)

975.53 hits per line

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

98.33
/src/Point.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\InvalidGeometryException;
10
use Brick\Geo\Projector\Projector;
11
use Override;
12

13
/**
14
 * A Point is a 0-dimensional geometric object and represents a single location in coordinate space.
15
 *
16
 * A Point has an x-coordinate value, a y-coordinate value.
17
 * If called for by the associated Spatial Reference System, it may also have coordinate values for z and m.
18
 *
19
 * The boundary of a Point is the empty set.
20
 *
21
 * @final
22
 */
23
class Point extends Geometry
24
{
25
    /**
26
     * The x-coordinate value for this Point, or NULL if the point is empty.
27
     */
28
    private ?float $x = null;
29

30
    /**
31
     * The y-coordinate value for this Point, or NULL if the point is empty.
32
     */
33
    private ?float $y = null;
34

35
    /**
36
     * The z-coordinate value for this Point, or NULL if it does not have one.
37
     */
38
    private ?float $z = null;
39

40
    /**
41
     * The m-coordinate value for this Point, or NULL if it does not have one.
42
     */
43
    private ?float $m = null;
44

45
    /**
46
     * @param CoordinateSystem $cs        The coordinate system.
47
     * @param float            ...$coords The point coordinates; can be empty for an empty point.
48
     *
49
     * @throws InvalidGeometryException If the number of coordinates does not match the coordinate system.
50
     *
51
     * @psalm-suppress PossiblyUndefinedArrayOffset
52
     */
53
    public function __construct(CoordinateSystem $cs, float ...$coords)
54
    {
55
        $isEmpty = count($coords) === 0;
15,922✔
56

57
        parent::__construct($cs, $isEmpty);
15,922✔
58

59
        if ($isEmpty) {
15,922✔
60
            return;
580✔
61
        }
62

63
        if (count($coords) !== $cs->coordinateDimension()) {
15,362✔
64
            throw new InvalidGeometryException(sprintf(
84✔
65
                'Expected %d coordinates for Point %s, got %d.',
84✔
66
                $cs->coordinateDimension(),
84✔
67
                $cs->coordinateName(),
84✔
68
                count($coords)
84✔
69
            ));
84✔
70
        }
71

72
        $coords = array_values($coords);
15,278✔
73

74
        foreach ($coords as $i => $coord) {
15,278✔
75
            if (! is_finite($coord)) {
15,278✔
76
                $coordinateName = match ($i) {
126✔
77
                    0 => 'X',
21✔
78
                    1 => 'Y',
21✔
79
                    2 => $cs->hasZ() ? 'Z' : 'M',
63✔
80
                    3 => 'M',
21✔
81
                };
126✔
82
                throw new InvalidGeometryException(sprintf(
126✔
83
                    'Coordinate #%d (%s) for Point %s is %s, this is not allowed.',
126✔
84
                    $i + 1,
126✔
85
                    $coordinateName,
126✔
86
                    $cs->coordinateName(),
126✔
87
                    is_infinite($coord) ? ($coord > 0 ? '+' : '-') . 'INF' : 'NaN',
126✔
88
                ));
126✔
89
            }
90
        }
91

92
        $this->x = $coords[0];
15,152✔
93
        $this->y = $coords[1];
15,152✔
94

95
        $hasZ = $cs->hasZ();
15,152✔
96
        $hasM = $cs->hasM();
15,152✔
97

98
        if ($hasZ) {
15,152✔
99
            $this->z = $coords[2];
6,406✔
100
        }
101

102
        if ($hasM) {
15,152✔
103
            $this->m = $coords[$hasZ ? 3 : 2];
5,770✔
104
        }
105
    }
106

107
    /**
108
     * Creates a point with X and Y coordinates.
109
     */
110
    public static function xy(float $x, float $y, int $srid = 0) : Point
111
    {
112
        return new Point(CoordinateSystem::xy($srid), $x, $y);
77✔
113
    }
114

115
    /**
116
     * Creates a point with X, Y and Z coordinates.
117
     */
118
    public static function xyz(float $x, float $y, float $z, int $srid = 0) : Point
119
    {
120
        return new Point(CoordinateSystem::xyz($srid), $x, $y, $z);
35✔
121
    }
122

123
    /**
124
     * Creates a point with X, Y and M coordinates.
125
     */
126
    public static function xym(float $x, float $y, float $m, int $srid = 0) : Point
127
    {
128
        return new Point(CoordinateSystem::xym($srid), $x, $y, $m);
21✔
129
    }
130

131
    /**
132
     * Creates a point with X, Y, Z and M coordinates.
133
     */
134
    public static function xyzm(float $x, float $y, float $z, float $m, int $srid = 0) : Point
135
    {
136
        return new Point(CoordinateSystem::xyzm($srid), $x, $y, $z, $m);
14✔
137
    }
138

139
    /**
140
     * Creates an empty Point with XY dimensionality.
141
     */
142
    public static function xyEmpty(int $srid = 0) : Point
143
    {
144
        return new Point(CoordinateSystem::xy($srid));
14✔
145
    }
146

147
    /**
148
     * Creates an empty Point with XYZ dimensionality.
149
     */
150
    public static function xyzEmpty(int $srid = 0) : Point
151
    {
152
        return new Point(CoordinateSystem::xyz($srid));
14✔
153
    }
154

155
    /**
156
     * Creates an empty Point with XYM dimensionality.
157
     */
158
    public static function xymEmpty(int $srid = 0) : Point
159
    {
160
        return new Point(CoordinateSystem::xym($srid));
14✔
161
    }
162

163
    /**
164
     * Creates an empty Point with XYZM dimensionality.
165
     */
166
    public static function xyzmEmpty(int $srid = 0) : Point
167
    {
168
        return new Point(CoordinateSystem::xyzm($srid));
14✔
169
    }
170

171
    /**
172
     * Returns the x-coordinate value for this Point.
173
     *
174
     * Returns NULL if the Point is empty.
175
     */
176
    public function x() : ?float
177
    {
178
        return $this->x;
11,057✔
179
    }
180

181
    /**
182
     * Returns the y-coordinate value for this Point.
183
     *
184
     * Returns NULL if the Point is empty.
185
     */
186
    public function y() : ?float
187
    {
188
        return $this->y;
11,057✔
189
    }
190

191
    /**
192
     * Returns the z-coordinate value for this Point.
193
     *
194
     * Returns NULL if the Point is empty, or does not have a Z coordinate.
195
     */
196
    public function z() : ?float
197
    {
198
        return $this->z;
11,050✔
199
    }
200

201
    /**
202
     * Returns the m-coordinate value for this Point.
203
     *
204
     * Returns NULL if the Point is empty, or does not have a M coordinate.
205
     */
206
    public function m() : ?float
207
    {
208
        return $this->m;
11,015✔
209
    }
210

211
    #[NoProxy, Override]
212
    public function geometryType() : string
213
    {
214
        return 'Point';
1,553✔
215
    }
216

217
    #[NoProxy, Override]
218
    public function geometryTypeBinary() : int
219
    {
220
        return Geometry::POINT;
1,049✔
221
    }
222

223
    #[NoProxy, Override]
224
    public function dimension() : int
225
    {
226
        return 0;
105✔
227
    }
228

229
    #[Override]
230
    public function getBoundingBox() : BoundingBox
231
    {
232
        return BoundingBox::new()->extendedWithPoint($this);
×
233
    }
234

235
    /**
236
     * @return list<float>
237
     */
238
    #[Override]
239
    public function toArray() : array
240
    {
241
        if ($this->isEmpty) {
3,178✔
242
            return [];
217✔
243
        }
244

245
        /** @var list<float> $result */
246
        $result = [$this->x, $this->y];
2,961✔
247

248
        if ($this->z !== null) {
2,961✔
249
            $result[] = $this->z;
1,407✔
250
        }
251

252
        if ($this->m !== null) {
2,961✔
253
            $result[] = $this->m;
1,036✔
254
        }
255

256
        return $result;
2,961✔
257
    }
258

259
    #[Override]
260
    public function project(Projector $projector) : Point
261
    {
262
        return $projector->project($this);
217✔
263
    }
264
}
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