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

brick / geo / 13642551372

03 Mar 2025 11:25PM UTC coverage: 84.406% (+0.8%) from 83.61%
13642551372

push

github

BenMorel
Merge WKTParser & EWKTParser

31 of 32 new or added lines in 3 files covered. (96.88%)

69 existing lines in 8 files now uncovered.

1548 of 1834 relevant lines covered (84.41%)

1988.83 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 class Geometry implements \Countable, \IteratorAggregate, \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
    protected 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;
25,713✔
62
        $this->isEmpty          = $isEmpty;
25,713✔
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;
6,561✔
83

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

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

90
        if ($geometry instanceof static) {
6,512✔
91
            return $geometry;
6,449✔
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,274✔
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,421✔
191

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

196
        return $wktWriter->write($this);
5,421✔
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,181✔
206

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

211
        return $wkbWriter->write($this);
1,181✔
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;
15,860✔
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,278✔
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,278✔
238
    }
239

240
    /**
241
     * Returns the coordinate system of this geometry.
242
     */
243
    public function coordinateSystem() : CoordinateSystem
244
    {
245
        return $this->coordinateSystem;
21,457✔
246
    }
247

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

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

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

UNCOV
272
        return $this->project(new RemoveZMProjector(removeZ: true, removeM: true));
×
273
    }
274

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

UNCOV
284
        return $this->project(new RemoveZMProjector(removeZ: true));
×
285
    }
286

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

296
        return $this->project(new RemoveZMProjector(removeM: true));
7✔
297
    }
298

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

304
    /**
305
     * Returns the raw coordinates of this geometry as an array.
306
     */
307
    abstract public function toArray() : array;
308

309
    /**
310
     * Returns a copy of this Geometry, with the X and Y coordinates swapped.
311
     */
312
    public function swapXY() : static
313
    {
UNCOV
314
        return $this->project(new SwapXYProjector());
×
315
    }
316

317
    /**
318
     * Projects this geometry to a different coordinate system.
319
     */
320
    abstract public function project(Projector $projector): static;
321

322
    /**
323
     * Returns whether this Geometry is identical to another Geometry.
324
     *
325
     * This method will only return true if the geometries are of the same type, with the exact same coordinates,
326
     * in the same order, and with the same SRID.
327
     *
328
     * This is different from the concept of spatially equal; if you need to check for spatial equality,
329
     * please see `GeometryEngine::equals()` instead.
330
     */
331
    public function isIdenticalTo(Geometry $that) : bool
332
    {
333
        return $this->SRID() === $that->SRID() && $this->asText() === $that->asText();
196✔
334
    }
335

336
    /**
337
     * Returns a text representation of this geometry.
338
     */
339
    #[Override]
340
    final public function __toString() : string
341
    {
UNCOV
342
        return $this->asText();
×
343
    }
344
}
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