【问题标题】:Why can shapely/geos parse this 'invalid' Well Known Binary?为什么 shapely/geos 可以解析这个“无效的”众所周知的二进制文件?
【发布时间】:2015-04-10 04:33:56
【问题描述】:

我正在尝试解析 Well Known Binary 地理信息系统 (GIS) 中使用的几何对象的二进制编码。我正在使用this spec from ESRI(相同的结果here from esri)。我从 Osmosis 输入数据,这是一个解析 OpenStreetMap 数据的工具,特别是 pgsimp-dump format,它给出了二进制的十六进制表示。

ESRI 文档说Point 应该只有 21 个字节,字节顺序应该只有 1 个字节,typeid 应该有 4 个字节,uint32 应该有 4 个字节,double x 应该有 8 个字节,double y 应该只有 8 个字节。

osmosis 的一个例子是这个(十六进制)例子:0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40,它有 25 个字节长。

Shapely一个解析WKB(等)的python程序,它基于流行的C库GEOS能够解析这个字符串:

>>> import shapely.wkb
>>> shapely.wkb.loads("0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40", hex=True)
<shapely.geometry.point.Point object at 0x7f221f2581d0>

当我让 Shapely 解析然后转换为 WKB 时,我得到 21 个字节。

>>> shapely.wkb.loads("0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40", hex=True).wkb.encode("hex").upper()
'0101000000DB81DF2B5F7822C0DFBB7262B4744A40'

不同的是中间的4个字节,对于typeif=d的uint32出现了3个字节

01010000**20E61000**00DB81DF2B5F7822C0DFBB7262B4744A40

为什么 shapely/geos 可以在 WKB 无效时解析这个 WKB?这些字节是什么意思?

【问题讨论】:

    标签: gis geospatial specifications geos shapely


    【解决方案1】:

    GEOS / Shapely 使用 WKT/WKB 的扩展变体,称为 EWKT / EWKB,PostGIS 为 documented。如果您有权访问 PostGIS,则可以在此处查看发生了什么:

    SELECT ST_AsEWKT('0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40'::geometry);
    

    返回 EWKT SRID=4326;POINT(-9.2351011 52.9117549)。所以额外的数据是空间参考标识符,或 SRID。特别是 EPSG:4326 用于 WGS 84。

    Shapely does not support SRIDs,但也有一些技巧,例如:

    from shapely import geos
    geos.WKBWriter.defaults['include_srid'] = True
    

    现在应该使 wkbwkb_hex 输出 EWKB,其中包括 SRID。默认值为False,它将为 2D 几何(但不为 3D)输出 ISO WKB。

    因此,您的目标似乎是将 EWKB 转换为 ISO WKB,您可以使用 GEOS / Shapely 仅对 2D 几何进行此操作。如果您有 3D(Z 或 M)或 4D (ZM) 几何图形,那么只有 PostGIS 能够进行这种转换。

    【讨论】:

      猜你喜欢
      • 2020-11-29
      • 1970-01-01
      • 2011-01-07
      • 1970-01-01
      • 1970-01-01
      • 2021-05-02
      • 2021-10-25
      • 2011-02-07
      • 1970-01-01
      相关资源
      最近更新 更多