Python如何解码存储为字节的GIS边界?

Python how to decode GIS boundary stored as bytes?

我从 Open Street Map(使用 pyrosm 包)中提取了一些兴趣点,然后将其导出到镶木地板文件中。这是几何图形,类型为 shapely.geometry:

0                                POINT (-82.65865 41.81229)
1                                POINT (-79.03619 43.15180)
2                                POINT (-73.85599 42.61587)
3                                POINT (-73.88552 42.78819)
4                                POINT (-73.97070 40.67335)
                                ...                        
185430    POLYGON ((-77.82350 42.79552, -77.82337 42.796...
185431    MULTIPOLYGON (((-77.82678 42.79437, -77.82673 ...
185432    POLYGON ((-77.82104 42.79403, -77.82091 42.794...
185433    POLYGON ((-77.82415 42.79387, -77.82417 42.793...
185434    POLYGON ((-77.82503 42.79258, -77.82508 42.792...
Name: geometry, Length: 185435, dtype: geometry

我使用 pandas 中的 to_parquet 方法将此数据帧写入 parquet,但在读回 df 后,我得到的几何图形为字节:

0         b"\x01\x01\x00\x00\x00\x00\x00\x00@'\xaaT\xc0\...
1         b'\x01\x01\x00\x00\x00\x00\x00\x00\xe0P\xc2S\x...
2         b'\x01\x01\x00\x00\x00\x00\x00\x00\x80\xc8vR\x...
3         b'\x01\x01\x00\x00\x00\x00\x00\x00`\xacxR\xc0\...
4         b'\x01\x01\x00\x00\x00\x00\x00\x00\x00 ~R\xc0\...
                                ...                        
185430    b'\x01\x03\x00\x00\x00\x01\x00\x00\x00\x07\x00...
185431    b'\x01\x06\x00\x00\x00\x02\x00\x00\x00\x01\x03...
185432    b'\x01\x03\x00\x00\x00\x04\x00\x00\x00+\x00\x0...
185433    b'\x01\x03\x00\x00\x00\x02\x00\x00\x00\x16\x00...
185434    b'\x01\x03\x00\x00\x00\x03\x00\x00\x00C\x00\x0...
Name: geometry, Length: 185435, dtype: object

似乎 pyarrow/fastparquet 引擎在编写几何图形时遇到了问题。

我尝试了几次转换,使用以下字符串作为示例:

x = b"\x01\x03\x00\x00\x00\x01\x00\x00\x00\x07\x00\x00\x00\x8bp\x93Q\xe5\xb5S\xc0\xc5\x98\xaaj8\x80E@\xe4\x8a\xe6\\xe5\xb5S\xc0\x84\xe3\xe8\xe0O\x80E@\xeb\xa9\xd5W\xd7\xb5S\xc0\x84\xe3\xe8\xe0O\x80E@\xc2\xff\xb1k\xd6\xb5S\xc0\xce\xefE\xc5I\x80E@i\xe5^`\xd6\xb5S\xc0'\xbc\x04\xa7>\x80E@\xeb\xa9\xd5W\xd7\xb5S\xc0\x19i\xf3I8\x80E@\x8bp\x93Q\xe5\xb5S\xc0\xc5\x98\xaaj8\x80E@"

尝试 1:

str(x,'utf-8')

尝试 1 错误:

---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-33-e93cefe956dd> in <module>
----> 1 str(test,'utf-8')

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 13: invalid start byte

尝试 2:

x.encode('utf-8').strip()

尝试 2 错误:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-34-44a32c3005da> in <module>
----> 1 test.encode('utf-8').strip()

AttributeError: 'bytes' object has no attribute 'encode'

我也试过使用 Python 的 geojson 包但是 geojson.Polygon(x) returns 一个整数数组:

{"coordinates": [1, 3, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 139, 112, 147, 81, 229, 181, 83, 192, 197, 152, 170, 106, 56, 128, 69, 64, 228, 138, 230, 92, 229, 181, 83, 192, 132, 227, 232, 224, 79, 128, 69, 64, 235, 169, 213, 87, 215, 181, 83, 192, 132, 227, 232, 224, 79, 128, 69, 64, 194, 255, 177, 107, 214, 181, 83, 192, 206, 239, 69, 197, 73, 128, 69, 64, 105, 229, 94, 96, 214, 181, 83, 192, 39, 188, 4, 167, 62, 128, 69, 64, 235, 169, 213, 87, 215, 181, 83, 192, 25, 105, 243, 73, 56, 128, 69, 64, 139, 112, 147, 81, 229, 181, 83, 192, 197, 152, 170, 106, 56, 128, 69, 64], "type": "Polygon"}

我可以使用其他解码器吗? 如何解码上面的字节串?

更新:

将 df 转换为 GeoPandas df 并使用其 to_parquet 方法有效。知道如何在不使用 GeoPandas.

的情况下进行转换仍然很好

格式好像是WKB,见https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry

有很多包可以解码它,但它是特定于几何的二进制格式,因此您需要使用一些特定于几何的包,如 geopndas 或 parse_wkb 来解码它。