为什么 shapely/geos 可以解析这个 'invalid' Well Known Binary?
Why can shapely/geos parse this 'invalid' Well Known Binary?
我正在尝试解析 Well Known Binary a binary encoding of geometry objects used in Geographic Information Systems (GIS). I am using this spec from ESRI (same results here from esri). I have input data from Osmosis a tool to parse OpenStreetMap data, specifically the pgsimp-dump format,它给出二进制的十六进制表示。
ESRI 文档说 Point
应该只有 21 个字节,字节顺序只有 1 个字节,typeid 的 uint32 有 4 个字节,double x 有 8 个字节,double y 有 8 个字节。
osmosis 的一个示例是这个(十六进制)示例:0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40
,长度为 25 个字节。
Shapely a python programme to parse WKB (etc), which is based on the popular C library 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?这些字节是什么意思?
GEOS / Shapely 使用 WKT/WKB 的扩展变体,称为 EWKT / EWKB,这是 PostGIS 的 documented。如果您有权访问 PostGIS,则可以在此处查看发生了什么:
SELECT ST_AsEWKT('0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40'::geometry);
Returns EWKT SRID=4326;POINT(-9.2351011 52.9117549)
。所以额外的数据是空间参考标识符或 SRID。特别是 EPSG:4326 用于 WGS 84。
身材匀称does not support SRIDs,但也有一些技巧,例如:
from shapely import geos
geos.WKBWriter.defaults['include_srid'] = True
现在应该使 wkb
或 wkb_hex
输出 EWKB,其中包括 SRID。默认值为 False
,它将为 2D 几何输出 ISO WKB(但不为 3D)。
所以您的 objective 似乎是将 EWKB 转换为 ISO WKB,您可以使用 GEOS / Shapely 仅对 2D 几何图形执行此操作。如果您有 3D(Z 或 M)或 4D (ZM) 几何图形,则只有 PostGIS 能够进行此转换。
我正在尝试解析 Well Known Binary a binary encoding of geometry objects used in Geographic Information Systems (GIS). I am using this spec from ESRI (same results here from esri). I have input data from Osmosis a tool to parse OpenStreetMap data, specifically the pgsimp-dump format,它给出二进制的十六进制表示。
ESRI 文档说 Point
应该只有 21 个字节,字节顺序只有 1 个字节,typeid 的 uint32 有 4 个字节,double x 有 8 个字节,double y 有 8 个字节。
osmosis 的一个示例是这个(十六进制)示例:0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40
,长度为 25 个字节。
Shapely a python programme to parse WKB (etc), which is based on the popular C library 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?这些字节是什么意思?
GEOS / Shapely 使用 WKT/WKB 的扩展变体,称为 EWKT / EWKB,这是 PostGIS 的 documented。如果您有权访问 PostGIS,则可以在此处查看发生了什么:
SELECT ST_AsEWKT('0101000020E6100000DB81DF2B5F7822C0DFBB7262B4744A40'::geometry);
Returns EWKT SRID=4326;POINT(-9.2351011 52.9117549)
。所以额外的数据是空间参考标识符或 SRID。特别是 EPSG:4326 用于 WGS 84。
身材匀称does not support SRIDs,但也有一些技巧,例如:
from shapely import geos
geos.WKBWriter.defaults['include_srid'] = True
现在应该使 wkb
或 wkb_hex
输出 EWKB,其中包括 SRID。默认值为 False
,它将为 2D 几何输出 ISO WKB(但不为 3D)。
所以您的 objective 似乎是将 EWKB 转换为 ISO WKB,您可以使用 GEOS / Shapely 仅对 2D 几何图形执行此操作。如果您有 3D(Z 或 M)或 4D (ZM) 几何图形,则只有 PostGIS 能够进行此转换。