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

brick / geo / 13716844819

07 Mar 2025 08:35AM UTC coverage: 47.964% (+3.9%) from 44.086%
13716844819

push

github

BenMorel
Add TypeChecker for engines

8 of 21 new or added lines in 5 files covered. (38.1%)

98 existing lines in 18 files now uncovered.

1684 of 3511 relevant lines covered (47.96%)

944.32 hits per line

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

96.83
/src/IO/AbstractWKBWriter.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Brick\Geo\IO;
6

7
use Brick\Geo\Exception\GeometryIOException;
8
use Brick\Geo\CircularString;
9
use Brick\Geo\CompoundCurve;
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\Point;
16
use Brick\Geo\Polygon;
17
use Brick\Geo\PolyhedralSurface;
18

19
/**
20
 * Base class for WKBWriter and EWKBWriter.
21
 *
22
 * @internal
23
 */
24
abstract class AbstractWKBWriter
25
{
26
    private WKBByteOrder $byteOrder;
27

28
    private WKBByteOrder $machineByteOrder;
29

30
    /**
31
     * @throws GeometryIOException
32
     */
33
    public function __construct()
34
    {
35
        $this->byteOrder = $this->machineByteOrder = WKBTools::getMachineByteOrder();
4,767✔
36
    }
37

38
    public function setByteOrder(WKBByteOrder $byteOrder) : void
39
    {
40
        $this->byteOrder = $byteOrder;
4,704✔
41
    }
42

43
    /**
44
     * @param Geometry $geometry The geometry to export as WKB.
45
     *
46
     * @return string The WKB representation of the given geometry.
47
     *
48
     * @throws GeometryIOException If the given geometry cannot be exported as WKB.
49
     */
50
    public function write(Geometry $geometry) : string
51
    {
52
        return $this->doWrite($geometry, true);
6,144✔
53
    }
54

55
    /**
56
     * @param Geometry $geometry The geometry export as WKB write.
57
     * @param bool     $outer    False if the geometry is nested in another geometry, true otherwise.
58
     *
59
     * @return string The WKB representation of the given geometry.
60
     *
61
     * @throws GeometryIOException If the given geometry cannot be exported as WKT.
62
     */
63
    protected function doWrite(Geometry $geometry, bool $outer) : string
64
    {
65
        if ($geometry instanceof Point) {
6,144✔
66
            return $this->writePoint($geometry, $outer);
979✔
67
        }
68

69
        if ($geometry instanceof LineString) {
5,752✔
70
            return $this->writeCurve($geometry, $outer);
1,796✔
71
        }
72

73
        if ($geometry instanceof CircularString) {
5,025✔
74
            return $this->writeCurve($geometry, $outer);
743✔
75
        }
76

77
        if ($geometry instanceof Polygon) {
4,653✔
78
            return $this->writePolygon($geometry, $outer);
2,004✔
79
        }
80

81
        if ($geometry instanceof CompoundCurve) {
3,445✔
82
            return $this->writeComposedGeometry($geometry, $outer);
448✔
83
        }
84

85
        if ($geometry instanceof CurvePolygon) {
3,081✔
86
            return $this->writeComposedGeometry($geometry, $outer);
350✔
87
        }
88

89
        if ($geometry instanceof GeometryCollection) {
2,731✔
90
            return $this->writeComposedGeometry($geometry, $outer);
2,052✔
91
        }
92

93
        if ($geometry instanceof PolyhedralSurface) {
679✔
94
            return $this->writeComposedGeometry($geometry, $outer);
679✔
95
        }
96

UNCOV
97
        throw GeometryIOException::unsupportedGeometryType($geometry->geometryType());
×
98
    }
99

100
    private function packByteOrder() : string
101
    {
102
        return pack('C', $this->byteOrder->value);
6,144✔
103
    }
104

105
    protected function packUnsignedInteger(int $uint) : string
106
    {
107
        return pack(match ($this->byteOrder) {
6,144✔
108
            WKBByteOrder::BIG_ENDIAN => 'N',
6,144✔
109
            WKBByteOrder::LITTLE_ENDIAN => 'V'
6,144✔
110
        }, $uint);
6,144✔
111
    }
112

113
    private function packDouble(float $double) : string
114
    {
115
        $binary = pack('d', $double);
4,051✔
116

117
        if ($this->byteOrder !== $this->machineByteOrder) {
4,051✔
118
            return strrev($binary);
1,344✔
119
        }
120

121
        return $binary;
2,707✔
122
    }
123

124
    /**
125
     * @throws GeometryIOException
126
     */
127
    private function packPoint(Point $point) : string
128
    {
129
        if ($point->isEmpty()) {
4,107✔
130
            throw new GeometryIOException('Empty points have no WKB representation.');
56✔
131
        }
132

133
        /** @psalm-suppress PossiblyNullArgument */
134
        $binary = $this->packDouble($point->x()) . $this->packDouble($point->y());
4,051✔
135

136
        if (null !== $z = $point->z()) {
4,051✔
137
            $binary .= $this->packDouble($z);
1,485✔
138
        }
139
        if (null !== $m = $point->m()) {
4,051✔
140
            $binary .= $this->packDouble($m);
1,440✔
141
        }
142

143
        return $binary;
4,051✔
144
    }
145

146
    /**
147
     * @throws GeometryIOException
148
     */
149
    private function packCurve(Curve $curve) : string
150
    {
151
        if (! $curve instanceof LineString && ! $curve instanceof CircularString) {
3,774✔
152
            // CompoundCurve is not a list of Points, not sure if WKB supports it!
153
            // For now, let's just not support it ourselves.
UNCOV
154
            throw new GeometryIOException(sprintf('Writing a %s as WKB is not supported.', $curve->geometryType()));
×
155
        }
156

157
        $wkb = $this->packUnsignedInteger($curve->count());
3,774✔
158

159
        foreach ($curve as $point) {
3,774✔
160
            $wkb .= $this->packPoint($point);
3,431✔
161
        }
162

163
        return $wkb;
3,774✔
164
    }
165

166
    private function writePoint(Point $point, bool $outer) : string
167
    {
168
        $wkb = $this->packByteOrder();
979✔
169
        $wkb.= $this->packHeader($point, $outer);
979✔
170
        $wkb.= $this->packPoint($point);
979✔
171

172
        return $wkb;
923✔
173
    }
174

175
    private function writeCurve(Curve $curve, bool $outer) : string
176
    {
177
        $wkb = $this->packByteOrder();
2,175✔
178
        $wkb.= $this->packHeader($curve, $outer);
2,175✔
179
        $wkb.= $this->packCurve($curve);
2,175✔
180

181
        return $wkb;
2,175✔
182
    }
183

184
    private function writePolygon(Polygon $polygon, bool $outer) : string
185
    {
186
        $wkb = $this->packByteOrder();
2,004✔
187
        $wkb.= $this->packHeader($polygon, $outer);
2,004✔
188
        $wkb.= $this->packUnsignedInteger($polygon->count());
2,004✔
189

190
        foreach ($polygon as $ring) {
2,004✔
191
            $wkb .= $this->packCurve($ring);
1,668✔
192
        }
193

194
        return $wkb;
2,004✔
195
    }
196

197
    private function writeComposedGeometry(CompoundCurve|CurvePolygon|GeometryCollection|PolyhedralSurface $collection, bool $outer) : string
198
    {
199
        $wkb = $this->packByteOrder();
3,445✔
200
        $wkb.= $this->packHeader($collection, $outer);
3,445✔
201
        $wkb.= $this->packUnsignedInteger($collection->count());
3,445✔
202

203
        foreach ($collection as $geometry) {
3,445✔
204
            $wkb .= $this->doWrite($geometry, false);
2,087✔
205
        }
206

207
        return $wkb;
3,445✔
208
    }
209

210
    abstract protected function packHeader(Geometry $geometry, bool $outer) : string;
211
}
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