如何在php中解包mysql多点几何数据?

kxe2p93d  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(307)

好吧,我想我离这里很近了,但是我对二进制数据的理解有一个限制。
我正在解析一些作为几何类型插入的mysql数据,使用php的 unpack() 作为我的解析器,一切都进展顺利,直到我开始尝试解包复杂的几何体类型(例如。 MULTIPOINT ).
为了一个 POINT 对于数据类型,我已经成功地使用了一个解包模式,它简单地忽略了第一个块,然后给了我一个 type , order , lat 以及 lon :

$coords = unpack('x/x/x/x/corder/Ltype/dlat/dlon', $point);
// >>> [
//       'order' => 1,
//       'type' => 1,
//       'lat' => (expected value),
//       'lon' => (expected value)
//     ];

很自然地,将完全相同的模式应用于 MULTIPOINT 几何图形的工作原理不一样。它得到了 order 以及 type 变成4,但是 lat 以及 lon 完全不是我所期望的。所以,我好奇地想看看整个事情是什么样子,于是我改变了模式,把它全部说成“double(依赖于机器的大小和表示)”类型:

$coords = unpack('x/x/x/x/corder/Ltype/d*', $multipoint);
// >>> mayhem

解包的内容实际上包括五个额外的数组项,而不是我所期望的具有两个点(2x2)的多点的4个数组项,而且这些值非常奇怪。例如,一个值,我希望它在40点左右的某个范围内,不管它看起来像什么 -1.0977282851114052e-218 .
打开 Package 的正确方法是什么 MULTIPOINT ? 我的直觉告诉我,我正在把字节切分到不该切分的地方,或者将它们转换成不合适的类型,但我不确定这些应该是什么。

twh00eeo

twh00eeo1#

找了一点,但我找到了各种几何图形的wkb格式的参考。正如我通过查看

SELECT HEX(ST_GeomFromText('MULTIPOINT(1 1, 2 2, 3 3)'))

顺序和类型后面有点数。挑战在于,对于每一个点和每一个点,都要重新声明顺序和类型 unpack 没有重复一组字节的概念。因此,您需要提取每个点的字节并运行 unpack 又来了。显然,一旦您尝试考虑更多的空间类型,这将开始涉及更多内容。

<?php
$multipoint_wkb = hex2bin("000000000104000000030000000101000000000000000000F03F000000000000F03F010100000000000000000000400000000000000040010100000000000000000008400000000000000840");

function unpack_multipoint($multipoint)
{
    $data = unpack("x4/corder/Ltype/Lcount", $multipoint);
    for ($i = 0; $i < $data["count"]; $i++) {
        // the header is 1+4+8 bytes and each point record is 1+4+8+8 bytes
        $offset = ($i * 21) + 13;
        $return[] = unpack("corder/Ltype/dlat/dlon", $multipoint, $offset);
    }
    return $return;
}

print_r(unpack_multipoint($multipoint_wkb));

值得注意的是,这4个nul字节是由mysql插入的,但不是实际geometry对象的一部分。我根据你的问题把它们留在原处,但是如果你用 ST_AsWKB 功能:

SELECT HEX(ST_AsWKB(ST_GeomFromText('MULTIPOINT(1 1, 2 2, 3 3)')))

多余的字节未加前缀。

相关问题