• 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

93.4
/src/IO/AbstractWKBReader.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Brick\Geo\IO;
6

7
use Brick\Geo\CircularString;
8
use Brick\Geo\CompoundCurve;
9
use Brick\Geo\CoordinateSystem;
10
use Brick\Geo\Curve;
11
use Brick\Geo\CurvePolygon;
12
use Brick\Geo\Geometry;
13
use Brick\Geo\GeometryCollection;
14
use Brick\Geo\LineString;
15
use Brick\Geo\MultiLineString;
16
use Brick\Geo\MultiPoint;
17
use Brick\Geo\MultiPolygon;
18
use Brick\Geo\Point;
19
use Brick\Geo\Polygon;
20
use Brick\Geo\PolyhedralSurface;
21
use Brick\Geo\TIN;
22
use Brick\Geo\Triangle;
23

24
use Brick\Geo\Exception\GeometryIOException;
25

26
/**
27
 * Base class for WKBReader and EWKBReader.
28
 *
29
 * @internal
30
 */
31
abstract class AbstractWKBReader
32
{
33
    /**
34
     * @throws GeometryIOException
35
     */
36
    abstract protected function readGeometryHeader(WKBBuffer $buffer) : WKBGeometryHeader;
37

38
    /**
39
     * @throws GeometryIOException
40
     */
41
    protected function readGeometry(WKBBuffer $buffer, int $srid) : Geometry
42
    {
43
        $buffer->readByteOrder();
6,829✔
44

45
        $geometryHeader = $this->readGeometryHeader($buffer);
6,829✔
46

47
        $cs = new CoordinateSystem(
6,829✔
48
            $geometryHeader->hasZ,
6,829✔
49
            $geometryHeader->hasM,
6,829✔
50
            $geometryHeader->srid ?? $srid
6,829✔
51
        );
6,829✔
52

53
        return match ($geometryHeader->geometryType) {
6,829✔
54
            Geometry::POINT => $this->readPoint($buffer, $cs),
1,839✔
55
            Geometry::LINESTRING => $this->readLineString($buffer, $cs),
2,270✔
56
            Geometry::CIRCULARSTRING => $this->readCircularString($buffer, $cs),
1,596✔
57
            Geometry::COMPOUNDCURVE => $this->readCompoundCurve($buffer, $cs),
1,244✔
58
            Geometry::POLYGON => $this->readPolygon($buffer, $cs),
1,962✔
59
            Geometry::CURVEPOLYGON => $this->readCurvePolygon($buffer, $cs),
973✔
60
            Geometry::MULTIPOINT => $this->readMultiPoint($buffer, $cs),
1,003✔
61
            Geometry::MULTILINESTRING => $this->readMultiLineString($buffer, $cs),
1,042✔
62
            Geometry::MULTIPOLYGON => $this->readMultiPolygon($buffer, $cs),
969✔
63
            Geometry::GEOMETRYCOLLECTION => $this->readGeometryCollection($buffer, $cs),
663✔
64
            Geometry::POLYHEDRALSURFACE => $this->readPolyhedralSurface($buffer, $cs),
597✔
65
            Geometry::TIN => $this->readTIN($buffer, $cs),
512✔
66
            Geometry::TRIANGLE => $this->readTriangle($buffer, $cs),
672✔
67
            default => throw GeometryIOException::unsupportedWKBType($geometryHeader->geometryType),
6,829✔
68
        };
6,829✔
69
    }
70

71
    private function readPoint(WKBBuffer $buffer, CoordinateSystem $cs) : Point
72
    {
73
        $coords = $buffer->readDoubles($cs->coordinateDimension());
4,048✔
74

75
        return new Point($cs, ...$coords);
4,048✔
76
    }
77

78
    private function readLineString(WKBBuffer $buffer, CoordinateSystem $cs) : LineString
79
    {
80
        $numPoints = $buffer->readUnsignedLong();
3,283✔
81

82
        $points = [];
3,283✔
83

84
        for ($i = 0; $i < $numPoints; $i++) {
3,283✔
85
            $points[] = $this->readPoint($buffer, $cs);
3,038✔
86
        }
87

88
        return new LineString($cs, ...$points);
3,283✔
89
    }
90

91
    private function readCircularString(WKBBuffer $buffer, CoordinateSystem $cs) : CircularString
92
    {
93
        $numPoints = $buffer->readUnsignedLong();
896✔
94

95
        $points = [];
896✔
96

97
        for ($i = 0; $i < $numPoints; $i++) {
896✔
98
            $points[] = $this->readPoint($buffer, $cs);
672✔
99
        }
100

101
        return new CircularString($cs, ...$points);
896✔
102
    }
103

104
    /**
105
     * @throws GeometryIOException
106
     */
107
    private function readCompoundCurve(WKBBuffer $buffer, CoordinateSystem $cs) : CompoundCurve
108
    {
109
        $numCurves = $buffer->readUnsignedLong();
560✔
110
        $curves = [];
560✔
111

112
        for ($i = 0; $i < $numCurves; $i++) {
560✔
113
            $curve = $this->readGeometry($buffer, $cs->SRID());
336✔
114

115
            if (! $curve instanceof LineString && ! $curve instanceof CircularString) {
336✔
116
                throw new GeometryIOException('Expected LineString|CircularString, got ' . $curve->geometryType());
×
117
            }
118

119
            $curves[] = $curve;
336✔
120
        }
121

122
        return new CompoundCurve($cs, ...$curves);
560✔
123
    }
124

125
    private function readPolygon(WKBBuffer $buffer, CoordinateSystem $cs) : Polygon
126
    {
127
        $numRings = $buffer->readUnsignedLong();
1,471✔
128

129
        $rings = [];
1,471✔
130

131
        for ($i = 0; $i < $numRings; $i++) {
1,471✔
132
            $rings[] = $this->readLineString($buffer, $cs);
1,233✔
133
        }
134

135
        return new Polygon($cs, ...$rings);
1,471✔
136
    }
137

138
    /**
139
     * @throws GeometryIOException
140
     */
141
    private function readCurvePolygon(WKBBuffer $buffer, CoordinateSystem $cs) : CurvePolygon
142
    {
143
        $numRings = $buffer->readUnsignedLong();
448✔
144

145
        $rings = [];
448✔
146

147
        for ($i = 0; $i < $numRings; $i++) {
448✔
148
            $ring = $this->readGeometry($buffer, $cs->SRID());
224✔
149

150
            if (! $ring instanceof Curve) {
224✔
151
                throw new GeometryIOException('Expected Curve, got ' . $ring->geometryType());
×
152
            }
153

154
            $rings[] = $ring;
224✔
155
        }
156

157
        return new CurvePolygon($cs, ...$rings);
448✔
158
    }
159

160
    /**
161
     * @throws GeometryIOException
162
     */
163
    private function readMultiPoint(WKBBuffer $buffer, CoordinateSystem $cs) : MultiPoint
164
    {
165
        $numPoints = $buffer->readUnsignedLong();
545✔
166
        $points = [];
545✔
167

168
        for ($i = 0; $i < $numPoints; $i++) {
545✔
169
            $point = $this->readGeometry($buffer, $cs->SRID());
321✔
170

171
            if (! $point instanceof Point) {
321✔
172
                throw new GeometryIOException('Expected Point, got ' . $point->geometryType());
×
173
            }
174

175
            $points[] = $point;
321✔
176
        }
177

178
        return new MultiPoint($cs, ...$points);
545✔
179
    }
180

181
    /**
182
     * @throws GeometryIOException
183
     */
184
    private function readMultiLineString(WKBBuffer $buffer, CoordinateSystem $cs) : MultiLineString
185
    {
186
        $numLineStrings = $buffer->readUnsignedLong();
681✔
187
        $lineStrings = [];
681✔
188

189
        for ($i = 0; $i < $numLineStrings; $i++) {
681✔
190
            $lineString = $this->readGeometry($buffer, $cs->SRID());
450✔
191

192
            if (! $lineString instanceof LineString) {
450✔
193
                throw new GeometryIOException('Expected LineString, got ' . $lineString->geometryType());
×
194
            }
195

196
            $lineStrings[] = $lineString;
450✔
197
        }
198

199
        return new MultiLineString($cs, ...$lineStrings);
681✔
200
    }
201

202
    /**
203
     * @throws GeometryIOException
204
     */
205
    private function readMultiPolygon(WKBBuffer $buffer, CoordinateSystem $cs) : MultiPolygon
206
    {
207
        $numPolygons = $buffer->readUnsignedLong();
708✔
208
        $polygons = [];
708✔
209

210
        for ($i = 0; $i < $numPolygons; $i++) {
708✔
211
            $polygon = $this->readGeometry($buffer, $cs->SRID());
470✔
212

213
            if (! $polygon instanceof Polygon) {
470✔
214
                throw new GeometryIOException('Expected Polygon, got ' . $polygon->geometryType());
×
215
            }
216

217
            $polygons[] = $polygon;
470✔
218
        }
219

220
        return new MultiPolygon($cs, ...$polygons);
708✔
221
    }
222

223
    private function readGeometryCollection(WKBBuffer $buffer, CoordinateSystem $cs) : GeometryCollection
224
    {
225
        $numGeometries = $buffer->readUnsignedLong();
468✔
226
        $geometries = [];
468✔
227

228
        for ($i = 0; $i < $numGeometries; $i++) {
468✔
229
            $geometries[] = $this->readGeometry($buffer, $cs->SRID());
228✔
230
        }
231

232
        return new GeometryCollection($cs, ...$geometries);
468✔
233
    }
234

235
    /**
236
     * @throws GeometryIOException
237
     */
238
    private function readPolyhedralSurface(WKBBuffer $buffer, CoordinateSystem $cs) : PolyhedralSurface
239
    {
240
        $numPatches = $buffer->readUnsignedLong();
469✔
241
        $patches = [];
469✔
242

243
        for ($i = 0; $i < $numPatches; $i++) {
469✔
244
            $patch = $this->readGeometry($buffer, $cs->SRID());
224✔
245

246
            if (! $patch instanceof Polygon) {
224✔
247
                throw new GeometryIOException('Expected Polygon, got ' . $patch->geometryType());
×
248
            }
249

250
            $patches[] = $patch;
224✔
251
        }
252

253
        return new PolyhedralSurface($cs, ...$patches);
469✔
254
    }
255

256
    /**
257
     * @throws GeometryIOException
258
     */
259
    private function readTIN(WKBBuffer $buffer, CoordinateSystem $cs) : TIN
260
    {
261
        $numPatches = $buffer->readUnsignedLong();
448✔
262
        $patches = [];
448✔
263

264
        for ($i = 0; $i < $numPatches; $i++) {
448✔
265
            $patch = $this->readGeometry($buffer, $cs->SRID());
224✔
266

267
            if (! $patch instanceof Triangle) {
224✔
268
                throw new GeometryIOException('Expected Triangle, got ' . $patch->geometryType());
×
269
            }
270

271
            $patches[] = $patch;
224✔
272
        }
273

274
        return new TIN($cs, ...$patches);
448✔
275
    }
276

277
    private function readTriangle(WKBBuffer $buffer, CoordinateSystem $cs) : Triangle
278
    {
279
        $numRings = $buffer->readUnsignedLong();
672✔
280

281
        $rings = [];
672✔
282

283
        for ($i = 0; $i < $numRings; $i++) {
672✔
284
            $rings[] = $this->readLineString($buffer, $cs);
448✔
285
        }
286

287
        return new Triangle($cs, ...$rings);
672✔
288
    }
289
}
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