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

brick / geo / 13766674441

10 Mar 2025 02:07PM UTC coverage: 87.322% (-0.09%) from 87.414%
13766674441

push

github

BenMorel
Support for boolean parameters in DatabaseEngine

1 of 2 new or added lines in 1 file covered. (50.0%)

1 existing line in 1 file now uncovered.

1653 of 1893 relevant lines covered (87.32%)

1944.87 hits per line

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

80.43
/src/Geometry.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Brick\Geo;
6

7
use Brick\Geo\Exception\CoordinateSystemException;
8
use Brick\Geo\Exception\GeometryIOException;
9
use Brick\Geo\Exception\InvalidGeometryException;
10
use Brick\Geo\Exception\UnexpectedGeometryException;
11
use Brick\Geo\IO\WKTReader;
12
use Brick\Geo\IO\WKTWriter;
13
use Brick\Geo\IO\WKBReader;
14
use Brick\Geo\IO\WKBWriter;
15
use Brick\Geo\Projector\Projector;
16
use Brick\Geo\Projector\RemoveZMProjector;
17
use Brick\Geo\Projector\SRIDProjector;
18
use Brick\Geo\Projector\SwapXYProjector;
19
use Override;
20

21
/**
22
 * Geometry is the root class of the hierarchy.
23
 */
24
abstract readonly class Geometry implements \Stringable
25
{
26
    final public const int GEOMETRY           = 0;
27
    final public const int POINT              = 1;
28
    final public const int LINESTRING         = 2;
29
    final public const int POLYGON            = 3;
30
    final public const int MULTIPOINT         = 4;
31
    final public const int MULTILINESTRING    = 5;
32
    final public const int MULTIPOLYGON       = 6;
33
    final public const int GEOMETRYCOLLECTION = 7;
34
    final public const int CIRCULARSTRING     = 8;
35
    final public const int COMPOUNDCURVE      = 9;
36
    final public const int CURVEPOLYGON       = 10;
37
    final public const int MULTICURVE         = 11;
38
    final public const int MULTISURFACE       = 12;
39
    final public const int CURVE              = 13;
40
    final public const int SURFACE            = 14;
41
    final public const int POLYHEDRALSURFACE  = 15;
42
    final public const int TIN                = 16;
43
    final public const int TRIANGLE           = 17;
44

45
    /**
46
     * The coordinate system of this geometry.
47
     */
48
    public CoordinateSystem $coordinateSystem;
49

50
    /**
51
     * Whether this geometry is empty.
52
     */
53
    protected bool $isEmpty;
54

55
    /**
56
     * @param CoordinateSystem $coordinateSystem The coordinate system of this geometry.
57
     * @param bool             $isEmpty          Whether this geometry is empty.
58
     */
59
    protected function __construct(CoordinateSystem $coordinateSystem, bool $isEmpty)
60
    {
61
        $this->coordinateSystem = $coordinateSystem;
26,778✔
62
        $this->isEmpty          = $isEmpty;
26,778✔
63
    }
64

65
    /**
66
     * Builds a Geometry from a WKT representation.
67
     *
68
     * If the resulting geometry is valid but is not an instance of the class this method is called on,
69
     * for example passing a Polygon WKT to Point::fromText(), an exception is thrown.
70
     *
71
     * @param string $wkt  The Well-Known Text representation.
72
     * @param int    $srid The optional SRID to use.
73
     *
74
     * @throws GeometryIOException         If the given string is not a valid WKT representation.
75
     * @throws CoordinateSystemException   If the WKT contains mixed coordinate systems.
76
     * @throws InvalidGeometryException    If the WKT represents an invalid geometry.
77
     * @throws UnexpectedGeometryException If the resulting geometry is not an instance of the current class.
78
     */
79
    public static function fromText(string $wkt, int $srid = 0) : static
80
    {
81
        /** @var WKTReader|null $wktReader */
82
        static $wktReader;
7,598✔
83

84
        if ($wktReader === null) {
7,598✔
85
            $wktReader = new WKTReader();
7✔
86
        }
87

88
        $geometry = $wktReader->read($wkt, $srid);
7,598✔
89

90
        if ($geometry instanceof static) {
7,549✔
91
            return $geometry;
7,486✔
92
        }
93

94
        throw UnexpectedGeometryException::unexpectedGeometryType(static::class, $geometry);
63✔
95
    }
96

97
    /**
98
     * Builds a Geometry from a WKB representation.
99
     *
100
     * If the resulting geometry is valid but is not an instance of the class this method is called on,
101
     * for example passing a Polygon WKB to Point::fromBinary(), an exception is thrown.
102
     *
103
     * @param string $wkb  The Well-Known Binary representation.
104
     * @param int    $srid The optional SRID to use.
105
     *
106
     * @throws GeometryIOException         If the given string is not a valid WKB representation.
107
     * @throws CoordinateSystemException   If the WKB contains mixed coordinate systems.
108
     * @throws InvalidGeometryException    If the WKB represents an invalid geometry.
109
     * @throws UnexpectedGeometryException If the resulting geometry is not an instance of the current class.
110
     */
111
    public static function fromBinary(string $wkb, int $srid = 0) : static
112
    {
113
        /** @var WKBReader|null $wkbReader */
114
        static $wkbReader;
98✔
115

116
        if ($wkbReader === null) {
98✔
117
            $wkbReader = new WKBReader();
7✔
118
        }
119

120
        $geometry = $wkbReader->read($wkb, $srid);
98✔
121

122
        if ($geometry instanceof static) {
98✔
123
            return $geometry;
28✔
124
        }
125

126
        throw UnexpectedGeometryException::unexpectedGeometryType(static::class, $geometry);
70✔
127
    }
128

129
    /**
130
     * Returns the inherent dimension of this geometry.
131
     *
132
     * This dimension must be less than or equal to the coordinate dimension.
133
     * In non-homogeneous collections, this will return the largest topological dimension of the contained objects.
134
     */
135
    abstract public function dimension() : int;
136

137
    /**
138
     * Returns the coordinate dimension of this geometry.
139
     *
140
     * The coordinate dimension is the total number of coordinates in the coordinate system.
141
     *
142
     * The coordinate dimension can be 2 (for x and y), 3 (with z or m added), or 4 (with both z and m added).
143
     * The ordinates x, y and z are spatial, and the ordinate m is a measure.
144
     *
145
     * @return int<2, 4>
146
     */
147
    public function coordinateDimension() : int
148
    {
149
        return $this->coordinateSystem->coordinateDimension();
56✔
150
    }
151

152
    /**
153
     * Returns the spatial dimension of this geometry.
154
     *
155
     * The spatial dimension is the number of measurements or axes needed to describe the
156
     * spatial position of this geometry in a coordinate system.
157
     *
158
     * The spatial dimension is 3 if the coordinate system has a Z coordinate, 2 otherwise.
159
     *
160
     * @return int<2, 3>
161
     */
162
    public function spatialDimension() : int
163
    {
164
        return $this->coordinateSystem->spatialDimension();
56✔
165
    }
166

167
    /**
168
     * Returns the name of the instantiable subtype of Geometry of which this Geometry is an instantiable member.
169
     */
170
    abstract public function geometryType() : string;
171

172
    abstract public function geometryTypeBinary() : int;
173

174
    /**
175
     * Returns the Spatial Reference System ID for this geometry.
176
     *
177
     * @return int The SRID, zero if not set.
178
     */
179
    public function SRID() : int
180
    {
181
        return $this->coordinateSystem->srid;
16,681✔
182
    }
183

184
    /**
185
     * Returns the WKT representation of this geometry.
186
     */
187
    public function asText() : string
188
    {
189
        /** @var WKTWriter|null $wktWriter */
190
        static $wktWriter;
5,635✔
191

192
        if ($wktWriter === null) {
5,635✔
193
            $wktWriter = new WKTWriter();
7✔
194
        }
195

196
        return $wktWriter->write($this);
5,635✔
197
    }
198

199
    /**
200
     * Returns the WKB representation of this geometry.
201
     */
202
    public function asBinary() : string
203
    {
204
        /** @var WKBWriter|null $wkbWriter */
205
        static $wkbWriter;
1,583✔
206

207
        if ($wkbWriter === null) {
1,583✔
208
            $wkbWriter = new WKBWriter();
7✔
209
        }
210

211
        return $wkbWriter->write($this);
1,583✔
212
    }
213

214
    /**
215
     * Returns whether this geometry is the empty Geometry.
216
     *
217
     * If true, then this geometry represents the empty point set for the coordinate space.
218
     */
219
    public function isEmpty() : bool
220
    {
221
        return $this->isEmpty;
16,524✔
222
    }
223

224
    /**
225
     * Returns whether this geometry has z coordinate values.
226
     */
227
    public function is3D() : bool
228
    {
229
        return $this->coordinateSystem->hasZ;
5,487✔
230
    }
231

232
    /**
233
     * Returns whether this geometry has m coordinate values.
234
     */
235
    public function isMeasured() : bool
236
    {
237
        return $this->coordinateSystem->hasM;
5,487✔
238
    }
239

240
    /**
241
     * Returns the coordinate system of this geometry.
242
     *
243
     * @deprecated Use $coordinateSystem property instead.
244
     */
245
    public function coordinateSystem() : CoordinateSystem
246
    {
UNCOV
247
        return $this->coordinateSystem;
×
248
    }
249

250
    /**
251
     * Returns a copy of this Geometry, with the SRID altered.
252
     *
253
     * Note that only the SRID value is changed, the coordinates are not reprojected.
254
     * Use GeometryEngine::transform() to reproject the Geometry to another SRID.
255
     */
256
    public function withSRID(int $srid) : static
257
    {
258
        if ($srid === $this->SRID()) {
196✔
259
            return $this;
×
260
        }
261

262
        return $this->project(new SRIDProjector($srid));
196✔
263
    }
264

265
    /**
266
     * Returns a copy of this Geometry, with Z and M coordinates removed.
267
     */
268
    public function toXY(): static
269
    {
270
        if ($this->coordinateDimension() === 2) {
×
271
            return $this;
×
272
        }
273

274
        return $this->project(new RemoveZMProjector(removeZ: true, removeM: true));
×
275
    }
276

277
    /**
278
     * Returns a copy of this Geometry, with the Z coordinate removed.
279
     */
280
    public function withoutZ() : static
281
    {
282
        if (! $this->coordinateSystem->hasZ) {
×
283
            return $this;
×
284
        }
285

286
        return $this->project(new RemoveZMProjector(removeZ: true));
×
287
    }
288

289
    /**
290
     * Returns a copy of this Geometry, with the M coordinate removed.
291
     */
292
    public function withoutM() : static
293
    {
294
        if (! $this->coordinateSystem->hasM) {
693✔
295
            return $this;
567✔
296
        }
297

298
        return $this->project(new RemoveZMProjector(removeM: true));
182✔
299
    }
300

301
    /**
302
     * Returns the bounding box of the Geometry.
303
     */
304
    abstract public function getBoundingBox() : BoundingBox;
305

306
    /**
307
     * Returns the raw coordinates of this geometry as an array.
308
     *
309
     * This returns potentially nested lists of floats.
310
     *
311
     * Examples:
312
     * - a Point will return list<float>
313
     * - a LineString will return list<list<float>>
314
     * - a Polygon will return list<list<list<float>>>
315
     *
316
     * Subclasses will narrow down the return type as appropriate.
317
     *
318
     * @return list<mixed>
319
     */
320
    abstract public function toArray() : array;
321

322
    /**
323
     * Returns a copy of this Geometry, with the X and Y coordinates swapped.
324
     */
325
    public function swapXY() : static
326
    {
327
        return $this->project(new SwapXYProjector());
14✔
328
    }
329

330
    /**
331
     * Projects this geometry to a different coordinate system.
332
     */
333
    abstract public function project(Projector $projector): static;
334

335
    /**
336
     * Returns whether this Geometry is identical to another Geometry.
337
     *
338
     * This method will only return true if the geometries are of the same type, with the exact same coordinates,
339
     * in the same order, and with the same SRID.
340
     *
341
     * This is different from the concept of spatially equal; if you need to check for spatial equality,
342
     * please see `GeometryEngine::equals()` instead.
343
     */
344
    public function isIdenticalTo(Geometry $that) : bool
345
    {
346
        return $this->SRID() === $that->SRID() && $this->asText() === $that->asText();
196✔
347
    }
348

349
    /**
350
     * Returns a text representation of this geometry.
351
     */
352
    #[Override]
353
    final public function __toString() : string
354
    {
355
        return $this->asText();
×
356
    }
357
}
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