-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
GeometryType.php
133 lines (108 loc) · 3.55 KB
/
GeometryType.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
declare(strict_types=1);
namespace Brick\Geo\Doctrine\Types;
use Brick\Geo\Geometry;
use Brick\Geo\IO\WKBReader;
use Brick\Geo\Proxy\GeometryProxy;
use Brick\Geo\Proxy\ProxyInterface;
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Types\Type;
/**
* Doctrine type for Geometry.
*/
class GeometryType extends Type
{
/**
* The default SRID to use for geometries when talking to the database.
*
* This is the SRID that will be used when retrieving geometries from the database,
* as the WKT and WKB formats do not include the SRID information.
*
* Due to current limitations in Doctrine, this will also be used when sending geometries to the database,
* in place of the actual SRID of the geometry.
*
* @see https://github.com/doctrine/orm/issues/4114
*/
public static int $srid = 0;
private ?WKBReader $wkbReader = null;
/**
* @psalm-return class-string<ProxyInterface&Geometry>
*/
protected function getProxyClassName() : string
{
return GeometryProxy::class;
}
/**
* Returns whether the associated geometry class has known (non-proxy) subclasses.
* If true, the WKB has to be introspected before the correct proxy class can be instantiated.
*/
protected function hasKnownSubclasses() : bool
{
return true;
}
public function getName() : string
{
return 'Geometry';
}
public function getSQLDeclaration(array $column, AbstractPlatform $platform) : string
{
if ($platform instanceof PostgreSQLPlatform) {
return 'GEOMETRY';
}
return strtoupper($this->getName());
}
public function convertToPHPValue($value, AbstractPlatform $platform) : ?Geometry
{
/** @var string|resource|null $value */
if ($value === null) {
return null;
}
if (is_resource($value)) {
$value = stream_get_contents($value);
}
if ($this->hasKnownSubclasses()) {
// Introspect the WKB to get the correct proxy class
if ($this->wkbReader === null) {
$this->wkbReader = new WKBReader();
}
return $this->wkbReader->readAsProxy($value, self::$srid);
}
$proxyClassName = $this->getProxyClassName();
return new $proxyClassName($value, true, self::$srid);
}
public function convertToDatabaseValue($value, AbstractPlatform $platform) : ?string
{
if ($value === null) {
return null;
}
if ($value instanceof Geometry) {
return $value->asBinary();
}
throw new \UnexpectedValueException(sprintf('Expected %s, got %s.', Geometry::class, get_debug_type($value)));
}
public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) : string
{
if ($platform instanceof AbstractMySQLPlatform) {
$sqlExpr = sprintf('BINARY %s', $sqlExpr);
}
return sprintf('ST_GeomFromWKB(%s, %d)', $sqlExpr, self::$srid);
}
public function convertToPHPValueSQL($sqlExpr, $platform) : string
{
return sprintf('ST_AsBinary(%s)', $sqlExpr);
}
public function canRequireSQLConversion() : bool
{
return true;
}
public function requiresSQLCommentHint(AbstractPlatform $platform) : bool
{
return true;
}
public function getBindingType() : int
{
return \PDO::PARAM_LOB;
}
}