1<?php
2/**
3 * EWKB (Extended Well Known Binary) Adapter
4 */
5class EWKB extends WKB
6{
7
8  /**
9   * Read WKB binary string into geometry objects
10   *
11   * @param string $wkb An Extended-WKB binary string
12   *
13   * @return Geometry
14   */
15  public function read($wkb, $is_hex_string = FALSE) {
16    if ($is_hex_string) {
17      $wkb = pack('H*',$wkb);
18    }
19
20    // Open the wkb up in memory so we can examine the SRID
21    $mem = fopen('php://memory', 'r+');
22    fwrite($mem, $wkb);
23    fseek($mem, 0);
24    $base_info = unpack("corder/ctype/cz/cm/cs", fread($mem, 5));
25    if ($base_info['s']) {
26      $srid = current(unpack("Lsrid", fread($mem, 4)));
27    }
28    else {
29      $srid = NULL;
30    }
31    fclose($mem);
32
33    // Run the wkb through the normal WKB reader to get the geometry
34    $wkb_reader = new WKB();
35    $geom = $wkb_reader->read($wkb);
36
37    // If there is an SRID, add it to the geometry
38    if ($srid) {
39      $geom->setSRID($srid);
40    }
41
42    return $geom;
43  }
44
45  /**
46   * Serialize geometries into an EWKB binary string.
47   *
48   * @param Geometry $geometry
49   *
50   * @return string The Extended-WKB binary string representation of the input geometries
51   */
52  public function write(Geometry $geometry, $write_as_hex = FALSE) {
53    // We always write into NDR (little endian)
54    $wkb = pack('c',1);
55
56    switch ($geometry->getGeomType()) {
57      case 'Point';
58        $wkb .= pack('L',1);
59        $wkb .= $this->writePoint($geometry);
60        break;
61      case 'LineString';
62        $wkb .= pack('L',2);
63        $wkb .= $this->writeLineString($geometry);
64        break;
65      case 'Polygon';
66        $wkb .= pack('L',3);
67        $wkb .= $this->writePolygon($geometry);
68        break;
69      case 'MultiPoint';
70        $wkb .= pack('L',4);
71        $wkb .= $this->writeMulti($geometry);
72        break;
73      case 'MultiLineString';
74        $wkb .= pack('L',5);
75        $wkb .= $this->writeMulti($geometry);
76        break;
77      case 'MultiPolygon';
78        $wkb .= pack('L',6);
79        $wkb .= $this->writeMulti($geometry);
80        break;
81      case 'GeometryCollection';
82        $wkb .= pack('L',7);
83        $wkb .= $this->writeMulti($geometry);
84        break;
85    }
86
87    if ($write_as_hex) {
88      $unpacked = unpack('H*',$wkb);
89      return $unpacked[1];
90    }
91    else {
92      return $wkb;
93    }
94  }
95
96}
97